summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt61
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt162
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt29
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitionsKosmos.kt2
8 files changed, 142 insertions, 167 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
index a8fe16b12e1b..9f707262db3a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
@@ -83,25 +83,6 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
- fun deviceDreaming_forceBlankScene() =
- with(kosmos) {
- testScope.runTest {
- val scene by collectLastValue(communalInteractor.desiredScene)
-
- communalInteractor.onSceneChanged(CommunalSceneKey.Communal)
- assertThat(scene).isEqualTo(CommunalSceneKey.Communal)
-
- fakeKeyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.GLANCEABLE_HUB,
- to = KeyguardState.DREAMING,
- testScope = this
- )
-
- assertThat(scene).isEqualTo(CommunalSceneKey.Blank)
- }
- }
-
- @Test
fun deviceDocked_forceCommunalScene() =
with(kosmos) {
testScope.runTest {
@@ -115,13 +96,6 @@ class CommunalSceneStartableTest : SysuiTestCase() {
testScope = this
)
assertThat(scene).isEqualTo(CommunalSceneKey.Communal)
-
- fakeKeyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.GLANCEABLE_HUB,
- to = KeyguardState.DREAMING,
- testScope = this
- )
- assertThat(scene).isEqualTo(CommunalSceneKey.Blank)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
index f7ba5a44f4c9..8397372e0735 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
@@ -88,7 +88,6 @@ constructor(
val docked = dockManager.isDocked
return when {
- to == KeyguardState.DREAMING -> CommunalSceneKey.Blank
docked && to == KeyguardState.LOCKSCREEN && from != KeyguardState.GLANCEABLE_HUB -> {
CommunalSceneKey.Communal
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
index c6594ef317d6..acfa107cc1f1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
@@ -18,6 +18,7 @@ package com.android.systemui.keyguard.domain.interactor
import android.animation.ValueAnimator
import com.android.app.animation.Interpolators
+import com.android.app.tracing.coroutines.launch
import com.android.systemui.Flags.communalHub
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
@@ -64,12 +65,13 @@ constructor(
private fun listenForDreamingToGlanceableHub() {
if (!communalHub()) return
- glanceableHubTransitions.listenForGlanceableHubTransition(
- transitionName = "listenForDreamingToGlanceableHub",
- transitionOwnerName = TAG,
- fromState = KeyguardState.DREAMING,
- toState = KeyguardState.GLANCEABLE_HUB,
- )
+ scope.launch("$TAG#listenForDreamingToGlanceableHub", mainDispatcher) {
+ glanceableHubTransitions.listenForGlanceableHubTransition(
+ transitionOwnerName = TAG,
+ fromState = KeyguardState.DREAMING,
+ toState = KeyguardState.GLANCEABLE_HUB,
+ )
+ }
}
fun startToLockscreenTransition() {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
index fbf195eb0952..786c3c6697d9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
@@ -27,13 +27,16 @@ import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
import com.android.systemui.power.domain.interactor.PowerInteractor
-import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleMultiple
+import com.android.systemui.util.kotlin.BooleanFlowOperators.and
+import com.android.systemui.util.kotlin.BooleanFlowOperators.not
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
@SysUISingleton
class FromGlanceableHubTransitionInteractor
@@ -58,13 +61,12 @@ constructor(
if (!Flags.communalHub()) {
return
}
- listenForHubToLockscreen()
+ listenForHubToLockscreenOrDreaming()
listenForHubToDozing()
listenForHubToPrimaryBouncer()
listenForHubToAlternateBouncer()
listenForHubToOccluded()
listenForHubToGone()
- listenForHubToDreaming()
}
override fun getDefaultAnimatorForTransitionsToState(toState: KeyguardState): ValueAnimator {
@@ -82,13 +84,24 @@ constructor(
* Listens for the glanceable hub transition to lock screen and directly drives the keyguard
* transition.
*/
- private fun listenForHubToLockscreen() {
- glanceableHubTransitions.listenForGlanceableHubTransition(
- transitionName = "listenForHubToLockscreen",
- transitionOwnerName = TAG,
- fromState = KeyguardState.GLANCEABLE_HUB,
- toState = KeyguardState.LOCKSCREEN,
- )
+ private fun listenForHubToLockscreenOrDreaming() {
+ scope.launch("$TAG#listenForGlanceableHubToLockscreenOrDream") {
+ keyguardInteractor.isDreaming.collectLatest { dreaming ->
+ withContext(mainDispatcher) {
+ val toState =
+ if (dreaming) {
+ KeyguardState.DREAMING
+ } else {
+ KeyguardState.LOCKSCREEN
+ }
+ glanceableHubTransitions.listenForGlanceableHubTransition(
+ transitionOwnerName = TAG,
+ fromState = KeyguardState.GLANCEABLE_HUB,
+ toState = toState,
+ )
+ }
+ }
+ }
}
private fun listenForHubToPrimaryBouncer() {
@@ -137,31 +150,15 @@ constructor(
}
}
- private fun listenForHubToDreaming() {
- val invalidFromStates = setOf(KeyguardState.AOD, KeyguardState.DOZING)
- scope.launch("$TAG#listenForHubToDreaming") {
- keyguardInteractor.isAbleToDream
- .sampleMultiple(startedKeyguardTransitionStep, finishedKeyguardState)
- .collect { (isAbleToDream, lastStartedTransition, finishedKeyguardState) ->
- val isOnHub = finishedKeyguardState == KeyguardState.GLANCEABLE_HUB
- val isTransitionInterruptible =
- lastStartedTransition.to == KeyguardState.GLANCEABLE_HUB &&
- !invalidFromStates.contains(lastStartedTransition.from)
- if (isAbleToDream && (isOnHub || isTransitionInterruptible)) {
- startTransitionTo(KeyguardState.DREAMING)
- }
- }
- }
- }
-
private fun listenForHubToOccluded() {
scope.launch {
- keyguardInteractor.isKeyguardOccluded.sample(startedKeyguardState, ::Pair).collect {
- (isOccluded, keyguardState) ->
- if (isOccluded && keyguardState == fromState) {
- startTransitionTo(KeyguardState.OCCLUDED)
+ and(keyguardInteractor.isKeyguardOccluded, not(keyguardInteractor.isDreaming))
+ .sample(startedKeyguardState, ::Pair)
+ .collect { (isOccludedAndNotDreaming, keyguardState) ->
+ if (isOccludedAndNotDreaming && keyguardState == fromState) {
+ startTransitionTo(KeyguardState.OCCLUDED)
+ }
}
- }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
index 40b2c638823d..7263ae96b3a8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
@@ -360,13 +360,13 @@ constructor(
if (!com.android.systemui.Flags.communalHub()) {
return
}
-
- glanceableHubTransitions.listenForGlanceableHubTransition(
- transitionName = "listenForLockscreenToGlanceableHub",
- transitionOwnerName = TAG,
- fromState = KeyguardState.LOCKSCREEN,
- toState = KeyguardState.GLANCEABLE_HUB,
- )
+ scope.launch(mainDispatcher) {
+ glanceableHubTransitions.listenForGlanceableHubTransition(
+ transitionOwnerName = TAG,
+ fromState = KeyguardState.LOCKSCREEN,
+ toState = KeyguardState.GLANCEABLE_HUB,
+ )
+ }
}
override fun getDefaultAnimatorForTransitionsToState(toState: KeyguardState): ValueAnimator {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt
index 809c0aee9882..6cb1eb493db3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt
@@ -18,11 +18,9 @@ package com.android.systemui.keyguard.domain.interactor
import android.animation.ValueAnimator
import com.android.app.animation.Interpolators
-import com.android.app.tracing.coroutines.launch
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalTransitionProgress
import com.android.systemui.communal.shared.model.CommunalSceneKey
-import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -32,13 +30,11 @@ import com.android.systemui.util.kotlin.sample
import java.util.UUID
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.flowOn
class GlanceableHubTransitions
@Inject
constructor(
- @Application private val scope: CoroutineScope,
@Background private val bgDispatcher: CoroutineDispatcher,
private val transitionInteractor: KeyguardTransitionInteractor,
private val transitionRepository: KeyguardTransitionRepository,
@@ -52,105 +48,101 @@ constructor(
* externally. The progress is used for both transitions caused by user touch input or by
* programmatic changes.
*/
- fun listenForGlanceableHubTransition(
- transitionName: String,
+ suspend fun listenForGlanceableHubTransition(
transitionOwnerName: String,
fromState: KeyguardState,
toState: KeyguardState,
) {
val toScene =
- if (toState == KeyguardState.GLANCEABLE_HUB) {
- CommunalSceneKey.Communal
- } else {
+ if (fromState == KeyguardState.GLANCEABLE_HUB) {
CommunalSceneKey.Blank
+ } else {
+ CommunalSceneKey.Communal
}
var transitionId: UUID? = null
- scope.launch("$transitionOwnerName#$transitionName") {
- communalInteractor
- .transitionProgressToScene(toScene)
- .sample(
- transitionInteractor.startedKeyguardTransitionStep.flowOn(bgDispatcher),
- ::Pair
- )
- .collect { pair ->
- val (transitionProgress, lastStartedStep) = pair
- val id = transitionId
- if (id == null) {
- // No transition started.
- if (
- transitionProgress is CommunalTransitionProgress.Transition &&
- lastStartedStep.to == fromState
- ) {
- transitionId =
- transitionRepository.startTransition(
- TransitionInfo(
- ownerName = transitionOwnerName,
- from = fromState,
- to = toState,
- animator = null, // transition will be manually controlled
- )
+ communalInteractor
+ .transitionProgressToScene(toScene)
+ .sample(
+ transitionInteractor.startedKeyguardTransitionStep.flowOn(bgDispatcher),
+ ::Pair,
+ )
+ .collect { (transitionProgress, lastStartedStep) ->
+ val id = transitionId
+ if (id == null) {
+ // No transition started.
+ if (
+ transitionProgress is CommunalTransitionProgress.Transition &&
+ lastStartedStep.to == fromState
+ ) {
+ transitionId =
+ transitionRepository.startTransition(
+ TransitionInfo(
+ ownerName = transitionOwnerName,
+ from = fromState,
+ to = toState,
+ animator = null, // transition will be manually controlled
)
- }
- } else {
- if (lastStartedStep.to != toState) {
- return@collect
- }
- // An existing `id` means a transition is started, and calls to
- // `updateTransition` will control it until FINISHED or CANCELED
- val nextState: TransitionState
- val progressFraction: Float
- when (transitionProgress) {
- is CommunalTransitionProgress.Idle -> {
- if (transitionProgress.scene == toScene) {
- nextState = TransitionState.FINISHED
- progressFraction = 1f
- } else {
- nextState = TransitionState.CANCELED
- progressFraction = 0f
- }
- }
- is CommunalTransitionProgress.Transition -> {
- nextState = TransitionState.RUNNING
- progressFraction = transitionProgress.progress
- }
- is CommunalTransitionProgress.OtherTransition -> {
- // Shouldn't happen but if another transition starts during the
- // current one, mark the current one as canceled.
+ )
+ }
+ } else {
+ if (lastStartedStep.to != toState) {
+ return@collect
+ }
+ // An existing `id` means a transition is started, and calls to
+ // `updateTransition` will control it until FINISHED or CANCELED
+ val nextState: TransitionState
+ val progressFraction: Float
+ when (transitionProgress) {
+ is CommunalTransitionProgress.Idle -> {
+ if (transitionProgress.scene == toScene) {
+ nextState = TransitionState.FINISHED
+ progressFraction = 1f
+ } else {
nextState = TransitionState.CANCELED
progressFraction = 0f
}
}
- transitionRepository.updateTransition(
- id,
- progressFraction,
- nextState,
- )
-
- if (
- nextState == TransitionState.CANCELED ||
- nextState == TransitionState.FINISHED
- ) {
- transitionId = null
+ is CommunalTransitionProgress.Transition -> {
+ nextState = TransitionState.RUNNING
+ progressFraction = transitionProgress.progress
}
+ is CommunalTransitionProgress.OtherTransition -> {
+ // Shouldn't happen but if another transition starts during the
+ // current one, mark the current one as canceled.
+ nextState = TransitionState.CANCELED
+ progressFraction = 0f
+ }
+ }
+ transitionRepository.updateTransition(
+ id,
+ progressFraction,
+ nextState,
+ )
- // If canceled, just put the state back.
- if (nextState == TransitionState.CANCELED) {
- transitionRepository.startTransition(
- TransitionInfo(
- ownerName = transitionOwnerName,
- from = toState,
- to = fromState,
- animator =
- ValueAnimator().apply {
- interpolator = Interpolators.LINEAR
- duration = 0
- }
- )
+ if (
+ nextState == TransitionState.CANCELED ||
+ nextState == TransitionState.FINISHED
+ ) {
+ transitionId = null
+ }
+
+ // If canceled, just put the state back.
+ if (nextState == TransitionState.CANCELED) {
+ transitionRepository.startTransition(
+ TransitionInfo(
+ ownerName = transitionOwnerName,
+ from = toState,
+ to = fromState,
+ animator =
+ ValueAnimator().apply {
+ interpolator = Interpolators.LINEAR
+ duration = 0
+ }
)
- }
+ )
}
}
- }
+ }
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
index abd42387cc2e..69cd173f4253 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
@@ -129,7 +129,6 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
val glanceableHubTransitions =
GlanceableHubTransitions(
- scope = testScope,
bgDispatcher = kosmos.testDispatcher,
transitionInteractor = transitionInteractor,
transitionRepository = transitionRepository,
@@ -1812,26 +1811,40 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
@Test
fun glanceableHubToDreaming() =
testScope.runTest {
- // GIVEN a device that is not dreaming or dozing
- keyguardRepository.setDreamingWithOverlay(false)
+ // GIVEN that we are dreaming and not dozing
+ keyguardRepository.setDreaming(true)
keyguardRepository.setDozeTransitionModel(
DozeTransitionModel(from = DozeStateModel.DOZE, to = DozeStateModel.FINISH)
)
runCurrent()
// GIVEN a prior transition has run to GLANCEABLE_HUB
- runTransitionAndSetWakefulness(KeyguardState.LOCKSCREEN, KeyguardState.GLANCEABLE_HUB)
+ runTransitionAndSetWakefulness(KeyguardState.DREAMING, KeyguardState.GLANCEABLE_HUB)
+ runCurrent()
- // WHEN the device begins to dream
- keyguardRepository.setDreamingWithOverlay(true)
- advanceTimeBy(100L)
+ // WHEN a transition away from glanceable hub starts
+ val currentScene = CommunalSceneKey.Communal
+ val targetScene = CommunalSceneKey.Blank
+
+ val transitionState =
+ MutableStateFlow<ObservableCommunalTransitionState>(
+ ObservableCommunalTransitionState.Transition(
+ fromScene = currentScene,
+ toScene = targetScene,
+ progress = flowOf(0f, 0.1f),
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
+ )
+ )
+ communalInteractor.setTransitionState(transitionState)
+ runCurrent()
assertThat(transitionRepository)
.startedTransition(
ownerName = FromGlanceableHubTransitionInteractor::class.simpleName,
from = KeyguardState.GLANCEABLE_HUB,
to = KeyguardState.DREAMING,
- animatorAssertion = { it.isNotNull() },
+ animatorAssertion = { it.isNull() }, // transition should be manually animated
)
coroutineContext.cancelChildren()
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitionsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitionsKosmos.kt
index 55885bf58acc..5dd50731c58a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitionsKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitionsKosmos.kt
@@ -19,13 +19,11 @@ package com.android.systemui.keyguard.domain.interactor
import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testDispatcher
val Kosmos.glanceableHubTransitions by
Kosmos.Fixture {
GlanceableHubTransitions(
- scope = applicationCoroutineScope,
bgDispatcher = testDispatcher,
transitionRepository = keyguardTransitionRepository,
transitionInteractor = keyguardTransitionInteractor,