Loading packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt +6 −2 Original line number Diff line number Diff line Loading @@ -134,8 +134,9 @@ constructor( powerInteractor.isAwake, startedKeyguardTransitionStep, keyguardInteractor.isKeyguardOccluded, keyguardInteractor.isDreaming, keyguardInteractor.isActiveDreamLockscreenHosted, communalInteractor.isIdleOnCommunal communalInteractor.isIdleOnCommunal, ) .collect { ( Loading @@ -143,6 +144,7 @@ constructor( isAwake, lastStartedTransitionStep, occluded, isDreaming, isActiveDreamLockscreenHosted, isIdleOnCommunal) -> if ( Loading @@ -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 } Loading packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt +23 −0 Original line number Diff line number Diff line Loading @@ -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>, Loading packages/SystemUI/src/com/android/systemui/util/kotlin/Utils.kt +39 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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) } } } Loading @@ -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() } Loading packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt +35 −0 Original line number Diff line number Diff line Loading @@ -1096,6 +1096,41 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { coroutineContext.cancelChildren() } @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 { Loading Loading
packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt +6 −2 Original line number Diff line number Diff line Loading @@ -134,8 +134,9 @@ constructor( powerInteractor.isAwake, startedKeyguardTransitionStep, keyguardInteractor.isKeyguardOccluded, keyguardInteractor.isDreaming, keyguardInteractor.isActiveDreamLockscreenHosted, communalInteractor.isIdleOnCommunal communalInteractor.isIdleOnCommunal, ) .collect { ( Loading @@ -143,6 +144,7 @@ constructor( isAwake, lastStartedTransitionStep, occluded, isDreaming, isActiveDreamLockscreenHosted, isIdleOnCommunal) -> if ( Loading @@ -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 } Loading
packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt +23 −0 Original line number Diff line number Diff line Loading @@ -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>, Loading
packages/SystemUI/src/com/android/systemui/util/kotlin/Utils.kt +39 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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) } } } Loading @@ -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() } Loading
packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt +35 −0 Original line number Diff line number Diff line Loading @@ -1096,6 +1096,41 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { coroutineContext.cancelChildren() } @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 { Loading