diff options
4 files changed, 103 insertions, 2 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt index acbd9fb4c407..f45a9ecfaedf 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt @@ -134,8 +134,9 @@ constructor( powerInteractor.isAwake, startedKeyguardTransitionStep, keyguardInteractor.isKeyguardOccluded, + keyguardInteractor.isDreaming, keyguardInteractor.isActiveDreamLockscreenHosted, - communalInteractor.isIdleOnCommunal + communalInteractor.isIdleOnCommunal, ) .collect { ( @@ -143,6 +144,7 @@ constructor( isAwake, lastStartedTransitionStep, occluded, + isDreaming, isActiveDreamLockscreenHosted, isIdleOnCommunal) -> if ( @@ -152,10 +154,12 @@ constructor( !isActiveDreamLockscreenHosted ) { val toState = - if (occluded) { + if (occluded && !isDreaming) { KeyguardState.OCCLUDED } else if (isIdleOnCommunal) { KeyguardState.GLANCEABLE_HUB + } else if (isDreaming) { + KeyguardState.DREAMING } else { KeyguardState.LOCKSCREEN } diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt index d47413faeadf..bb907cc0055e 100644 --- a/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt +++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt @@ -245,6 +245,29 @@ fun <T> Flow<T>.throttle(periodMs: Long, clock: SystemClock = SystemClockImpl()) } } +inline fun <T1, T2, T3, T4, T5, T6, R> combine( + flow: Flow<T1>, + flow2: Flow<T2>, + flow3: Flow<T3>, + flow4: Flow<T4>, + flow5: Flow<T5>, + flow6: Flow<T6>, + crossinline transform: suspend (T1, T2, T3, T4, T5, T6) -> R +): Flow<R> { + return kotlinx.coroutines.flow.combine(flow, flow2, flow3, flow4, flow5, flow6) { + args: Array<*> -> + @Suppress("UNCHECKED_CAST") + transform( + args[0] as T1, + args[1] as T2, + args[2] as T3, + args[3] as T4, + args[4] as T5, + args[5] as T6, + ) + } +} + inline fun <T1, T2, T3, T4, T5, T6, T7, R> combine( flow: Flow<T1>, flow2: Flow<T2>, diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/Utils.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/Utils.kt index fa0d0306f157..a88be065d722 100644 --- a/packages/SystemUI/src/com/android/systemui/util/kotlin/Utils.kt +++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/Utils.kt @@ -36,6 +36,17 @@ class Utils { fun <A, B, C, D, E, F> toSextuple(a: A, bcdef: Quint<B, C, D, E, F>) = Sextuple(a, bcdef.first, bcdef.second, bcdef.third, bcdef.fourth, bcdef.fifth) + fun <A, B, C, D, E, F, G> toSeptuple(a: A, bcdefg: Sextuple<B, C, D, E, F, G>) = + Septuple( + a, + bcdefg.first, + bcdefg.second, + bcdefg.third, + bcdefg.fourth, + bcdefg.fifth, + bcdefg.sixth + ) + /** * Samples the provided flows, emitting a tuple of the original flow's value as well as each * of the combined flows' values. @@ -90,6 +101,24 @@ class Utils { ): Flow<Sextuple<A, B, C, D, E, F>> { return this.sample(combine(b, c, d, e, f, ::Quint), ::toSextuple) } + + /** + * Samples the provided flows, emitting a tuple of the original flow's value as well as each + * of the combined flows' values. + * + * Flow<A>.sample(Flow<B>, Flow<C>, Flow<D>, Flow<E>, Flow<F>, Flow<G>) -> (A, B, C, D, E, + * F, G) + */ + fun <A, B, C, D, E, F, G> Flow<A>.sample( + b: Flow<B>, + c: Flow<C>, + d: Flow<D>, + e: Flow<E>, + f: Flow<F>, + g: Flow<G>, + ): Flow<Septuple<A, B, C, D, E, F, G>> { + return this.sample(combine(b, c, d, e, f, g, ::Sextuple), ::toSeptuple) + } } } @@ -112,6 +141,16 @@ data class Sextuple<A, B, C, D, E, F>( val sixth: F, ) +data class Septuple<A, B, C, D, E, F, G>( + val first: A, + val second: B, + val third: C, + val fourth: D, + val fifth: E, + val sixth: F, + val seventh: G, +) + fun Int.toPx(context: Context): Int { return (this * context.resources.displayMetrics.density).toInt() } 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 a5d577dceecb..abd42387cc2e 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 @@ -1097,6 +1097,41 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test + fun primaryBouncerToGlanceableHubWhileDreaming() = + testScope.runTest { + // GIVEN a prior transition has run to PRIMARY_BOUNCER + bouncerRepository.setPrimaryShow(true) + runTransitionAndSetWakefulness(KeyguardState.LOCKSCREEN, KeyguardState.PRIMARY_BOUNCER) + + // GIVEN that we are dreaming and occluded + keyguardRepository.setDreaming(true) + keyguardRepository.setKeyguardOccluded(true) + + // GIVEN the device is idle on the glanceable hub + val idleTransitionState = + MutableStateFlow<ObservableCommunalTransitionState>( + ObservableCommunalTransitionState.Idle(CommunalSceneKey.Communal) + ) + communalInteractor.setTransitionState(idleTransitionState) + runCurrent() + + // WHEN the primaryBouncer stops showing + bouncerRepository.setPrimaryShow(false) + runCurrent() + + // THEN a transition to LOCKSCREEN should occur + assertThat(transitionRepository) + .startedTransition( + ownerName = FromPrimaryBouncerTransitionInteractor::class.simpleName, + from = KeyguardState.PRIMARY_BOUNCER, + to = KeyguardState.GLANCEABLE_HUB, + animatorAssertion = { it.isNotNull() }, + ) + + coroutineContext.cancelChildren() + } + + @Test fun primaryBouncerToDreamingLockscreenHosted() = testScope.runTest { // GIVEN device dreaming with the lockscreen hosted dream and not dozing |