summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ale Nijamkin <nijamkin@google.com> 2023-09-19 20:47:07 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-09-19 20:47:07 +0000
commite1859f9ce89b9fb14de38eee1490a68ad98f6f90 (patch)
tree74a0425d4d937ee16847f8719ec27d5978f9a47d
parentd4d75ae192b6b44fd6ccfff3ff63edfbd20e6c01 (diff)
parenteacba4edfb27de3bf0cacde3c7d4068f288bd3c9 (diff)
Merge "[flexiglass] destinationScenes a stable flow." into main
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt2
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt4
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt3
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt2
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt4
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt31
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt1
10 files changed, 44 insertions, 35 deletions
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
index e06a69bfaa63..5505eaf8fd7e 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
@@ -82,7 +82,7 @@ constructor(
) : ComposableScene {
override val key = SceneKey.Bouncer
- override fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
+ override val destinationScenes: StateFlow<Map<UserAction, SceneModel>> =
MutableStateFlow(
mapOf(
UserAction.Back to SceneModel(SceneKey.Lockscreen),
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
index 463253b9fb41..f1da16862220 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
@@ -66,13 +66,13 @@ constructor(
) : ComposableScene {
override val key = SceneKey.Lockscreen
- override fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
+ override val destinationScenes: StateFlow<Map<UserAction, SceneModel>> =
viewModel.upDestinationSceneKey
.map { pageKey -> destinationScenes(up = pageKey) }
.stateIn(
scope = applicationScope,
started = SharingStarted.Eagerly,
- initialValue = destinationScenes(up = null)
+ initialValue = destinationScenes(up = viewModel.upDestinationSceneKey.value)
)
@Composable
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
index 7ac39011d4da..1f9c3e6d1ea1 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
@@ -58,13 +58,14 @@ constructor(
) : ComposableScene {
override val key = SceneKey.QuickSettings
- override fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
+ private val _destinationScenes =
MutableStateFlow<Map<UserAction, SceneModel>>(
mapOf(
UserAction.Swipe(Direction.UP) to SceneModel(SceneKey.Shade),
)
)
.asStateFlow()
+ override val destinationScenes: StateFlow<Map<UserAction, SceneModel>> = _destinationScenes
@Composable
override fun SceneScope.Content(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
index 40b0b4a3eaa3..2ee461fca042 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
@@ -38,7 +38,7 @@ import kotlinx.coroutines.flow.asStateFlow
class GoneScene @Inject constructor() : ComposableScene {
override val key = SceneKey.Gone
- override fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
+ override val destinationScenes: StateFlow<Map<UserAction, SceneModel>> =
MutableStateFlow<Map<UserAction, SceneModel>>(
mapOf(
UserAction.Swipe(Direction.DOWN) to SceneModel(SceneKey.Shade),
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
index 6a5a368b3599..47af842c1511 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
@@ -79,7 +79,7 @@ fun SceneContainer(
val currentSceneKey = currentSceneModel.key
val currentScene = checkNotNull(sceneByKey[currentSceneKey])
val currentDestinations: Map<UserAction, SceneModel> by
- currentScene.destinationScenes().collectAsState()
+ currentScene.destinationScenes.collectAsState()
val state = remember { SceneTransitionLayoutState(currentSceneKey.toTransitionSceneKey()) }
val isRibbonEnabled = remember { SystemProperties.getBoolean("flexi.ribbon", false) }
@@ -116,7 +116,7 @@ fun SceneContainer(
if (sceneKey == currentSceneKey) {
currentDestinations
} else {
- composableScene.destinationScenes().value
+ composableScene.destinationScenes.value
}
.map { (userAction, destinationSceneModel) ->
toTransitionModels(userAction, destinationSceneModel)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
index b1056376220f..8832a119dbfd 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
@@ -87,7 +87,7 @@ constructor(
) : ComposableScene {
override val key = SceneKey.Shade
- override fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
+ override val destinationScenes: StateFlow<Map<UserAction, SceneModel>> =
viewModel.upDestinationSceneKey
.map { sceneKey -> destinationScenes(up = sceneKey) }
.stateIn(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
index 05c932372ccf..cfcbdac4c4e9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
@@ -18,26 +18,39 @@ package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.scene.shared.model.SceneKey
import javax.inject.Inject
-import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
/** Models UI state and handles user input for the lockscreen scene. */
@SysUISingleton
class LockscreenSceneViewModel
@Inject
constructor(
+ @Application applicationScope: CoroutineScope,
authenticationInteractor: AuthenticationInteractor,
val longPress: KeyguardLongPressViewModel,
) {
/** The key of the scene we should switch to when swiping up. */
- val upDestinationSceneKey: Flow<SceneKey> =
- authenticationInteractor.isUnlocked.map { isUnlocked ->
- if (isUnlocked) {
- SceneKey.Gone
- } else {
- SceneKey.Bouncer
- }
+ val upDestinationSceneKey: StateFlow<SceneKey> =
+ authenticationInteractor.isUnlocked
+ .map { isUnlocked -> upDestinationSceneKey(isUnlocked) }
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = upDestinationSceneKey(authenticationInteractor.isUnlocked.value),
+ )
+
+ private fun upDestinationSceneKey(isUnlocked: Boolean): SceneKey {
+ return if (isUnlocked) {
+ SceneKey.Gone
+ } else {
+ SceneKey.Bouncer
}
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt
index 31597c1752db..4bc93a8f1ca5 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt
@@ -16,9 +16,7 @@
package com.android.systemui.scene.shared.model
-import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
/**
* Defines interface for classes that can describe a "scene".
@@ -34,31 +32,26 @@ interface Scene {
val key: SceneKey
/**
- * Returns a mapping between [UserAction] and flows that emit a [SceneModel].
+ * The mapping between [UserAction] and destination [SceneModel]s.
*
- * When the scene framework detects the user action, it starts a transition to the scene
- * described by the latest value in the flow that's mapped from that user action.
+ * When the scene framework detects a user action, if the current scene has a map entry for that
+ * user action, the framework starts a transition to the scene in the map.
*
- * Once the [Scene] becomes the current one, the scene framework will invoke this method and set
- * up collectors to watch for new values emitted to each of the flows. If a value is added to
- * the map at a given [UserAction], the framework will set up user input handling for that
- * [UserAction] and, if such a user action is detected, the framework will initiate a transition
- * to that [SceneModel].
+ * Once the [Scene] becomes the current one, the scene framework will read this property and set
+ * up a collector to watch for new mapping values. If every map entry provided by the scene, the
+ * framework will set up user input handling for its [UserAction] and, if such a user action is
+ * detected, initiate a transition to the specified [SceneModel].
*
- * Note that calling this method does _not_ mean that the given user action has occurred.
- * Instead, the method is called before any user action/gesture is detected so that the
- * framework can decide whether to set up gesture/input detectors/listeners for that type of
- * user action.
+ * Note that reading from this method does _not_ mean that any user action has occurred.
+ * Instead, the property is read before any user action/gesture is detected so that the
+ * framework can decide whether to set up gesture/input detectors/listeners in case user actions
+ * of the given types ever occur.
*
* Note that a missing value for a specific [UserAction] means that the user action of the given
* type is not currently active in the scene and should be ignored by the framework, while the
* current scene is this one.
- *
- * 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.
*/
- fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
- MutableStateFlow(emptyMap<UserAction, SceneModel>()).asStateFlow()
+ val destinationScenes: StateFlow<Map<UserAction, SceneModel>>
}
/** Enumerates all scene framework supported user actions. */
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
index b30dc9cc67c4..f40ccfde5a92 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
@@ -44,6 +44,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
private val underTest =
LockscreenSceneViewModel(
+ applicationScope = testScope.backgroundScope,
authenticationInteractor = authenticationInteractor,
longPress =
KeyguardLongPressViewModel(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
index 141fcbb15c0c..78385cd516c8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -123,6 +123,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
private val lockscreenSceneViewModel =
LockscreenSceneViewModel(
+ applicationScope = testScope.backgroundScope,
authenticationInteractor = authenticationInteractor,
longPress =
KeyguardLongPressViewModel(