[flexiglass] Removes support for multiple containers.

This was an premature optimization that we're deciding to remove for
now; greatly simplifies the Flexi-non-Flexi interaction.

Fix: 293005905
Test: Built and ran ComposeGallery
Test: Built and ran System UI without Compose
Test: Built and ran Sytem UI with Compose
Change-Id: I39cdcbecb936b64e55b40a04ea8ca897278fcf62
This commit is contained in:
Alejandro Nijamkin
2023-07-27 14:14:23 -07:00
committed by Ale Nijamkin
parent 89ab7b88e4
commit 7d07ad7375
45 changed files with 341 additions and 953 deletions

View File

@@ -17,12 +17,10 @@
package com.android.systemui.scene.ui.composable package com.android.systemui.scene.ui.composable
import com.android.systemui.scene.shared.model.Scene import com.android.systemui.scene.shared.model.Scene
import com.android.systemui.scene.shared.model.SceneContainerNames
import dagger.Module import dagger.Module
import dagger.multibindings.Multibinds import dagger.multibindings.Multibinds
import javax.inject.Named
@Module @Module
interface SceneModule { interface SceneModule {
@Multibinds @Named(SceneContainerNames.SYSTEM_UI_DEFAULT) fun scenes(): Set<Scene> @Multibinds fun scenes(): Set<Scene>
} }

View File

@@ -16,35 +16,29 @@
package com.android.systemui.scene.ui.composable package com.android.systemui.scene.ui.composable
import android.app.AlertDialog
import android.content.Context import android.content.Context
import com.android.systemui.bouncer.ui.composable.BouncerScene import com.android.systemui.bouncer.ui.composable.BouncerScene
import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel import com.android.systemui.bouncer.ui.composable.BouncerSceneDialogFactory
import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.ui.composable.LockscreenScene import com.android.systemui.keyguard.ui.composable.LockscreenScene
import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel
import com.android.systemui.qs.ui.composable.QuickSettingsScene import com.android.systemui.qs.ui.composable.QuickSettingsScene
import com.android.systemui.qs.ui.viewmodel.QuickSettingsSceneViewModel
import com.android.systemui.scene.shared.model.Scene import com.android.systemui.scene.shared.model.Scene
import com.android.systemui.scene.shared.model.SceneContainerNames
import com.android.systemui.shade.ui.composable.ShadeScene import com.android.systemui.shade.ui.composable.ShadeScene
import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel
import com.android.systemui.statusbar.phone.SystemUIDialog import com.android.systemui.statusbar.phone.SystemUIDialog
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import javax.inject.Named
import kotlinx.coroutines.CoroutineScope
@Module @Module
object SceneModule { object SceneModule {
@Provides @Provides
@Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
fun scenes( fun scenes(
@Named(SceneContainerNames.SYSTEM_UI_DEFAULT) bouncer: BouncerScene, bouncer: BouncerScene,
@Named(SceneContainerNames.SYSTEM_UI_DEFAULT) gone: GoneScene, gone: GoneScene,
@Named(SceneContainerNames.SYSTEM_UI_DEFAULT) lockScreen: LockscreenScene, lockScreen: LockscreenScene,
@Named(SceneContainerNames.SYSTEM_UI_DEFAULT) qs: QuickSettingsScene, qs: QuickSettingsScene,
@Named(SceneContainerNames.SYSTEM_UI_DEFAULT) shade: ShadeScene, shade: ShadeScene,
): Set<Scene> { ): Set<Scene> {
return setOf( return setOf(
bouncer, bouncer,
@@ -57,70 +51,11 @@ object SceneModule {
@Provides @Provides
@SysUISingleton @SysUISingleton
@Named(SceneContainerNames.SYSTEM_UI_DEFAULT) fun bouncerSceneDialogFactory(@Application context: Context): BouncerSceneDialogFactory {
fun bouncerScene( return object : BouncerSceneDialogFactory {
@Application context: Context, override fun invoke(): AlertDialog {
viewModelFactory: BouncerViewModel.Factory, return SystemUIDialog(context)
): BouncerScene { }
return BouncerScene( }
viewModel =
viewModelFactory.create(
containerName = SceneContainerNames.SYSTEM_UI_DEFAULT,
),
dialogFactory = { SystemUIDialog(context) },
)
}
@Provides
@SysUISingleton
@Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
fun goneScene(): GoneScene {
return GoneScene()
}
@Provides
@SysUISingleton
@Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
fun lockscreenScene(
@Application applicationScope: CoroutineScope,
viewModelFactory: LockscreenSceneViewModel.Factory,
): LockscreenScene {
return LockscreenScene(
applicationScope = applicationScope,
viewModel =
viewModelFactory.create(
containerName = SceneContainerNames.SYSTEM_UI_DEFAULT,
),
)
}
@Provides
@SysUISingleton
@Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
fun quickSettingsScene(
viewModelFactory: QuickSettingsSceneViewModel.Factory,
): QuickSettingsScene {
return QuickSettingsScene(
viewModel =
viewModelFactory.create(
containerName = SceneContainerNames.SYSTEM_UI_DEFAULT,
),
)
}
@Provides
@SysUISingleton
@Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
fun shadeScene(
@Application applicationScope: CoroutineScope,
viewModelFactory: ShadeSceneViewModel.Factory,
): ShadeScene {
return ShadeScene(
applicationScope = applicationScope,
viewModel =
viewModelFactory.create(
containerName = SceneContainerNames.SYSTEM_UI_DEFAULT,
),
)
} }
} }

View File

@@ -52,24 +52,27 @@ import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel
import com.android.systemui.bouncer.ui.viewmodel.PasswordBouncerViewModel import com.android.systemui.bouncer.ui.viewmodel.PasswordBouncerViewModel
import com.android.systemui.bouncer.ui.viewmodel.PatternBouncerViewModel import com.android.systemui.bouncer.ui.viewmodel.PatternBouncerViewModel
import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.scene.shared.model.UserAction import com.android.systemui.scene.shared.model.UserAction
import com.android.systemui.scene.ui.composable.ComposableScene import com.android.systemui.scene.ui.composable.ComposableScene
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
/** The bouncer scene displays authentication challenges like PIN, password, or pattern. */ /** The bouncer scene displays authentication challenges like PIN, password, or pattern. */
class BouncerScene( @SysUISingleton
class BouncerScene
@Inject
constructor(
private val viewModel: BouncerViewModel, private val viewModel: BouncerViewModel,
private val dialogFactory: () -> AlertDialog, private val dialogFactory: BouncerSceneDialogFactory,
) : ComposableScene { ) : ComposableScene {
override val key = SceneKey.Bouncer override val key = SceneKey.Bouncer
override fun destinationScenes( override fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
containerName: String,
): StateFlow<Map<UserAction, SceneModel>> =
MutableStateFlow<Map<UserAction, SceneModel>>( MutableStateFlow<Map<UserAction, SceneModel>>(
mapOf( mapOf(
UserAction.Back to SceneModel(SceneKey.Lockscreen), UserAction.Back to SceneModel(SceneKey.Lockscreen),
@@ -79,7 +82,6 @@ class BouncerScene(
@Composable @Composable
override fun Content( override fun Content(
containerName: String,
modifier: Modifier, modifier: Modifier,
) = BouncerScene(viewModel, dialogFactory, modifier) ) = BouncerScene(viewModel, dialogFactory, modifier)
} }
@@ -87,7 +89,7 @@ class BouncerScene(
@Composable @Composable
private fun BouncerScene( private fun BouncerScene(
viewModel: BouncerViewModel, viewModel: BouncerViewModel,
dialogFactory: () -> AlertDialog, dialogFactory: BouncerSceneDialogFactory,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
val message: BouncerViewModel.MessageViewModel by viewModel.message.collectAsState() val message: BouncerViewModel.MessageViewModel by viewModel.message.collectAsState()
@@ -175,3 +177,7 @@ private fun BouncerScene(
} }
} }
} }
interface BouncerSceneDialogFactory {
operator fun invoke(): AlertDialog
}

View File

@@ -31,6 +31,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.ui.compose.Icon import com.android.systemui.common.ui.compose.Icon
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel
import com.android.systemui.scene.shared.model.Direction import com.android.systemui.scene.shared.model.Direction
@@ -38,6 +39,7 @@ import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.scene.shared.model.UserAction import com.android.systemui.scene.shared.model.UserAction
import com.android.systemui.scene.ui.composable.ComposableScene import com.android.systemui.scene.ui.composable.ComposableScene
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
@@ -45,15 +47,16 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
/** The lock screen scene shows when the device is locked. */ /** The lock screen scene shows when the device is locked. */
class LockscreenScene( @SysUISingleton
class LockscreenScene
@Inject
constructor(
@Application private val applicationScope: CoroutineScope, @Application private val applicationScope: CoroutineScope,
private val viewModel: LockscreenSceneViewModel, private val viewModel: LockscreenSceneViewModel,
) : ComposableScene { ) : ComposableScene {
override val key = SceneKey.Lockscreen override val key = SceneKey.Lockscreen
override fun destinationScenes( override fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
containerName: String,
): StateFlow<Map<UserAction, SceneModel>> =
viewModel.upDestinationSceneKey viewModel.upDestinationSceneKey
.map { pageKey -> destinationScenes(up = pageKey) } .map { pageKey -> destinationScenes(up = pageKey) }
.stateIn( .stateIn(
@@ -64,7 +67,6 @@ class LockscreenScene(
@Composable @Composable
override fun Content( override fun Content(
containerName: String,
modifier: Modifier, modifier: Modifier,
) { ) {
LockscreenScene( LockscreenScene(

View File

@@ -27,25 +27,28 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.qs.ui.viewmodel.QuickSettingsSceneViewModel import com.android.systemui.qs.ui.viewmodel.QuickSettingsSceneViewModel
import com.android.systemui.scene.shared.model.Direction import com.android.systemui.scene.shared.model.Direction
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.scene.shared.model.UserAction import com.android.systemui.scene.shared.model.UserAction
import com.android.systemui.scene.ui.composable.ComposableScene import com.android.systemui.scene.ui.composable.ComposableScene
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
/** The Quick Settings (AKA "QS") scene shows the quick setting tiles. */ /** The Quick Settings (AKA "QS") scene shows the quick setting tiles. */
class QuickSettingsScene( @SysUISingleton
class QuickSettingsScene
@Inject
constructor(
private val viewModel: QuickSettingsSceneViewModel, private val viewModel: QuickSettingsSceneViewModel,
) : ComposableScene { ) : ComposableScene {
override val key = SceneKey.QuickSettings override val key = SceneKey.QuickSettings
override fun destinationScenes( override fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
containerName: String,
): StateFlow<Map<UserAction, SceneModel>> =
MutableStateFlow<Map<UserAction, SceneModel>>( MutableStateFlow<Map<UserAction, SceneModel>>(
mapOf( mapOf(
UserAction.Swipe(Direction.UP) to SceneModel(SceneKey.Shade), UserAction.Swipe(Direction.UP) to SceneModel(SceneKey.Shade),
@@ -55,7 +58,6 @@ class QuickSettingsScene(
@Composable @Composable
override fun Content( override fun Content(
containerName: String,
modifier: Modifier, modifier: Modifier,
) { ) {
QuickSettingsScene( QuickSettingsScene(

View File

@@ -22,5 +22,5 @@ import com.android.systemui.scene.shared.model.Scene
/** Compose-capable extension of [Scene]. */ /** Compose-capable extension of [Scene]. */
interface ComposableScene : Scene { interface ComposableScene : Scene {
@Composable fun Content(containerName: String, modifier: Modifier) @Composable fun Content(modifier: Modifier)
} }

View File

@@ -23,10 +23,12 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.scene.shared.model.Direction import com.android.systemui.scene.shared.model.Direction
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.scene.shared.model.UserAction import com.android.systemui.scene.shared.model.UserAction
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
@@ -35,12 +37,11 @@ import kotlinx.coroutines.flow.asStateFlow
* "Gone" is not a real scene but rather the absence of scenes when we want to skip showing any * "Gone" is not a real scene but rather the absence of scenes when we want to skip showing any
* content from the scene framework. * content from the scene framework.
*/ */
class GoneScene : ComposableScene { @SysUISingleton
class GoneScene @Inject constructor() : ComposableScene {
override val key = SceneKey.Gone override val key = SceneKey.Gone
override fun destinationScenes( override fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
containerName: String,
): StateFlow<Map<UserAction, SceneModel>> =
MutableStateFlow<Map<UserAction, SceneModel>>( MutableStateFlow<Map<UserAction, SceneModel>>(
mapOf( mapOf(
UserAction.Swipe(Direction.DOWN) to SceneModel(SceneKey.Shade), UserAction.Swipe(Direction.DOWN) to SceneModel(SceneKey.Shade),
@@ -50,7 +51,6 @@ class GoneScene : ComposableScene {
@Composable @Composable
override fun Content( override fun Content(
containerName: String,
modifier: Modifier, modifier: Modifier,
) { ) {
/* /*

View File

@@ -75,7 +75,6 @@ fun SceneContainer(
if (key == currentSceneKey) { if (key == currentSceneKey) {
Scene( Scene(
scene = composableScene, scene = composableScene,
containerName = viewModel.containerName,
onSceneChanged = viewModel::setCurrentScene, onSceneChanged = viewModel::setCurrentScene,
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
) )
@@ -88,12 +87,10 @@ fun SceneContainer(
@Composable @Composable
private fun Scene( private fun Scene(
scene: ComposableScene, scene: ComposableScene,
containerName: String,
onSceneChanged: (SceneModel) -> Unit, onSceneChanged: (SceneModel) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
val destinationScenes: Map<UserAction, SceneModel> by val destinationScenes: Map<UserAction, SceneModel> by scene.destinationScenes().collectAsState()
scene.destinationScenes(containerName).collectAsState()
val swipeLeftDestinationScene = destinationScenes[UserAction.Swipe(Direction.LEFT)] val swipeLeftDestinationScene = destinationScenes[UserAction.Swipe(Direction.LEFT)]
val swipeUpDestinationScene = destinationScenes[UserAction.Swipe(Direction.UP)] val swipeUpDestinationScene = destinationScenes[UserAction.Swipe(Direction.UP)]
val swipeRightDestinationScene = destinationScenes[UserAction.Swipe(Direction.RIGHT)] val swipeRightDestinationScene = destinationScenes[UserAction.Swipe(Direction.RIGHT)]
@@ -107,7 +104,6 @@ private fun Scene(
modifier = Modifier.align(Alignment.Center), modifier = Modifier.align(Alignment.Center),
) { ) {
scene.Content( scene.Content(
containerName = containerName,
modifier = Modifier, modifier = Modifier,
) )

View File

@@ -26,6 +26,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.notifications.ui.composable.Notifications import com.android.systemui.notifications.ui.composable.Notifications
import com.android.systemui.qs.footer.ui.compose.QuickSettings import com.android.systemui.qs.footer.ui.compose.QuickSettings
@@ -35,6 +36,7 @@ import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.scene.shared.model.UserAction import com.android.systemui.scene.shared.model.UserAction
import com.android.systemui.scene.ui.composable.ComposableScene import com.android.systemui.scene.ui.composable.ComposableScene
import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
@@ -42,15 +44,16 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
/** The shade scene shows scrolling list of notifications and some of the quick setting tiles. */ /** The shade scene shows scrolling list of notifications and some of the quick setting tiles. */
class ShadeScene( @SysUISingleton
class ShadeScene
@Inject
constructor(
@Application private val applicationScope: CoroutineScope, @Application private val applicationScope: CoroutineScope,
private val viewModel: ShadeSceneViewModel, private val viewModel: ShadeSceneViewModel,
) : ComposableScene { ) : ComposableScene {
override val key = SceneKey.Shade override val key = SceneKey.Shade
override fun destinationScenes( override fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
containerName: String,
): StateFlow<Map<UserAction, SceneModel>> =
viewModel.upDestinationSceneKey viewModel.upDestinationSceneKey
.map { sceneKey -> destinationScenes(up = sceneKey) } .map { sceneKey -> destinationScenes(up = sceneKey) }
.stateIn( .stateIn(
@@ -61,7 +64,6 @@ class ShadeScene(
@Composable @Composable
override fun Content( override fun Content(
containerName: String,
modifier: Modifier, modifier: Modifier,
) = ShadeScene(viewModel, modifier) ) = ShadeScene(viewModel, modifier)

View File

@@ -81,7 +81,6 @@ import com.android.systemui.log.SessionTracker;
import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.scene.domain.interactor.SceneInteractor; import com.android.systemui.scene.domain.interactor.SceneInteractor;
import com.android.systemui.scene.shared.model.SceneContainerNames;
import com.android.systemui.scene.shared.model.SceneKey; import com.android.systemui.scene.shared.model.SceneKey;
import com.android.systemui.shared.system.SysUiStatsLog; import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -476,7 +475,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
if (mFeatureFlags.isEnabled(Flags.SCENE_CONTAINER)) { if (mFeatureFlags.isEnabled(Flags.SCENE_CONTAINER)) {
// When the scene framework transitions from bouncer to gone, we dismiss the keyguard. // When the scene framework transitions from bouncer to gone, we dismiss the keyguard.
mSceneTransitionCollectionJob = mJavaAdapter.get().alwaysCollectFlow( mSceneTransitionCollectionJob = mJavaAdapter.get().alwaysCollectFlow(
mSceneInteractor.get().sceneTransitions(SceneContainerNames.SYSTEM_UI_DEFAULT), mSceneInteractor.get().getTransitions(),
sceneTransitionModel -> { sceneTransitionModel -> {
if (sceneTransitionModel != null if (sceneTransitionModel != null
&& sceneTransitionModel.getFrom() == SceneKey.Bouncer.INSTANCE && sceneTransitionModel.getFrom() == SceneKey.Bouncer.INSTANCE

View File

@@ -24,6 +24,7 @@ import com.android.systemui.authentication.domain.interactor.AuthenticationInter
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
import com.android.systemui.bouncer.data.repository.BouncerRepository import com.android.systemui.bouncer.data.repository.BouncerRepository
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
@@ -31,9 +32,7 @@ import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.util.kotlin.pairwise import com.android.systemui.util.kotlin.pairwise
import dagger.assisted.Assisted import javax.inject.Inject
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -44,8 +43,9 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
/** Encapsulates business logic and application state accessing use-cases. */ /** Encapsulates business logic and application state accessing use-cases. */
@SysUISingleton
class BouncerInteractor class BouncerInteractor
@AssistedInject @Inject
constructor( constructor(
@Application private val applicationScope: CoroutineScope, @Application private val applicationScope: CoroutineScope,
@Application private val applicationContext: Context, @Application private val applicationContext: Context,
@@ -53,7 +53,6 @@ constructor(
private val authenticationInteractor: AuthenticationInteractor, private val authenticationInteractor: AuthenticationInteractor,
private val sceneInteractor: SceneInteractor, private val sceneInteractor: SceneInteractor,
featureFlags: FeatureFlags, featureFlags: FeatureFlags,
@Assisted private val containerName: String,
) { ) {
/** The user-facing message to show in the bouncer. */ /** The user-facing message to show in the bouncer. */
@@ -118,23 +117,19 @@ constructor(
/** /**
* Either shows the bouncer or unlocks the device, if the bouncer doesn't need to be shown. * Either shows the bouncer or unlocks the device, if the bouncer doesn't need to be shown.
* *
* @param containerName The name of the scene container to show the bouncer in.
* @param message An optional message to show to the user in the bouncer. * @param message An optional message to show to the user in the bouncer.
*/ */
fun showOrUnlockDevice( fun showOrUnlockDevice(
containerName: String,
message: String? = null, message: String? = null,
) { ) {
applicationScope.launch { applicationScope.launch {
if (authenticationInteractor.isAuthenticationRequired()) { if (authenticationInteractor.isAuthenticationRequired()) {
repository.setMessage(message ?: promptMessage(getAuthenticationMethod())) repository.setMessage(message ?: promptMessage(getAuthenticationMethod()))
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(
containerName = containerName,
scene = SceneModel(SceneKey.Bouncer), scene = SceneModel(SceneKey.Bouncer),
) )
} else { } else {
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(
containerName = containerName,
scene = SceneModel(SceneKey.Gone), scene = SceneModel(SceneKey.Gone),
) )
} }
@@ -180,7 +175,6 @@ constructor(
if (isAuthenticated) { if (isAuthenticated) {
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(
containerName = containerName,
scene = SceneModel(SceneKey.Gone), scene = SceneModel(SceneKey.Gone),
) )
} else { } else {
@@ -228,11 +222,4 @@ constructor(
else -> "" else -> ""
} }
} }
@AssistedFactory
interface Factory {
fun create(
containerName: String,
): BouncerInteractor
}
} }

View File

@@ -22,13 +22,12 @@ import android.content.Context
import com.android.systemui.R import com.android.systemui.R
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
import com.android.systemui.util.kotlin.pairwise import com.android.systemui.util.kotlin.pairwise
import dagger.assisted.Assisted import javax.inject.Inject
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlin.math.ceil import kotlin.math.ceil
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -45,17 +44,15 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
/** Holds UI state and handles user input on bouncer UIs. */ /** Holds UI state and handles user input on bouncer UIs. */
@SysUISingleton
class BouncerViewModel class BouncerViewModel
@AssistedInject @Inject
constructor( constructor(
@Application private val applicationContext: Context, @Application private val applicationContext: Context,
@Application private val applicationScope: CoroutineScope, @Application private val applicationScope: CoroutineScope,
interactorFactory: BouncerInteractor.Factory, private val interactor: BouncerInteractor,
featureFlags: FeatureFlags, featureFlags: FeatureFlags,
@Assisted containerName: String,
) { ) {
private val interactor: BouncerInteractor = interactorFactory.create(containerName)
private val isInputEnabled: StateFlow<Boolean> = private val isInputEnabled: StateFlow<Boolean> =
interactor.isThrottled interactor.isThrottled
.map { !it } .map { !it }
@@ -222,11 +219,4 @@ constructor(
*/ */
val isUpdateAnimated: Boolean, val isUpdateAnimated: Boolean,
) )
@AssistedFactory
interface Factory {
fun create(
containerName: String,
): BouncerViewModel
}
} }

View File

@@ -19,10 +19,9 @@ package com.android.systemui.keyguard.domain.interactor
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Application
import dagger.assisted.Assisted import javax.inject.Inject
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
@@ -30,17 +29,14 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
/** Hosts business and application state accessing logic for the lockscreen scene. */ /** Hosts business and application state accessing logic for the lockscreen scene. */
@SysUISingleton
class LockscreenSceneInteractor class LockscreenSceneInteractor
@AssistedInject @Inject
constructor( constructor(
@Application applicationScope: CoroutineScope, @Application applicationScope: CoroutineScope,
private val authenticationInteractor: AuthenticationInteractor, private val authenticationInteractor: AuthenticationInteractor,
bouncerInteractorFactory: BouncerInteractor.Factory, private val bouncerInteractor: BouncerInteractor,
@Assisted private val containerName: String,
) { ) {
private val bouncerInteractor: BouncerInteractor =
bouncerInteractorFactory.create(containerName)
/** Whether the device is currently locked. */ /** Whether the device is currently locked. */
val isDeviceLocked: StateFlow<Boolean> = val isDeviceLocked: StateFlow<Boolean> =
authenticationInteractor.isUnlocked authenticationInteractor.isUnlocked
@@ -67,13 +63,6 @@ constructor(
/** Attempts to dismiss the lockscreen. This will cause the bouncer to show, if needed. */ /** Attempts to dismiss the lockscreen. This will cause the bouncer to show, if needed. */
fun dismissLockscreen() { fun dismissLockscreen() {
bouncerInteractor.showOrUnlockDevice(containerName = containerName) bouncerInteractor.showOrUnlockDevice()
}
@AssistedFactory
interface Factory {
fun create(
containerName: String,
): LockscreenSceneInteractor
} }
} }

View File

@@ -19,12 +19,11 @@ package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.R import com.android.systemui.R
import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Icon
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
import dagger.assisted.Assisted import javax.inject.Inject
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
@@ -32,15 +31,13 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
/** Models UI state and handles user input for the lockscreen scene. */ /** Models UI state and handles user input for the lockscreen scene. */
@SysUISingleton
class LockscreenSceneViewModel class LockscreenSceneViewModel
@AssistedInject @Inject
constructor( constructor(
@Application applicationScope: CoroutineScope, @Application applicationScope: CoroutineScope,
interactorFactory: LockscreenSceneInteractor.Factory, private val interactor: LockscreenSceneInteractor,
@Assisted containerName: String,
) { ) {
private val interactor: LockscreenSceneInteractor = interactorFactory.create(containerName)
/** The icon for the "lock" button on the lockscreen. */ /** The icon for the "lock" button on the lockscreen. */
val lockButtonIcon: StateFlow<Icon> = val lockButtonIcon: StateFlow<Icon> =
interactor.isDeviceLocked interactor.isDeviceLocked
@@ -98,11 +95,4 @@ constructor(
) )
) )
} }
@AssistedFactory
interface Factory {
fun create(
containerName: String,
): LockscreenSceneViewModel
}
} }

View File

@@ -16,30 +16,19 @@
package com.android.systemui.qs.ui.viewmodel package com.android.systemui.qs.ui.viewmodel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import dagger.assisted.Assisted import javax.inject.Inject
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
/** Models UI state and handles user input for the quick settings scene. */ /** Models UI state and handles user input for the quick settings scene. */
@SysUISingleton
class QuickSettingsSceneViewModel class QuickSettingsSceneViewModel
@AssistedInject @Inject
constructor( constructor(
lockscreenSceneInteractorFactory: LockscreenSceneInteractor.Factory, private val lockscreenSceneInteractor: LockscreenSceneInteractor,
@Assisted containerName: String,
) { ) {
private val lockscreenSceneInteractor: LockscreenSceneInteractor =
lockscreenSceneInteractorFactory.create(containerName)
/** Notifies that some content in quick settings was clicked. */ /** Notifies that some content in quick settings was clicked. */
fun onContentClicked() { fun onContentClicked() {
lockscreenSceneInteractor.dismissLockscreen() lockscreenSceneInteractor.dismissLockscreen()
} }
@AssistedFactory
interface Factory {
fun create(
containerName: String,
): QuickSettingsSceneViewModel
}
} }

View File

@@ -97,7 +97,6 @@ import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.navigationbar.buttons.KeyButtonView; import com.android.systemui.navigationbar.buttons.KeyButtonView;
import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener; import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
import com.android.systemui.scene.domain.interactor.SceneInteractor; import com.android.systemui.scene.domain.interactor.SceneInteractor;
import com.android.systemui.scene.shared.model.SceneContainerNames;
import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.settings.UserTracker; import com.android.systemui.settings.UserTracker;
import com.android.systemui.shade.ShadeViewController; import com.android.systemui.shade.ShadeViewController;
@@ -221,8 +220,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
// If scene framework is enabled, set the scene container window to // If scene framework is enabled, set the scene container window to
// visible and let the touch "slip" into that window. // visible and let the touch "slip" into that window.
if (mFeatureFlags.isEnabled(Flags.SCENE_CONTAINER)) { if (mFeatureFlags.isEnabled(Flags.SCENE_CONTAINER)) {
mSceneInteractor.get().setVisible( mSceneInteractor.get().setVisible(true);
SceneContainerNames.SYSTEM_UI_DEFAULT, true);
} else { } else {
centralSurfaces.onInputFocusTransfer( centralSurfaces.onInputFocusTransfer(
mInputFocusTransferStarted, false /* cancel */, mInputFocusTransferStarted, false /* cancel */,

View File

@@ -16,16 +16,16 @@
package com.android.systemui.scene package com.android.systemui.scene
import com.android.systemui.scene.domain.startable.SceneContainerStartableModule
import com.android.systemui.scene.shared.model.SceneContainerConfigModule import com.android.systemui.scene.shared.model.SceneContainerConfigModule
import com.android.systemui.scene.ui.composable.SceneModule import com.android.systemui.scene.ui.composable.SceneModule
import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModelModule
import dagger.Module import dagger.Module
@Module( @Module(
includes = includes =
[ [
SceneContainerConfigModule::class, SceneContainerConfigModule::class,
SceneContainerViewModelModule::class, SceneContainerStartableModule::class,
SceneModule::class, SceneModule::class,
], ],
) )

View File

@@ -29,26 +29,20 @@ import kotlinx.coroutines.flow.asStateFlow
class SceneContainerRepository class SceneContainerRepository
@Inject @Inject
constructor( constructor(
private val containerConfigByName: Map<String, SceneContainerConfig>, private val config: SceneContainerConfig,
) { ) {
private val containerVisibilityByName: Map<String, MutableStateFlow<Boolean>> = private val _isVisible = MutableStateFlow(true)
containerConfigByName val isVisible: StateFlow<Boolean> = _isVisible.asStateFlow()
.map { (containerName, _) -> containerName to MutableStateFlow(true) }
.toMap() private val _currentScene = MutableStateFlow(SceneModel(config.initialSceneKey))
private val currentSceneByContainerName: Map<String, MutableStateFlow<SceneModel>> = val currentScene: StateFlow<SceneModel> = _currentScene.asStateFlow()
containerConfigByName
.map { (containerName, config) -> private val _transitionProgress = MutableStateFlow(1f)
containerName to MutableStateFlow(SceneModel(config.initialSceneKey)) val transitionProgress: StateFlow<Float> = _transitionProgress.asStateFlow()
}
.toMap() private val _transitions = MutableStateFlow<SceneTransitionModel?>(null)
private val sceneTransitionProgressByContainerName: Map<String, MutableStateFlow<Float>> = val transitions: StateFlow<SceneTransitionModel?> = _transitions.asStateFlow()
containerConfigByName
.map { (containerName, _) -> containerName to MutableStateFlow(1f) }
.toMap()
private val sceneTransitionByContainerName:
Map<String, MutableStateFlow<SceneTransitionModel?>> =
containerConfigByName.keys.associateWith { MutableStateFlow(null) }
/** /**
* Returns the keys to all scenes in the container with the given name. * Returns the keys to all scenes in the container with the given name.
@@ -56,100 +50,50 @@ constructor(
* The scenes will be sorted in z-order such that the last one is the one that should be * The scenes will be sorted in z-order such that the last one is the one that should be
* rendered on top of all previous ones. * rendered on top of all previous ones.
*/ */
fun allSceneKeys(containerName: String): List<SceneKey> { fun allSceneKeys(): List<SceneKey> {
return containerConfigByName[containerName]?.sceneKeys return config.sceneKeys
?: error(noSuchContainerErrorMessage(containerName))
} }
/** Sets the current scene in the container with the given name. */ /** Sets the current scene in the container with the given name. */
fun setCurrentScene(containerName: String, scene: SceneModel) { fun setCurrentScene(scene: SceneModel) {
check(allSceneKeys(containerName).contains(scene.key)) { check(allSceneKeys().contains(scene.key)) {
""" """
Cannot set current scene key to "${scene.key}". The container "$containerName" does Cannot set current scene key to "${scene.key}". The configuration does not contain a
not contain a scene with that key. scene with that key.
""" """
.trimIndent() .trimIndent()
} }
currentSceneByContainerName.setValue(containerName, scene) _currentScene.value = scene
} }
/** Sets the scene transition in the container with the given name. */ /** Sets the scene transition in the container with the given name. */
fun setSceneTransition(containerName: String, from: SceneKey, to: SceneKey) { fun setSceneTransition(from: SceneKey, to: SceneKey) {
check(allSceneKeys(containerName).contains(from)) { check(allSceneKeys().contains(from)) {
""" """
Cannot set current scene key to "$from". The container "$containerName" does Cannot set current scene key to "$from". The configuration does not contain a scene
not contain a scene with that key. with that key.
""" """
.trimIndent() .trimIndent()
} }
check(allSceneKeys(containerName).contains(to)) { check(allSceneKeys().contains(to)) {
""" """
Cannot set current scene key to "$to". The container "$containerName" does Cannot set current scene key to "$to". The configuration does not contain a scene
not contain a scene with that key. with that key.
""" """
.trimIndent() .trimIndent()
} }
sceneTransitionByContainerName.setValue( _transitions.value = SceneTransitionModel(from = from, to = to)
containerName,
SceneTransitionModel(from = from, to = to)
)
}
/** The current scene in the container with the given name. */
fun currentScene(containerName: String): StateFlow<SceneModel> {
return currentSceneByContainerName.mutableOrError(containerName).asStateFlow()
}
/**
* Scene transitions as pairs of keys. A new value is emitted exactly once, each time a scene
* transition occurs. The flow begins with a `null` value at first, because the initial scene is
* not something that we transition to from another scene.
*/
fun sceneTransitions(containerName: String): StateFlow<SceneTransitionModel?> {
return sceneTransitionByContainerName.mutableOrError(containerName).asStateFlow()
} }
/** Sets whether the container with the given name is visible. */ /** Sets whether the container with the given name is visible. */
fun setVisible(containerName: String, isVisible: Boolean) { fun setVisible(isVisible: Boolean) {
containerVisibilityByName.setValue(containerName, isVisible) _isVisible.value = isVisible
}
/** Whether the container with the given name should be visible. */
fun isVisible(containerName: String): StateFlow<Boolean> {
return containerVisibilityByName.mutableOrError(containerName).asStateFlow()
} }
/** Sets scene transition progress to the current scene in the container with the given name. */ /** Sets scene transition progress to the current scene in the container with the given name. */
fun setSceneTransitionProgress(containerName: String, progress: Float) { fun setSceneTransitionProgress(progress: Float) {
sceneTransitionProgressByContainerName.setValue(containerName, progress) _transitionProgress.value = progress
}
/** Progress of the transition into the current scene in the container with the given name. */
fun sceneTransitionProgress(containerName: String): StateFlow<Float> {
return sceneTransitionProgressByContainerName.mutableOrError(containerName).asStateFlow()
}
private fun <T> Map<String, MutableStateFlow<T>>.mutableOrError(
containerName: String,
): MutableStateFlow<T> {
return this[containerName] ?: error(noSuchContainerErrorMessage(containerName))
}
private fun <T> Map<String, MutableStateFlow<T>>.setValue(
containerName: String,
value: T,
) {
val mutable = mutableOrError(containerName)
mutable.value = value
}
private fun noSuchContainerErrorMessage(containerName: String): String {
return """
No container named "$containerName". Existing containers:
${containerConfigByName.values.joinToString(", ") { it.name }}
"""
.trimIndent()
} }
} }

View File

@@ -30,12 +30,8 @@ import kotlinx.coroutines.flow.asStateFlow
/** /**
* Generic business logic and app state accessors for the scene framework. * Generic business logic and app state accessors for the scene framework.
* *
* Note that scene container specific business logic does not belong in this class. Instead, it * Note that this class should not depend on state or logic of other modules or features. Instead,
* should be hoisted to a class that is specific to that scene container, for an example, please see * other feature modules should depend on and call into this class when their parts of the
* [SystemUiDefaultSceneContainerStartable].
*
* Also note that this class should not depend on state or logic of other modules or features.
* Instead, other feature modules should depend on and call into this class when their parts of the
* application state change. * application state change.
*/ */
@SysUISingleton @SysUISingleton
@@ -51,50 +47,42 @@ constructor(
* The scenes will be sorted in z-order such that the last one is the one that should be * The scenes will be sorted in z-order such that the last one is the one that should be
* rendered on top of all previous ones. * rendered on top of all previous ones.
*/ */
fun allSceneKeys(containerName: String): List<SceneKey> { fun allSceneKeys(): List<SceneKey> {
return repository.allSceneKeys(containerName) return repository.allSceneKeys()
} }
/** Sets the scene in the container with the given name. */ /** Sets the scene in the container with the given name. */
fun setCurrentScene(containerName: String, scene: SceneModel) { fun setCurrentScene(scene: SceneModel) {
val currentSceneKey = repository.currentScene(containerName).value.key val currentSceneKey = repository.currentScene.value.key
repository.setCurrentScene(containerName, scene) repository.setCurrentScene(scene)
repository.setSceneTransition(containerName, from = currentSceneKey, to = scene.key) repository.setSceneTransition(from = currentSceneKey, to = scene.key)
} }
/** The current scene in the container with the given name. */ /** The current scene in the container with the given name. */
fun currentScene(containerName: String): StateFlow<SceneModel> { val currentScene: StateFlow<SceneModel> = repository.currentScene
return repository.currentScene(containerName)
}
/** Sets the visibility of the container with the given name. */ /** Sets the visibility of the container with the given name. */
fun setVisible(containerName: String, isVisible: Boolean) { fun setVisible(isVisible: Boolean) {
return repository.setVisible(containerName, isVisible) return repository.setVisible(isVisible)
} }
/** Whether the container with the given name is visible. */ /** Whether the container with the given name is visible. */
fun isVisible(containerName: String): StateFlow<Boolean> { val isVisible: StateFlow<Boolean> = repository.isVisible
return repository.isVisible(containerName)
}
/** Sets scene transition progress to the current scene in the container with the given name. */ /** Sets scene transition progress to the current scene in the container with the given name. */
fun setSceneTransitionProgress(containerName: String, progress: Float) { fun setSceneTransitionProgress(progress: Float) {
repository.setSceneTransitionProgress(containerName, progress) repository.setSceneTransitionProgress(progress)
} }
/** Progress of the transition into the current scene in the container with the given name. */ /** Progress of the transition into the current scene in the container with the given name. */
fun sceneTransitionProgress(containerName: String): StateFlow<Float> { val transitionProgress: StateFlow<Float> = repository.transitionProgress
return repository.sceneTransitionProgress(containerName)
}
/** /**
* Scene transitions as pairs of keys. A new value is emitted exactly once, each time a scene * Scene transitions as pairs of keys. A new value is emitted exactly once, each time a scene
* transition occurs. The flow begins with a `null` value at first, because the initial scene is * transition occurs. The flow begins with a `null` value at first, because the initial scene is
* not something that we transition to from another scene. * not something that we transition to from another scene.
*/ */
fun sceneTransitions(containerName: String): StateFlow<SceneTransitionModel?> { val transitions: StateFlow<SceneTransitionModel?> = repository.transitions
return repository.sceneTransitions(containerName)
}
private val _remoteUserInput: MutableStateFlow<RemoteUserInput?> = MutableStateFlow(null) private val _remoteUserInput: MutableStateFlow<RemoteUserInput?> = MutableStateFlow(null)

View File

@@ -28,7 +28,6 @@ import com.android.systemui.keyguard.shared.model.WakefulnessState
import com.android.systemui.model.SysUiState import com.android.systemui.model.SysUiState
import com.android.systemui.model.updateFlags import com.android.systemui.model.updateFlags
import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.SceneContainerNames
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING
@@ -44,12 +43,11 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
/** /**
* Hooks up business logic that manipulates the state of the [SceneInteractor] for the default * Hooks up business logic that manipulates the state of the [SceneInteractor] for the system UI
* system UI scene container (the one named [SceneContainerNames.SYSTEM_UI_DEFAULT]) based on state * scene container based on state from other systems.
* from other systems.
*/ */
@SysUISingleton @SysUISingleton
class SystemUiDefaultSceneContainerStartable class SceneContainerStartable
@Inject @Inject
constructor( constructor(
@Application private val applicationScope: CoroutineScope, @Application private val applicationScope: CoroutineScope,
@@ -72,13 +70,10 @@ constructor(
/** Updates the visibility of the scene container based on the current scene. */ /** Updates the visibility of the scene container based on the current scene. */
private fun hydrateVisibility() { private fun hydrateVisibility() {
applicationScope.launch { applicationScope.launch {
sceneInteractor sceneInteractor.currentScene
.currentScene(CONTAINER_NAME)
.map { it.key } .map { it.key }
.distinctUntilChanged() .distinctUntilChanged()
.collect { sceneKey -> .collect { sceneKey -> sceneInteractor.setVisible(sceneKey != SceneKey.Gone) }
sceneInteractor.setVisible(CONTAINER_NAME, sceneKey != SceneKey.Gone)
}
} }
} }
@@ -87,7 +82,7 @@ constructor(
applicationScope.launch { applicationScope.launch {
authenticationInteractor.isUnlocked authenticationInteractor.isUnlocked
.map { isUnlocked -> .map { isUnlocked ->
val currentSceneKey = sceneInteractor.currentScene(CONTAINER_NAME).value.key val currentSceneKey = sceneInteractor.currentScene.value.key
val isBypassEnabled = authenticationInteractor.isBypassEnabled() val isBypassEnabled = authenticationInteractor.isBypassEnabled()
when { when {
isUnlocked -> isUnlocked ->
@@ -135,8 +130,7 @@ constructor(
/** Keeps [SysUiState] up-to-date */ /** Keeps [SysUiState] up-to-date */
private fun hydrateSystemUiState() { private fun hydrateSystemUiState() {
applicationScope.launch { applicationScope.launch {
sceneInteractor sceneInteractor.currentScene
.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT)
.map { it.key } .map { it.key }
.distinctUntilChanged() .distinctUntilChanged()
.collect { sceneKey -> .collect { sceneKey ->
@@ -155,12 +149,7 @@ constructor(
private fun switchToScene(targetSceneKey: SceneKey) { private fun switchToScene(targetSceneKey: SceneKey) {
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(
containerName = CONTAINER_NAME,
scene = SceneModel(targetSceneKey), scene = SceneModel(targetSceneKey),
) )
} }
companion object {
private const val CONTAINER_NAME = SceneContainerNames.SYSTEM_UI_DEFAULT
}
} }

View File

@@ -27,6 +27,6 @@ interface SceneContainerStartableModule {
@Binds @Binds
@IntoMap @IntoMap
@ClassKey(SystemUiDefaultSceneContainerStartable::class) @ClassKey(SceneContainerStartable::class)
fun bind(impl: SystemUiDefaultSceneContainerStartable): CoreStartable fun bind(impl: SceneContainerStartable): CoreStartable
} }

View File

@@ -27,8 +27,6 @@ import kotlinx.coroutines.flow.asStateFlow
* takes care of rendering the current scene and allowing scenes to be switched from one to another * takes care of rendering the current scene and allowing scenes to be switched from one to another
* based on either user action (for example, swiping down while on the lock screen scene may switch * based on either user action (for example, swiping down while on the lock screen scene may switch
* to the shade scene). * to the shade scene).
*
* The framework also supports multiple containers, each one with its own configuration.
*/ */
interface Scene { interface Scene {
@@ -59,7 +57,7 @@ interface Scene {
* The API is designed such that it's possible to emit ever-changing values for each * The API is designed such that it's possible to emit ever-changing values for each
* [UserAction] to enable, disable, or change the destination scene of a given user action. * [UserAction] to enable, disable, or change the destination scene of a given user action.
*/ */
fun destinationScenes(containerName: String): StateFlow<Map<UserAction, SceneModel>> = fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
MutableStateFlow(emptyMap<UserAction, SceneModel>()).asStateFlow() MutableStateFlow(emptyMap<UserAction, SceneModel>()).asStateFlow()
} }

View File

@@ -16,10 +16,8 @@
package com.android.systemui.scene.shared.model package com.android.systemui.scene.shared.model
/** Models the configuration of a single scene container. */ /** Models the configuration of the scene container. */
data class SceneContainerConfig( data class SceneContainerConfig(
/** Container name. Must be unique across all containers in System UI. */
val name: String,
/** /**
* The keys to all scenes in the container, sorted by z-order such that the last one renders on * The keys to all scenes in the container, sorted by z-order such that the last one renders on

View File

@@ -16,44 +16,27 @@
package com.android.systemui.scene.shared.model package com.android.systemui.scene.shared.model
import com.android.systemui.dagger.SysUISingleton
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import javax.inject.Named
@Module @Module
object SceneContainerConfigModule { object SceneContainerConfigModule {
@Provides @Provides
fun containerConfigs(): Map<String, SceneContainerConfig> { fun containerConfig(): SceneContainerConfig {
return mapOf( return SceneContainerConfig(
SceneContainerNames.SYSTEM_UI_DEFAULT to // Note that this list is in z-order. The first one is the bottom-most and the
SceneContainerConfig( // last
name = SceneContainerNames.SYSTEM_UI_DEFAULT, // one is top-most.
// Note that this list is in z-order. The first one is the bottom-most and the sceneKeys =
// last listOf(
// one is top-most. SceneKey.Gone,
sceneKeys = SceneKey.Lockscreen,
listOf( SceneKey.Bouncer,
SceneKey.Gone, SceneKey.Shade,
SceneKey.Lockscreen, SceneKey.QuickSettings,
SceneKey.Bouncer,
SceneKey.Shade,
SceneKey.QuickSettings,
),
initialSceneKey = SceneKey.Lockscreen,
), ),
initialSceneKey = SceneKey.Lockscreen,
) )
} }
@Provides
@SysUISingleton
@Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
fun provideDefaultSceneContainerConfig(
configs: Map<String, SceneContainerConfig>,
): SceneContainerConfig {
return checkNotNull(configs[SceneContainerNames.SYSTEM_UI_DEFAULT]) {
"No SceneContainerConfig named \"${SceneContainerNames.SYSTEM_UI_DEFAULT}\"."
}
}
} }

View File

@@ -1,21 +0,0 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.scene.shared.model
object SceneContainerNames {
const val SYSTEM_UI_DEFAULT = "system_ui"
}

View File

@@ -17,16 +17,20 @@
package com.android.systemui.scene.ui.viewmodel package com.android.systemui.scene.ui.viewmodel
import android.view.MotionEvent import android.view.MotionEvent
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.RemoteUserInput import com.android.systemui.scene.shared.model.RemoteUserInput
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.SceneModel
import javax.inject.Inject
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
/** Models UI state for a single scene container. */ /** Models UI state for the scene container. */
class SceneContainerViewModel( @SysUISingleton
class SceneContainerViewModel
@Inject
constructor(
private val interactor: SceneInteractor, private val interactor: SceneInteractor,
val containerName: String,
) { ) {
/** A flow of motion events originating from outside of the scene framework. */ /** A flow of motion events originating from outside of the scene framework. */
val remoteUserInput: StateFlow<RemoteUserInput?> = interactor.remoteUserInput val remoteUserInput: StateFlow<RemoteUserInput?> = interactor.remoteUserInput
@@ -37,22 +41,22 @@ class SceneContainerViewModel(
* The scenes will be sorted in z-order such that the last one is the one that should be * The scenes will be sorted in z-order such that the last one is the one that should be
* rendered on top of all previous ones. * rendered on top of all previous ones.
*/ */
val allSceneKeys: List<SceneKey> = interactor.allSceneKeys(containerName) val allSceneKeys: List<SceneKey> = interactor.allSceneKeys()
/** The current scene. */ /** The current scene. */
val currentScene: StateFlow<SceneModel> = interactor.currentScene(containerName) val currentScene: StateFlow<SceneModel> = interactor.currentScene
/** Whether the container is visible. */ /** Whether the container is visible. */
val isVisible: StateFlow<Boolean> = interactor.isVisible(containerName) val isVisible: StateFlow<Boolean> = interactor.isVisible
/** Requests a transition to the scene with the given key. */ /** Requests a transition to the scene with the given key. */
fun setCurrentScene(scene: SceneModel) { fun setCurrentScene(scene: SceneModel) {
interactor.setCurrentScene(containerName, scene) interactor.setCurrentScene(scene)
} }
/** Notifies of the progress of a scene transition. */ /** Notifies of the progress of a scene transition. */
fun setSceneTransitionProgress(progress: Float) { fun setSceneTransitionProgress(progress: Float) {
interactor.setSceneTransitionProgress(containerName, progress) interactor.setSceneTransitionProgress(progress)
} }
/** Handles a [MotionEvent] representing remote user input. */ /** Handles a [MotionEvent] representing remote user input. */

View File

@@ -1,40 +0,0 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.scene.ui.viewmodel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.SceneContainerNames
import dagger.Module
import dagger.Provides
import javax.inject.Named
@Module
object SceneContainerViewModelModule {
@Provides
@SysUISingleton
@Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
fun defaultSceneContainerViewModel(
interactor: SceneInteractor,
): SceneContainerViewModel {
return SceneContainerViewModel(
interactor = interactor,
containerName = SceneContainerNames.SYSTEM_UI_DEFAULT,
)
}
}

View File

@@ -36,7 +36,6 @@ import com.android.systemui.keyguard.ui.view.KeyguardRootView
import com.android.systemui.privacy.OngoingPrivacyChip import com.android.systemui.privacy.OngoingPrivacyChip
import com.android.systemui.scene.shared.model.Scene import com.android.systemui.scene.shared.model.Scene
import com.android.systemui.scene.shared.model.SceneContainerConfig import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.SceneContainerNames
import com.android.systemui.scene.ui.view.SceneWindowRootView import com.android.systemui.scene.ui.view.SceneWindowRootView
import com.android.systemui.scene.ui.view.WindowRootView import com.android.systemui.scene.ui.view.WindowRootView
import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
@@ -73,11 +72,8 @@ abstract class ShadeViewProviderModule {
fun providesWindowRootView( fun providesWindowRootView(
layoutInflater: LayoutInflater, layoutInflater: LayoutInflater,
featureFlags: FeatureFlags, featureFlags: FeatureFlags,
@Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
viewModelProvider: Provider<SceneContainerViewModel>, viewModelProvider: Provider<SceneContainerViewModel>,
@Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
containerConfigProvider: Provider<SceneContainerConfig>, containerConfigProvider: Provider<SceneContainerConfig>,
@Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
scenesProvider: Provider<Set<@JvmSuppressWildcards Scene>>, scenesProvider: Provider<Set<@JvmSuppressWildcards Scene>>,
layoutInsetController: NotificationInsetsController, layoutInsetController: NotificationInsetsController,
): WindowRootView { ): WindowRootView {

View File

@@ -16,12 +16,11 @@
package com.android.systemui.shade.ui.viewmodel package com.android.systemui.shade.ui.viewmodel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
import dagger.assisted.Assisted import javax.inject.Inject
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
@@ -29,32 +28,29 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
/** Models UI state and handles user input for the shade scene. */ /** Models UI state and handles user input for the shade scene. */
@SysUISingleton
class ShadeSceneViewModel class ShadeSceneViewModel
@AssistedInject @Inject
constructor( constructor(
@Application private val applicationScope: CoroutineScope, @Application private val applicationScope: CoroutineScope,
lockscreenSceneInteractorFactory: LockscreenSceneInteractor.Factory, private val lockscreenSceneInteractor: LockscreenSceneInteractor,
@Assisted private val containerName: String,
) { ) {
private val lockScreenInteractor: LockscreenSceneInteractor =
lockscreenSceneInteractorFactory.create(containerName)
/** The key of the scene we should switch to when swiping up. */ /** The key of the scene we should switch to when swiping up. */
val upDestinationSceneKey: StateFlow<SceneKey> = val upDestinationSceneKey: StateFlow<SceneKey> =
lockScreenInteractor.isDeviceLocked lockscreenSceneInteractor.isDeviceLocked
.map { isLocked -> upDestinationSceneKey(isLocked = isLocked) } .map { isLocked -> upDestinationSceneKey(isLocked = isLocked) }
.stateIn( .stateIn(
scope = applicationScope, scope = applicationScope,
started = SharingStarted.WhileSubscribed(), started = SharingStarted.WhileSubscribed(),
initialValue = initialValue =
upDestinationSceneKey( upDestinationSceneKey(
isLocked = lockScreenInteractor.isDeviceLocked.value, isLocked = lockscreenSceneInteractor.isDeviceLocked.value,
), ),
) )
/** Notifies that some content in the shade was clicked. */ /** Notifies that some content in the shade was clicked. */
fun onContentClicked() { fun onContentClicked() {
lockScreenInteractor.dismissLockscreen() lockscreenSceneInteractor.dismissLockscreen()
} }
private fun upDestinationSceneKey( private fun upDestinationSceneKey(
@@ -62,11 +58,4 @@ constructor(
): SceneKey { ): SceneKey {
return if (isLocked) SceneKey.Lockscreen else SceneKey.Gone return if (isLocked) SceneKey.Lockscreen else SceneKey.Gone
} }
@AssistedFactory
interface Factory {
fun create(
containerName: String,
): ShadeSceneViewModel
}
} }

View File

@@ -30,7 +30,6 @@ import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.RemoteUserInput import com.android.systemui.scene.shared.model.RemoteUserInput
import com.android.systemui.scene.shared.model.SceneContainerNames
import com.android.systemui.shade.ShadeController import com.android.systemui.shade.ShadeController
import com.android.systemui.shade.ShadeLogger import com.android.systemui.shade.ShadeLogger
import com.android.systemui.shade.ShadeViewController import com.android.systemui.shade.ShadeViewController
@@ -183,7 +182,7 @@ class PhoneStatusBarViewController private constructor(
sceneInteractor.get() sceneInteractor.get()
.onRemoteUserInput(RemoteUserInput.translateMotionEvent(event)) .onRemoteUserInput(RemoteUserInput.translateMotionEvent(event))
// TODO(b/291965119): remove once view is expanded to cover the status bar // TODO(b/291965119): remove once view is expanded to cover the status bar
sceneInteractor.get().setVisible(SceneContainerNames.SYSTEM_UI_DEFAULT, true) sceneInteractor.get().setVisible(true)
return false return false
} }

View File

@@ -37,7 +37,6 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags; import com.android.systemui.flags.Flags;
import com.android.systemui.scene.domain.interactor.SceneInteractor; import com.android.systemui.scene.domain.interactor.SceneInteractor;
import com.android.systemui.scene.shared.model.SceneContainerNames;
import com.android.systemui.shade.ShadeExpansionStateManager; import com.android.systemui.shade.ShadeExpansionStateManager;
import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -126,7 +125,7 @@ public final class StatusBarTouchableRegionManager implements Dumpable {
if (featureFlags.isEnabled(Flags.SCENE_CONTAINER)) { if (featureFlags.isEnabled(Flags.SCENE_CONTAINER)) {
javaAdapter.get().alwaysCollectFlow( javaAdapter.get().alwaysCollectFlow(
sceneInteractor.get().isVisible(SceneContainerNames.SYSTEM_UI_DEFAULT), sceneInteractor.get().isVisible(),
this::onShadeExpansionFullyChanged); this::onShadeExpansionFullyChanged);
} }

View File

@@ -733,29 +733,20 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() {
// is // is
// not enough to trigger a dismissal of the keyguard. // not enough to trigger a dismissal of the keyguard.
underTest.onViewAttached() underTest.onViewAttached()
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer, null))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer, null)
)
runCurrent() runCurrent()
verify(viewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt()) verify(viewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt())
// While listening, going from the bouncer scene to the gone scene, does dismiss the // While listening, going from the bouncer scene to the gone scene, does dismiss the
// keyguard. // keyguard.
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Gone, null))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Gone, null)
)
runCurrent() runCurrent()
verify(viewMediatorCallback).keyguardDone(anyBoolean(), anyInt()) verify(viewMediatorCallback).keyguardDone(anyBoolean(), anyInt())
// While listening, moving back to the bouncer scene does not dismiss the keyguard // While listening, moving back to the bouncer scene does not dismiss the keyguard
// again. // again.
clearInvocations(viewMediatorCallback) clearInvocations(viewMediatorCallback)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer, null))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer, null)
)
runCurrent() runCurrent()
verify(viewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt()) verify(viewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt())
@@ -763,18 +754,12 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() {
// scene // scene
// does not dismiss the keyguard while we're not listening. // does not dismiss the keyguard while we're not listening.
underTest.onViewDetached() underTest.onViewDetached()
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Gone, null))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Gone, null)
)
runCurrent() runCurrent()
verify(viewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt()) verify(viewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt())
// While not listening, moving back to the bouncer does not dismiss the keyguard. // While not listening, moving back to the bouncer does not dismiss the keyguard.
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer, null))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer, null)
)
runCurrent() runCurrent()
verify(viewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt()) verify(viewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt())
@@ -782,10 +767,7 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() {
// gone // gone
// scene now does dismiss the keyguard again. // scene now does dismiss the keyguard again.
underTest.onViewAttached() underTest.onViewAttached()
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Gone, null))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Gone, null)
)
runCurrent() runCurrent()
verify(viewMediatorCallback).keyguardDone(anyBoolean(), anyInt()) verify(viewMediatorCallback).keyguardDone(anyBoolean(), anyInt())
} }

View File

@@ -69,13 +69,12 @@ class BouncerInteractorTest : SysuiTestCase() {
@Test @Test
fun pinAuthMethod() = fun pinAuthMethod() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(underTest.message) val message by collectLastValue(underTest.message)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1) underTest.showOrUnlockDevice()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PIN) assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PIN)
@@ -101,14 +100,13 @@ class BouncerInteractorTest : SysuiTestCase() {
@Test @Test
fun pinAuthMethod_tryAutoConfirm_withAutoConfirmPin() = fun pinAuthMethod_tryAutoConfirm_withAutoConfirmPin() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(underTest.message) val message by collectLastValue(underTest.message)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setAutoConfirmEnabled(true) utils.authenticationRepository.setAutoConfirmEnabled(true)
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1) underTest.showOrUnlockDevice()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PIN) assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PIN)
underTest.clearMessage() underTest.clearMessage()
@@ -138,13 +136,12 @@ class BouncerInteractorTest : SysuiTestCase() {
@Test @Test
fun pinAuthMethod_tryAutoConfirm_withoutAutoConfirmPin() = fun pinAuthMethod_tryAutoConfirm_withoutAutoConfirmPin() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(underTest.message) val message by collectLastValue(underTest.message)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1) underTest.showOrUnlockDevice()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.clearMessage() underTest.clearMessage()
@@ -168,14 +165,13 @@ class BouncerInteractorTest : SysuiTestCase() {
@Test @Test
fun passwordAuthMethod() = fun passwordAuthMethod() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(underTest.message) val message by collectLastValue(underTest.message)
utils.authenticationRepository.setAuthenticationMethod( utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Password AuthenticationMethodModel.Password
) )
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1) underTest.showOrUnlockDevice()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PASSWORD) assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PASSWORD)
@@ -201,14 +197,13 @@ class BouncerInteractorTest : SysuiTestCase() {
@Test @Test
fun patternAuthMethod() = fun patternAuthMethod() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(underTest.message) val message by collectLastValue(underTest.message)
utils.authenticationRepository.setAuthenticationMethod( utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Pattern AuthenticationMethodModel.Pattern
) )
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1) underTest.showOrUnlockDevice()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PATTERN) assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PATTERN)
@@ -239,13 +234,12 @@ class BouncerInteractorTest : SysuiTestCase() {
@Test @Test
fun showOrUnlockDevice_notLocked_switchesToGoneScene() = fun showOrUnlockDevice_notLocked_switchesToGoneScene() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(true) utils.authenticationRepository.setUnlocked(true)
runCurrent() runCurrent()
underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1) underTest.showOrUnlockDevice()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
} }
@@ -253,12 +247,11 @@ class BouncerInteractorTest : SysuiTestCase() {
@Test @Test
fun showOrUnlockDevice_authMethodNotSecure_switchesToGoneScene() = fun showOrUnlockDevice_authMethodNotSecure_switchesToGoneScene() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1) underTest.showOrUnlockDevice()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
} }
@@ -266,8 +259,7 @@ class BouncerInteractorTest : SysuiTestCase() {
@Test @Test
fun showOrUnlockDevice_customMessageShown() = fun showOrUnlockDevice_customMessageShown() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(underTest.message) val message by collectLastValue(underTest.message)
utils.authenticationRepository.setAuthenticationMethod( utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Password AuthenticationMethodModel.Password
@@ -275,7 +267,7 @@ class BouncerInteractorTest : SysuiTestCase() {
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
val customMessage = "Hello there!" val customMessage = "Hello there!"
underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1, customMessage) underTest.showOrUnlockDevice(customMessage)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
assertThat(message).isEqualTo(customMessage) assertThat(message).isEqualTo(customMessage)
@@ -287,11 +279,10 @@ class BouncerInteractorTest : SysuiTestCase() {
val isThrottled by collectLastValue(underTest.isThrottled) val isThrottled by collectLastValue(underTest.isThrottled)
val throttling by collectLastValue(underTest.throttling) val throttling by collectLastValue(underTest.throttling)
val message by collectLastValue(underTest.message) val message by collectLastValue(underTest.message)
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
runCurrent() runCurrent()
underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1) underTest.showOrUnlockDevice()
runCurrent() runCurrent()
assertThat(currentScene?.key).isEqualTo(SceneKey.Bouncer) assertThat(currentScene?.key).isEqualTo(SceneKey.Bouncer)
assertThat(isThrottled).isFalse() assertThat(isThrottled).isFalse()

View File

@@ -72,18 +72,14 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onShown() = fun onShown() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(bouncerViewModel.message) val message by collectLastValue(bouncerViewModel.message)
val password by collectLastValue(underTest.password) val password by collectLastValue(underTest.password)
utils.authenticationRepository.setAuthenticationMethod( utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Password AuthenticationMethodModel.Password
) )
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
@@ -96,18 +92,14 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onPasswordInputChanged() = fun onPasswordInputChanged() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(bouncerViewModel.message) val message by collectLastValue(bouncerViewModel.message)
val password by collectLastValue(underTest.password) val password by collectLastValue(underTest.password)
utils.authenticationRepository.setAuthenticationMethod( utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Password AuthenticationMethodModel.Password
) )
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
runCurrent() runCurrent()
@@ -122,16 +114,12 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onAuthenticateKeyPressed_whenCorrect() = fun onAuthenticateKeyPressed_whenCorrect() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
utils.authenticationRepository.setAuthenticationMethod( utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Password AuthenticationMethodModel.Password
) )
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
underTest.onPasswordInputChanged("password") underTest.onPasswordInputChanged("password")
@@ -144,18 +132,14 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onAuthenticateKeyPressed_whenWrong() = fun onAuthenticateKeyPressed_whenWrong() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(bouncerViewModel.message) val message by collectLastValue(bouncerViewModel.message)
val password by collectLastValue(underTest.password) val password by collectLastValue(underTest.password)
utils.authenticationRepository.setAuthenticationMethod( utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Password AuthenticationMethodModel.Password
) )
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
underTest.onPasswordInputChanged("wrong") underTest.onPasswordInputChanged("wrong")
@@ -170,18 +154,14 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onAuthenticateKeyPressed_correctAfterWrong() = fun onAuthenticateKeyPressed_correctAfterWrong() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(bouncerViewModel.message) val message by collectLastValue(bouncerViewModel.message)
val password by collectLastValue(underTest.password) val password by collectLastValue(underTest.password)
utils.authenticationRepository.setAuthenticationMethod( utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Password AuthenticationMethodModel.Password
) )
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
underTest.onPasswordInputChanged("wrong") underTest.onPasswordInputChanged("wrong")

View File

@@ -75,8 +75,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onShown() = fun onShown() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(bouncerViewModel.message) val message by collectLastValue(bouncerViewModel.message)
val selectedDots by collectLastValue(underTest.selectedDots) val selectedDots by collectLastValue(underTest.selectedDots)
val currentDot by collectLastValue(underTest.currentDot) val currentDot by collectLastValue(underTest.currentDot)
@@ -84,10 +83,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
AuthenticationMethodModel.Pattern AuthenticationMethodModel.Pattern
) )
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
@@ -101,8 +97,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onDragStart() = fun onDragStart() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(bouncerViewModel.message) val message by collectLastValue(bouncerViewModel.message)
val selectedDots by collectLastValue(underTest.selectedDots) val selectedDots by collectLastValue(underTest.selectedDots)
val currentDot by collectLastValue(underTest.currentDot) val currentDot by collectLastValue(underTest.currentDot)
@@ -110,10 +105,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
AuthenticationMethodModel.Pattern AuthenticationMethodModel.Pattern
) )
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
runCurrent() runCurrent()
@@ -129,18 +121,14 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onDragEnd_whenCorrect() = fun onDragEnd_whenCorrect() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val selectedDots by collectLastValue(underTest.selectedDots) val selectedDots by collectLastValue(underTest.selectedDots)
val currentDot by collectLastValue(underTest.currentDot) val currentDot by collectLastValue(underTest.currentDot)
utils.authenticationRepository.setAuthenticationMethod( utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Pattern AuthenticationMethodModel.Pattern
) )
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
underTest.onDragStart() underTest.onDragStart()
@@ -180,8 +168,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onDragEnd_whenWrong() = fun onDragEnd_whenWrong() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(bouncerViewModel.message) val message by collectLastValue(bouncerViewModel.message)
val selectedDots by collectLastValue(underTest.selectedDots) val selectedDots by collectLastValue(underTest.selectedDots)
val currentDot by collectLastValue(underTest.currentDot) val currentDot by collectLastValue(underTest.currentDot)
@@ -189,10 +176,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
AuthenticationMethodModel.Pattern AuthenticationMethodModel.Pattern
) )
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
underTest.onDragStart() underTest.onDragStart()
@@ -216,8 +200,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onDragEnd_correctAfterWrong() = fun onDragEnd_correctAfterWrong() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(bouncerViewModel.message) val message by collectLastValue(bouncerViewModel.message)
val selectedDots by collectLastValue(underTest.selectedDots) val selectedDots by collectLastValue(underTest.selectedDots)
val currentDot by collectLastValue(underTest.currentDot) val currentDot by collectLastValue(underTest.currentDot)
@@ -225,10 +208,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
AuthenticationMethodModel.Pattern AuthenticationMethodModel.Pattern
) )
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
underTest.onDragStart() underTest.onDragStart()

View File

@@ -75,15 +75,11 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onShown() = fun onShown() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(bouncerViewModel.message) val message by collectLastValue(bouncerViewModel.message)
val pin by collectLastValue(underTest.pinInput.map { it.getPin() }) val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
@@ -96,16 +92,12 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onPinButtonClicked() = fun onPinButtonClicked() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(bouncerViewModel.message) val message by collectLastValue(bouncerViewModel.message)
val pin by collectLastValue(underTest.pinInput.map { it.getPin() }) val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
runCurrent() runCurrent()
@@ -120,16 +112,12 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onBackspaceButtonClicked() = fun onBackspaceButtonClicked() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(bouncerViewModel.message) val message by collectLastValue(bouncerViewModel.message)
val pin by collectLastValue(underTest.pinInput.map { it.getPin() }) val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
runCurrent() runCurrent()
@@ -146,15 +134,11 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onPinEdit() = fun onPinEdit() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val pin by collectLastValue(underTest.pinInput.map { it.getPin() }) val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
@@ -172,16 +156,12 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onBackspaceButtonLongPressed() = fun onBackspaceButtonLongPressed() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(bouncerViewModel.message) val message by collectLastValue(bouncerViewModel.message)
val pin by collectLastValue(underTest.pinInput.map { it.getPin() }) val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
runCurrent() runCurrent()
@@ -200,14 +180,10 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onAuthenticateButtonClicked_whenCorrect() = fun onAuthenticateButtonClicked_whenCorrect() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
FakeAuthenticationRepository.DEFAULT_PIN.forEach { digit -> FakeAuthenticationRepository.DEFAULT_PIN.forEach { digit ->
@@ -222,16 +198,12 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onAuthenticateButtonClicked_whenWrong() = fun onAuthenticateButtonClicked_whenWrong() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(bouncerViewModel.message) val message by collectLastValue(bouncerViewModel.message)
val pin by collectLastValue(underTest.pinInput.map { it.getPin() }) val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
underTest.onPinButtonClicked(1) underTest.onPinButtonClicked(1)
@@ -250,16 +222,12 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onAuthenticateButtonClicked_correctAfterWrong() = fun onAuthenticateButtonClicked_correctAfterWrong() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(bouncerViewModel.message) val message by collectLastValue(bouncerViewModel.message)
val pin by collectLastValue(underTest.pinInput.map { it.getPin() }) val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
underTest.onPinButtonClicked(1) underTest.onPinButtonClicked(1)
@@ -286,15 +254,11 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onAutoConfirm_whenCorrect() = fun onAutoConfirm_whenCorrect() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
utils.authenticationRepository.setAutoConfirmEnabled(true) utils.authenticationRepository.setAutoConfirmEnabled(true)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
FakeAuthenticationRepository.DEFAULT_PIN.forEach { digit -> FakeAuthenticationRepository.DEFAULT_PIN.forEach { digit ->
@@ -307,17 +271,13 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test @Test
fun onAutoConfirm_whenWrong() = fun onAutoConfirm_whenWrong() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
val message by collectLastValue(bouncerViewModel.message) val message by collectLastValue(bouncerViewModel.message)
val pin by collectLastValue(underTest.pinInput.map { it.getPin() }) val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
utils.authenticationRepository.setAutoConfirmEnabled(true) utils.authenticationRepository.setAutoConfirmEnabled(true)
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
SceneTestUtils.CONTAINER_1,
SceneModel(SceneKey.Bouncer)
)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown() underTest.onShown()
FakeAuthenticationRepository.DEFAULT_PIN.dropLast(1).forEach { digit -> FakeAuthenticationRepository.DEFAULT_PIN.dropLast(1).forEach { digit ->

View File

@@ -21,7 +21,6 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.scene.SceneTestUtils import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.SceneTestUtils.Companion.CONTAINER_1
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.SceneModel
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
@@ -91,7 +90,7 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
@Test @Test
fun dismissLockScreen_deviceLockedWithSecureAuthMethod_switchesToBouncer() = fun dismissLockScreen_deviceLockedWithSecureAuthMethod_switchesToBouncer() =
testScope.runTest { testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1)) val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
@@ -104,7 +103,7 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
@Test @Test
fun dismissLockScreen_deviceUnlocked_switchesToGone() = fun dismissLockScreen_deviceUnlocked_switchesToGone() =
testScope.runTest { testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1)) val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setUnlocked(true) utils.authenticationRepository.setUnlocked(true)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
@@ -117,7 +116,7 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
@Test @Test
fun dismissLockScreen_deviceLockedWithInsecureAuthMethod_switchesToGone() = fun dismissLockScreen_deviceLockedWithInsecureAuthMethod_switchesToGone() =
testScope.runTest { testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1)) val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
@@ -131,11 +130,11 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
fun switchFromLockScreenToGone_authMethodNotSwipe_doesNotUnlockDevice() = fun switchFromLockScreenToGone_authMethodNotSwipe_doesNotUnlockDevice() =
testScope.runTest { testScope.runTest {
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked) val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Lockscreen)) sceneInteractor.setCurrentScene(SceneModel(SceneKey.Lockscreen))
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
assertThat(isUnlocked).isFalse() assertThat(isUnlocked).isFalse()
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Gone)) sceneInteractor.setCurrentScene(SceneModel(SceneKey.Gone))
assertThat(isUnlocked).isFalse() assertThat(isUnlocked).isFalse()
} }
@@ -145,13 +144,13 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
testScope.runTest { testScope.runTest {
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked) val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
runCurrent() runCurrent()
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Shade)) sceneInteractor.setCurrentScene(SceneModel(SceneKey.Shade))
runCurrent() runCurrent()
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
runCurrent() runCurrent()
assertThat(isUnlocked).isFalse() assertThat(isUnlocked).isFalse()
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Gone)) sceneInteractor.setCurrentScene(SceneModel(SceneKey.Gone))
assertThat(isUnlocked).isFalse() assertThat(isUnlocked).isFalse()
} }
@@ -159,10 +158,10 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
@Test @Test
fun authMethodChangedToNone_notOnLockScreenScene_doesNotDismissLockScreen() = fun authMethodChangedToNone_notOnLockScreenScene_doesNotDismissLockScreen() =
testScope.runTest { testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1)) val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
runCurrent() runCurrent()
sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.QuickSettings)) sceneInteractor.setCurrentScene(SceneModel(SceneKey.QuickSettings))
runCurrent() runCurrent()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.QuickSettings)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.QuickSettings))

View File

@@ -22,9 +22,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Icon
import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import com.android.systemui.scene.SceneTestUtils import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.SceneTestUtils.Companion.CONTAINER_1
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.SceneModel
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
@@ -51,20 +49,15 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
private val underTest = private val underTest =
LockscreenSceneViewModel( LockscreenSceneViewModel(
applicationScope = testScope.backgroundScope, applicationScope = testScope.backgroundScope,
interactorFactory = interactor =
object : LockscreenSceneInteractor.Factory { utils.lockScreenSceneInteractor(
override fun create(containerName: String): LockscreenSceneInteractor { authenticationInteractor = authenticationInteractor,
return utils.lockScreenSceneInteractor( bouncerInteractor =
utils.bouncerInteractor(
authenticationInteractor = authenticationInteractor, authenticationInteractor = authenticationInteractor,
bouncerInteractor = sceneInteractor = sceneInteractor,
utils.bouncerInteractor( ),
authenticationInteractor = authenticationInteractor, ),
sceneInteractor = sceneInteractor,
),
)
}
},
containerName = CONTAINER_1
) )
@Test @Test
@@ -116,7 +109,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
@Test @Test
fun onLockButtonClicked_deviceLockedSecurely_switchesToBouncer() = fun onLockButtonClicked_deviceLockedSecurely_switchesToBouncer() =
testScope.runTest { testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1)) val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
runCurrent() runCurrent()
@@ -129,7 +122,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
@Test @Test
fun onContentClicked_deviceUnlocked_switchesToGone() = fun onContentClicked_deviceUnlocked_switchesToGone() =
testScope.runTest { testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1)) val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(true) utils.authenticationRepository.setUnlocked(true)
runCurrent() runCurrent()
@@ -142,7 +135,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
@Test @Test
fun onContentClicked_deviceLockedSecurely_switchesToBouncer() = fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
testScope.runTest { testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1)) val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
runCurrent() runCurrent()
@@ -155,7 +148,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
@Test @Test
fun onLockButtonClicked_deviceUnlocked_switchesToGone() = fun onLockButtonClicked_deviceUnlocked_switchesToGone() =
testScope.runTest { testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1)) val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(true) utils.authenticationRepository.setUnlocked(true)
runCurrent() runCurrent()

View File

@@ -20,9 +20,7 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import com.android.systemui.scene.SceneTestUtils import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.SceneTestUtils.Companion.CONTAINER_1
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.SceneModel
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
@@ -48,26 +46,21 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() {
private val underTest = private val underTest =
QuickSettingsSceneViewModel( QuickSettingsSceneViewModel(
lockscreenSceneInteractorFactory = lockscreenSceneInteractor =
object : LockscreenSceneInteractor.Factory { utils.lockScreenSceneInteractor(
override fun create(containerName: String): LockscreenSceneInteractor { authenticationInteractor = authenticationInteractor,
return utils.lockScreenSceneInteractor( bouncerInteractor =
utils.bouncerInteractor(
authenticationInteractor = authenticationInteractor, authenticationInteractor = authenticationInteractor,
bouncerInteractor = sceneInteractor = sceneInteractor,
utils.bouncerInteractor( ),
authenticationInteractor = authenticationInteractor, ),
sceneInteractor = sceneInteractor,
),
)
}
},
containerName = CONTAINER_1
) )
@Test @Test
fun onContentClicked_deviceUnlocked_switchesToGone() = fun onContentClicked_deviceUnlocked_switchesToGone() =
testScope.runTest { testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1)) val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(true) utils.authenticationRepository.setUnlocked(true)
runCurrent() runCurrent()
@@ -80,7 +73,7 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() {
@Test @Test
fun onContentClicked_deviceLockedSecurely_switchesToBouncer() = fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
testScope.runTest { testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1)) val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
runCurrent() runCurrent()

View File

@@ -41,7 +41,7 @@ class SceneContainerRepositoryTest : SysuiTestCase() {
@Test @Test
fun allSceneKeys() { fun allSceneKeys() {
val underTest = utils.fakeSceneContainerRepository() val underTest = utils.fakeSceneContainerRepository()
assertThat(underTest.allSceneKeys(SceneTestUtils.CONTAINER_1)) assertThat(underTest.allSceneKeys())
.isEqualTo( .isEqualTo(
listOf( listOf(
SceneKey.QuickSettings, SceneKey.QuickSettings,
@@ -53,162 +53,79 @@ class SceneContainerRepositoryTest : SysuiTestCase() {
) )
} }
@Test(expected = IllegalStateException::class)
fun allSceneKeys_noSuchContainer_throws() {
val underTest = utils.fakeSceneContainerRepository()
underTest.allSceneKeys("nonExistingContainer")
}
@Test @Test
fun currentScene() = runTest { fun currentScene() = runTest {
val underTest = utils.fakeSceneContainerRepository() val underTest = utils.fakeSceneContainerRepository()
val currentScene by collectLastValue(underTest.currentScene(SceneTestUtils.CONTAINER_1)) val currentScene by collectLastValue(underTest.currentScene)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
underTest.setCurrentScene(SceneTestUtils.CONTAINER_1, SceneModel(SceneKey.Shade)) underTest.setCurrentScene(SceneModel(SceneKey.Shade))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Shade)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Shade))
} }
@Test(expected = IllegalStateException::class)
fun currentScene_noSuchContainer_throws() {
val underTest = utils.fakeSceneContainerRepository()
underTest.currentScene("nonExistingContainer")
}
@Test(expected = IllegalStateException::class)
fun setCurrentScene_noSuchContainer_throws() {
val underTest = utils.fakeSceneContainerRepository()
underTest.setCurrentScene("nonExistingContainer", SceneModel(SceneKey.Shade))
}
@Test(expected = IllegalStateException::class) @Test(expected = IllegalStateException::class)
fun setCurrentScene_noSuchSceneInContainer_throws() { fun setCurrentScene_noSuchSceneInContainer_throws() {
val underTest = val underTest =
utils.fakeSceneContainerRepository( utils.fakeSceneContainerRepository(
setOf( utils.fakeSceneContainerConfig(listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)),
utils.fakeSceneContainerConfig(SceneTestUtils.CONTAINER_1),
utils.fakeSceneContainerConfig(
SceneTestUtils.CONTAINER_2,
listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)
),
)
) )
underTest.setCurrentScene(SceneTestUtils.CONTAINER_2, SceneModel(SceneKey.Shade)) underTest.setCurrentScene(SceneModel(SceneKey.Shade))
} }
@Test @Test
fun isVisible() = runTest { fun isVisible() = runTest {
val underTest = utils.fakeSceneContainerRepository() val underTest = utils.fakeSceneContainerRepository()
val isVisible by collectLastValue(underTest.isVisible(SceneTestUtils.CONTAINER_1)) val isVisible by collectLastValue(underTest.isVisible)
assertThat(isVisible).isTrue() assertThat(isVisible).isTrue()
underTest.setVisible(SceneTestUtils.CONTAINER_1, false) underTest.setVisible(false)
assertThat(isVisible).isFalse() assertThat(isVisible).isFalse()
underTest.setVisible(SceneTestUtils.CONTAINER_1, true) underTest.setVisible(true)
assertThat(isVisible).isTrue() assertThat(isVisible).isTrue()
} }
@Test(expected = IllegalStateException::class)
fun isVisible_noSuchContainer_throws() {
val underTest = utils.fakeSceneContainerRepository()
underTest.isVisible("nonExistingContainer")
}
@Test(expected = IllegalStateException::class)
fun setVisible_noSuchContainer_throws() {
val underTest = utils.fakeSceneContainerRepository()
underTest.setVisible("nonExistingContainer", false)
}
@Test @Test
fun sceneTransitionProgress() = runTest { fun transitionProgress() = runTest {
val underTest = utils.fakeSceneContainerRepository() val underTest = utils.fakeSceneContainerRepository()
val sceneTransitionProgress by val sceneTransitionProgress by collectLastValue(underTest.transitionProgress)
collectLastValue(underTest.sceneTransitionProgress(SceneTestUtils.CONTAINER_1))
assertThat(sceneTransitionProgress).isEqualTo(1f) assertThat(sceneTransitionProgress).isEqualTo(1f)
underTest.setSceneTransitionProgress(SceneTestUtils.CONTAINER_1, 0.1f) underTest.setSceneTransitionProgress(0.1f)
assertThat(sceneTransitionProgress).isEqualTo(0.1f) assertThat(sceneTransitionProgress).isEqualTo(0.1f)
underTest.setSceneTransitionProgress(SceneTestUtils.CONTAINER_1, 0.9f) underTest.setSceneTransitionProgress(0.9f)
assertThat(sceneTransitionProgress).isEqualTo(0.9f) assertThat(sceneTransitionProgress).isEqualTo(0.9f)
} }
@Test(expected = IllegalStateException::class)
fun sceneTransitionProgress_noSuchContainer_throws() {
val underTest = utils.fakeSceneContainerRepository()
underTest.sceneTransitionProgress("nonExistingContainer")
}
@Test @Test
fun setSceneTransition() = runTest { fun setSceneTransition() = runTest {
val underTest = val underTest = utils.fakeSceneContainerRepository()
utils.fakeSceneContainerRepository( val sceneTransition by collectLastValue(underTest.transitions)
setOf(
utils.fakeSceneContainerConfig(SceneTestUtils.CONTAINER_1),
utils.fakeSceneContainerConfig(
SceneTestUtils.CONTAINER_2,
listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)
),
)
)
val sceneTransition by
collectLastValue(underTest.sceneTransitions(SceneTestUtils.CONTAINER_2))
assertThat(sceneTransition).isNull() assertThat(sceneTransition).isNull()
underTest.setSceneTransition( underTest.setSceneTransition(SceneKey.Lockscreen, SceneKey.QuickSettings)
SceneTestUtils.CONTAINER_2,
SceneKey.Lockscreen,
SceneKey.QuickSettings
)
assertThat(sceneTransition) assertThat(sceneTransition)
.isEqualTo( .isEqualTo(
SceneTransitionModel(from = SceneKey.Lockscreen, to = SceneKey.QuickSettings) SceneTransitionModel(from = SceneKey.Lockscreen, to = SceneKey.QuickSettings)
) )
} }
@Test(expected = IllegalStateException::class)
fun setSceneTransition_noSuchContainer_throws() {
val underTest = utils.fakeSceneContainerRepository()
underTest.setSceneTransition("nonExistingContainer", SceneKey.Lockscreen, SceneKey.Shade)
}
@Test(expected = IllegalStateException::class) @Test(expected = IllegalStateException::class)
fun setSceneTransition_noFromSceneInContainer_throws() { fun setSceneTransition_noFromSceneInContainer_throws() {
val underTest = val underTest =
utils.fakeSceneContainerRepository( utils.fakeSceneContainerRepository(
setOf( utils.fakeSceneContainerConfig(listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)),
utils.fakeSceneContainerConfig(SceneTestUtils.CONTAINER_1),
utils.fakeSceneContainerConfig(
SceneTestUtils.CONTAINER_2,
listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)
),
)
) )
underTest.setSceneTransition( underTest.setSceneTransition(SceneKey.Shade, SceneKey.Lockscreen)
SceneTestUtils.CONTAINER_2,
SceneKey.Shade,
SceneKey.Lockscreen
)
} }
@Test(expected = IllegalStateException::class) @Test(expected = IllegalStateException::class)
fun setSceneTransition_noToSceneInContainer_throws() { fun setSceneTransition_noToSceneInContainer_throws() {
val underTest = val underTest =
utils.fakeSceneContainerRepository( utils.fakeSceneContainerRepository(
setOf( utils.fakeSceneContainerConfig(listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)),
utils.fakeSceneContainerConfig(SceneTestUtils.CONTAINER_1),
utils.fakeSceneContainerConfig(
SceneTestUtils.CONTAINER_2,
listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)
),
)
) )
underTest.setSceneTransition( underTest.setSceneTransition(SceneKey.Shade, SceneKey.Lockscreen)
SceneTestUtils.CONTAINER_2,
SceneKey.Shade,
SceneKey.Lockscreen
)
} }
} }

View File

@@ -41,48 +41,46 @@ class SceneInteractorTest : SysuiTestCase() {
@Test @Test
fun allSceneKeys() { fun allSceneKeys() {
assertThat(underTest.allSceneKeys(SceneTestUtils.CONTAINER_1)) assertThat(underTest.allSceneKeys()).isEqualTo(utils.fakeSceneKeys())
.isEqualTo(utils.fakeSceneKeys())
} }
@Test @Test
fun currentScene() = runTest { fun currentScene() = runTest {
val currentScene by collectLastValue(underTest.currentScene(SceneTestUtils.CONTAINER_1)) val currentScene by collectLastValue(underTest.currentScene)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
underTest.setCurrentScene(SceneTestUtils.CONTAINER_1, SceneModel(SceneKey.Shade)) underTest.setCurrentScene(SceneModel(SceneKey.Shade))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Shade)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Shade))
} }
@Test @Test
fun sceneTransitionProgress() = runTest { fun sceneTransitionProgress() = runTest {
val progress by val progress by collectLastValue(underTest.transitionProgress)
collectLastValue(underTest.sceneTransitionProgress(SceneTestUtils.CONTAINER_1))
assertThat(progress).isEqualTo(1f) assertThat(progress).isEqualTo(1f)
underTest.setSceneTransitionProgress(SceneTestUtils.CONTAINER_1, 0.55f) underTest.setSceneTransitionProgress(0.55f)
assertThat(progress).isEqualTo(0.55f) assertThat(progress).isEqualTo(0.55f)
} }
@Test @Test
fun isVisible() = runTest { fun isVisible() = runTest {
val isVisible by collectLastValue(underTest.isVisible(SceneTestUtils.CONTAINER_1)) val isVisible by collectLastValue(underTest.isVisible)
assertThat(isVisible).isTrue() assertThat(isVisible).isTrue()
underTest.setVisible(SceneTestUtils.CONTAINER_1, false) underTest.setVisible(false)
assertThat(isVisible).isFalse() assertThat(isVisible).isFalse()
underTest.setVisible(SceneTestUtils.CONTAINER_1, true) underTest.setVisible(true)
assertThat(isVisible).isTrue() assertThat(isVisible).isTrue()
} }
@Test @Test
fun sceneTransitions() = runTest { fun sceneTransitions() = runTest {
val transitions by collectLastValue(underTest.sceneTransitions(SceneTestUtils.CONTAINER_1)) val transitions by collectLastValue(underTest.transitions)
assertThat(transitions).isNull() assertThat(transitions).isNull()
val initialSceneKey = underTest.currentScene(SceneTestUtils.CONTAINER_1).value.key val initialSceneKey = underTest.currentScene.value.key
underTest.setCurrentScene(SceneTestUtils.CONTAINER_1, SceneModel(SceneKey.Shade)) underTest.setCurrentScene(SceneModel(SceneKey.Shade))
assertThat(transitions) assertThat(transitions)
.isEqualTo( .isEqualTo(
SceneTransitionModel( SceneTransitionModel(
@@ -91,7 +89,7 @@ class SceneInteractorTest : SysuiTestCase() {
) )
) )
underTest.setCurrentScene(SceneTestUtils.CONTAINER_1, SceneModel(SceneKey.QuickSettings)) underTest.setCurrentScene(SceneModel(SceneKey.QuickSettings))
assertThat(transitions) assertThat(transitions)
.isEqualTo( .isEqualTo(
SceneTransitionModel( SceneTransitionModel(

View File

@@ -28,7 +28,6 @@ import com.android.systemui.keyguard.shared.model.WakefulnessModel
import com.android.systemui.keyguard.shared.model.WakefulnessState import com.android.systemui.keyguard.shared.model.WakefulnessState
import com.android.systemui.model.SysUiState import com.android.systemui.model.SysUiState
import com.android.systemui.scene.SceneTestUtils import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.shared.model.SceneContainerNames
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.mock
@@ -47,7 +46,7 @@ import org.mockito.Mockito.verify
@SmallTest @SmallTest
@RunWith(JUnit4::class) @RunWith(JUnit4::class)
class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() { class SceneContainerStartableTest : SysuiTestCase() {
private val utils = SceneTestUtils(this) private val utils = SceneTestUtils(this)
private val testScope = utils.testScope private val testScope = utils.testScope
@@ -66,7 +65,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
private val sysUiState: SysUiState = mock() private val sysUiState: SysUiState = mock()
private val underTest = private val underTest =
SystemUiDefaultSceneContainerStartable( SceneContainerStartable(
applicationScope = testScope.backgroundScope, applicationScope = testScope.backgroundScope,
sceneInteractor = sceneInteractor, sceneInteractor = sceneInteractor,
authenticationInteractor = authenticationInteractor, authenticationInteractor = authenticationInteractor,
@@ -84,14 +83,8 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test @Test
fun hydrateVisibility_featureEnabled() = fun hydrateVisibility_featureEnabled() =
testScope.runTest { testScope.runTest {
val currentSceneKey by val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
collectLastValue( val isVisible by collectLastValue(sceneInteractor.isVisible)
sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
it.key
}
)
val isVisible by
collectLastValue(sceneInteractor.isVisible(SceneContainerNames.SYSTEM_UI_DEFAULT))
prepareState( prepareState(
isFeatureEnabled = true, isFeatureEnabled = true,
isDeviceUnlocked = true, isDeviceUnlocked = true,
@@ -104,24 +97,15 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
assertThat(isVisible).isFalse() assertThat(isVisible).isFalse()
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Shade))
SceneContainerNames.SYSTEM_UI_DEFAULT,
SceneModel(SceneKey.Shade)
)
assertThat(isVisible).isTrue() assertThat(isVisible).isTrue()
} }
@Test @Test
fun hydrateVisibility_featureDisabled() = fun hydrateVisibility_featureDisabled() =
testScope.runTest { testScope.runTest {
val currentSceneKey by val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
collectLastValue( val isVisible by collectLastValue(sceneInteractor.isVisible)
sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
it.key
}
)
val isVisible by
collectLastValue(sceneInteractor.isVisible(SceneContainerNames.SYSTEM_UI_DEFAULT))
prepareState( prepareState(
isFeatureEnabled = false, isFeatureEnabled = false,
isDeviceUnlocked = true, isDeviceUnlocked = true,
@@ -133,28 +117,17 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
underTest.start() underTest.start()
assertThat(isVisible).isTrue() assertThat(isVisible).isTrue()
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Gone))
SceneContainerNames.SYSTEM_UI_DEFAULT,
SceneModel(SceneKey.Gone)
)
assertThat(isVisible).isTrue() assertThat(isVisible).isTrue()
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(SceneKey.Shade))
SceneContainerNames.SYSTEM_UI_DEFAULT,
SceneModel(SceneKey.Shade)
)
assertThat(isVisible).isTrue() assertThat(isVisible).isTrue()
} }
@Test @Test
fun switchToLockscreenWhenDeviceLocks_featureEnabled() = fun switchToLockscreenWhenDeviceLocks_featureEnabled() =
testScope.runTest { testScope.runTest {
val currentSceneKey by val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
collectLastValue(
sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
it.key
}
)
prepareState( prepareState(
isFeatureEnabled = true, isFeatureEnabled = true,
isDeviceUnlocked = true, isDeviceUnlocked = true,
@@ -171,12 +144,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test @Test
fun switchToLockscreenWhenDeviceLocks_featureDisabled() = fun switchToLockscreenWhenDeviceLocks_featureDisabled() =
testScope.runTest { testScope.runTest {
val currentSceneKey by val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
collectLastValue(
sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
it.key
}
)
prepareState( prepareState(
isFeatureEnabled = false, isFeatureEnabled = false,
isDeviceUnlocked = false, isDeviceUnlocked = false,
@@ -193,12 +161,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test @Test
fun switchFromBouncerToGoneWhenDeviceUnlocked_featureEnabled() = fun switchFromBouncerToGoneWhenDeviceUnlocked_featureEnabled() =
testScope.runTest { testScope.runTest {
val currentSceneKey by val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
collectLastValue(
sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
it.key
}
)
prepareState( prepareState(
isFeatureEnabled = true, isFeatureEnabled = true,
isDeviceUnlocked = false, isDeviceUnlocked = false,
@@ -215,12 +178,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test @Test
fun switchFromBouncerToGoneWhenDeviceUnlocked_featureDisabled() = fun switchFromBouncerToGoneWhenDeviceUnlocked_featureDisabled() =
testScope.runTest { testScope.runTest {
val currentSceneKey by val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
collectLastValue(
sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
it.key
}
)
prepareState( prepareState(
isFeatureEnabled = false, isFeatureEnabled = false,
isDeviceUnlocked = false, isDeviceUnlocked = false,
@@ -237,12 +195,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test @Test
fun switchFromLockscreenToGoneWhenDeviceUnlocksWithBypassOn_featureOn_bypassOn() = fun switchFromLockscreenToGoneWhenDeviceUnlocksWithBypassOn_featureOn_bypassOn() =
testScope.runTest { testScope.runTest {
val currentSceneKey by val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
collectLastValue(
sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
it.key
}
)
prepareState( prepareState(
isFeatureEnabled = true, isFeatureEnabled = true,
isBypassEnabled = true, isBypassEnabled = true,
@@ -259,12 +212,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test @Test
fun switchFromLockscreenToGoneWhenDeviceUnlocksWithBypassOn_featureOn_bypassOff() = fun switchFromLockscreenToGoneWhenDeviceUnlocksWithBypassOn_featureOn_bypassOff() =
testScope.runTest { testScope.runTest {
val currentSceneKey by val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
collectLastValue(
sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
it.key
}
)
prepareState( prepareState(
isFeatureEnabled = true, isFeatureEnabled = true,
isBypassEnabled = false, isBypassEnabled = false,
@@ -281,12 +229,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test @Test
fun switchFromLockscreenToGoneWhenDeviceUnlocksWithBypassOn_featureOff_bypassOn() = fun switchFromLockscreenToGoneWhenDeviceUnlocksWithBypassOn_featureOff_bypassOn() =
testScope.runTest { testScope.runTest {
val currentSceneKey by val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
collectLastValue(
sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
it.key
}
)
prepareState( prepareState(
isFeatureEnabled = false, isFeatureEnabled = false,
isBypassEnabled = true, isBypassEnabled = true,
@@ -303,12 +246,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test @Test
fun switchToGoneWhenDeviceSleepsUnlocked_featureEnabled() = fun switchToGoneWhenDeviceSleepsUnlocked_featureEnabled() =
testScope.runTest { testScope.runTest {
val currentSceneKey by val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
collectLastValue(
sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
it.key
}
)
prepareState( prepareState(
isFeatureEnabled = true, isFeatureEnabled = true,
isDeviceUnlocked = true, isDeviceUnlocked = true,
@@ -325,12 +263,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test @Test
fun switchToGoneWhenDeviceSleepsUnlocked_featureDisabled() = fun switchToGoneWhenDeviceSleepsUnlocked_featureDisabled() =
testScope.runTest { testScope.runTest {
val currentSceneKey by val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
collectLastValue(
sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
it.key
}
)
prepareState( prepareState(
isFeatureEnabled = false, isFeatureEnabled = false,
isDeviceUnlocked = true, isDeviceUnlocked = true,
@@ -347,12 +280,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test @Test
fun switchToLockscreenWhenDeviceSleepsLocked_featureEnabled() = fun switchToLockscreenWhenDeviceSleepsLocked_featureEnabled() =
testScope.runTest { testScope.runTest {
val currentSceneKey by val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
collectLastValue(
sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
it.key
}
)
prepareState( prepareState(
isFeatureEnabled = true, isFeatureEnabled = true,
isDeviceUnlocked = false, isDeviceUnlocked = false,
@@ -369,12 +297,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test @Test
fun switchToLockscreenWhenDeviceSleepsLocked_featureDisabled() = fun switchToLockscreenWhenDeviceSleepsLocked_featureDisabled() =
testScope.runTest { testScope.runTest {
val currentSceneKey by val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
collectLastValue(
sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
it.key
}
)
prepareState( prepareState(
isFeatureEnabled = false, isFeatureEnabled = false,
isDeviceUnlocked = false, isDeviceUnlocked = false,
@@ -403,10 +326,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
SceneKey.QuickSettings, SceneKey.QuickSettings,
) )
.forEachIndexed { index, sceneKey -> .forEachIndexed { index, sceneKey ->
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(SceneModel(sceneKey))
SceneContainerNames.SYSTEM_UI_DEFAULT,
SceneModel(sceneKey),
)
runCurrent() runCurrent()
verify(sysUiState, times(index + 1)).commitUpdate(Display.DEFAULT_DISPLAY) verify(sysUiState, times(index + 1)).commitUpdate(Display.DEFAULT_DISPLAY)
@@ -422,9 +342,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
featureFlags.set(Flags.SCENE_CONTAINER, isFeatureEnabled) featureFlags.set(Flags.SCENE_CONTAINER, isFeatureEnabled)
authenticationRepository.setUnlocked(isDeviceUnlocked) authenticationRepository.setUnlocked(isDeviceUnlocked)
keyguardRepository.setBypassEnabled(isBypassEnabled) keyguardRepository.setBypassEnabled(isBypassEnabled)
initialSceneKey?.let { initialSceneKey?.let { sceneInteractor.setCurrentScene(SceneModel(it)) }
sceneInteractor.setCurrentScene(SceneContainerNames.SYSTEM_UI_DEFAULT, SceneModel(it))
}
} }
companion object { companion object {

View File

@@ -45,7 +45,6 @@ class SceneContainerViewModelTest : SysuiTestCase() {
private val underTest = private val underTest =
SceneContainerViewModel( SceneContainerViewModel(
interactor = interactor, interactor = interactor,
containerName = SceneTestUtils.CONTAINER_1,
) )
@Test @Test
@@ -53,10 +52,10 @@ class SceneContainerViewModelTest : SysuiTestCase() {
val isVisible by collectLastValue(underTest.isVisible) val isVisible by collectLastValue(underTest.isVisible)
assertThat(isVisible).isTrue() assertThat(isVisible).isTrue()
interactor.setVisible(SceneTestUtils.CONTAINER_1, false) interactor.setVisible(false)
assertThat(isVisible).isFalse() assertThat(isVisible).isFalse()
interactor.setVisible(SceneTestUtils.CONTAINER_1, true) interactor.setVisible(true)
assertThat(isVisible).isTrue() assertThat(isVisible).isTrue()
} }

View File

@@ -20,7 +20,6 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import com.android.systemui.scene.SceneTestUtils import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.SceneModel
@@ -48,20 +47,15 @@ class ShadeSceneViewModelTest : SysuiTestCase() {
private val underTest = private val underTest =
ShadeSceneViewModel( ShadeSceneViewModel(
applicationScope = testScope.backgroundScope, applicationScope = testScope.backgroundScope,
lockscreenSceneInteractorFactory = lockscreenSceneInteractor =
object : LockscreenSceneInteractor.Factory { utils.lockScreenSceneInteractor(
override fun create(containerName: String): LockscreenSceneInteractor { authenticationInteractor = authenticationInteractor,
return utils.lockScreenSceneInteractor( bouncerInteractor =
utils.bouncerInteractor(
authenticationInteractor = authenticationInteractor, authenticationInteractor = authenticationInteractor,
bouncerInteractor = sceneInteractor = sceneInteractor,
utils.bouncerInteractor( ),
authenticationInteractor = authenticationInteractor, ),
sceneInteractor = sceneInteractor,
),
)
}
},
containerName = SceneTestUtils.CONTAINER_1
) )
@Test @Test
@@ -87,8 +81,7 @@ class ShadeSceneViewModelTest : SysuiTestCase() {
@Test @Test
fun onContentClicked_deviceUnlocked_switchesToGone() = fun onContentClicked_deviceUnlocked_switchesToGone() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(true) utils.authenticationRepository.setUnlocked(true)
runCurrent() runCurrent()
@@ -101,8 +94,7 @@ class ShadeSceneViewModelTest : SysuiTestCase() {
@Test @Test
fun onContentClicked_deviceLockedSecurely_switchesToBouncer() = fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
testScope.runTest { testScope.runTest {
val currentScene by val currentScene by collectLastValue(sceneInteractor.currentScene)
collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false) utils.authenticationRepository.setUnlocked(false)
runCurrent() runCurrent()

View File

@@ -41,7 +41,6 @@ import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.RemoteUserInput import com.android.systemui.scene.shared.model.RemoteUserInput
import com.android.systemui.scene.shared.model.RemoteUserInputAction import com.android.systemui.scene.shared.model.RemoteUserInputAction
import com.android.systemui.scene.shared.model.SceneContainerConfig import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.SceneContainerNames
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.user.data.repository.FakeUserRepository import com.android.systemui.user.data.repository.FakeUserRepository
import com.android.systemui.user.data.repository.UserRepository import com.android.systemui.user.data.repository.UserRepository
@@ -96,13 +95,9 @@ class SceneTestUtils(
private val context = test.context private val context = test.context
fun fakeSceneContainerRepository( fun fakeSceneContainerRepository(
containerConfigurations: Set<SceneContainerConfig> = containerConfig: SceneContainerConfig = fakeSceneContainerConfig(),
setOf(
fakeSceneContainerConfig(CONTAINER_1),
fakeSceneContainerConfig(CONTAINER_2),
)
): SceneContainerRepository { ): SceneContainerRepository {
return SceneContainerRepository(containerConfigurations.associateBy { it.name }) return SceneContainerRepository(containerConfig)
} }
fun fakeSceneKeys(): List<SceneKey> { fun fakeSceneKeys(): List<SceneKey> {
@@ -116,11 +111,9 @@ class SceneTestUtils(
} }
fun fakeSceneContainerConfig( fun fakeSceneContainerConfig(
name: String,
sceneKeys: List<SceneKey> = fakeSceneKeys(), sceneKeys: List<SceneKey> = fakeSceneKeys(),
): SceneContainerConfig { ): SceneContainerConfig {
return SceneContainerConfig( return SceneContainerConfig(
name = name,
sceneKeys = sceneKeys, sceneKeys = sceneKeys,
initialSceneKey = SceneKey.Lockscreen, initialSceneKey = SceneKey.Lockscreen,
) )
@@ -174,7 +167,6 @@ class SceneTestUtils(
authenticationInteractor = authenticationInteractor, authenticationInteractor = authenticationInteractor,
sceneInteractor = sceneInteractor, sceneInteractor = sceneInteractor,
featureFlags = featureFlags, featureFlags = featureFlags,
containerName = CONTAINER_1,
) )
} }
@@ -184,14 +176,8 @@ class SceneTestUtils(
return BouncerViewModel( return BouncerViewModel(
applicationContext = context, applicationContext = context,
applicationScope = applicationScope(), applicationScope = applicationScope(),
interactorFactory = interactor = bouncerInteractor,
object : BouncerInteractor.Factory {
override fun create(containerName: String): BouncerInteractor {
return bouncerInteractor
}
},
featureFlags = featureFlags, featureFlags = featureFlags,
containerName = CONTAINER_1,
) )
} }
@@ -202,13 +188,7 @@ class SceneTestUtils(
return LockscreenSceneInteractor( return LockscreenSceneInteractor(
applicationScope = applicationScope(), applicationScope = applicationScope(),
authenticationInteractor = authenticationInteractor, authenticationInteractor = authenticationInteractor,
bouncerInteractorFactory = bouncerInteractor = bouncerInteractor,
object : BouncerInteractor.Factory {
override fun create(containerName: String): BouncerInteractor {
return bouncerInteractor
}
},
containerName = CONTAINER_1,
) )
} }
@@ -217,9 +197,6 @@ class SceneTestUtils(
} }
companion object { companion object {
const val CONTAINER_1 = SceneContainerNames.SYSTEM_UI_DEFAULT
const val CONTAINER_2 = "container2"
val REMOTE_INPUT_DOWN_GESTURE = val REMOTE_INPUT_DOWN_GESTURE =
listOf( listOf(
RemoteUserInput(10f, 10f, RemoteUserInputAction.DOWN), RemoteUserInput(10f, 10f, RemoteUserInputAction.DOWN),