Loading packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt +4 −21 Original line number Diff line number Diff line Loading @@ -29,9 +29,7 @@ import com.android.systemui.util.kotlin.sample import javax.inject.Inject import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @SysUISingleton Loading Loading @@ -64,29 +62,14 @@ constructor( private fun listenForDreamingToOccluded() { scope.launch { keyguardInteractor.isDreaming // Add a slight delay, as dreaming and occluded events will arrive with a small gap // in time. This prevents a transition to OCCLUSION happening prematurely. .onEach { delay(50) } .sample( combine( keyguardInteractor.isKeyguardOccluded, transitionInteractor.startedKeyguardTransitionStep, ::Pair, ), ::toTriple ) .collect { (isDreaming, isOccluded, lastStartedTransition) -> combine(keyguardInteractor.isKeyguardOccluded, keyguardInteractor.isDreaming, ::Pair) .sample(transitionInteractor.startedKeyguardTransitionStep, ::toTriple) .collect { (isOccluded, isDreaming, lastStartedTransition) -> if ( isOccluded && !isDreaming && (lastStartedTransition.to == KeyguardState.DREAMING || lastStartedTransition.to == KeyguardState.LOCKSCREEN) lastStartedTransition.to == KeyguardState.DREAMING ) { // At the moment, checking for LOCKSCREEN state above provides a corrective // action. There's no great signal to determine when the dream is ending // and a transition to OCCLUDED is beginning directly. For now, the solution // is DREAMING->LOCKSCREEN->OCCLUDED startTransitionTo(KeyguardState.OCCLUDED) } } Loading packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt +3 −10 Original line number Diff line number Diff line Loading @@ -318,16 +318,9 @@ constructor( private fun listenForLockscreenToOccluded() { scope.launch { keyguardInteractor.isKeyguardOccluded .sample( combine( transitionInteractor.startedKeyguardState, keyguardInteractor.isDreaming, ::Pair ), ::toTriple ) .collect { (isOccluded, keyguardState, isDreaming) -> if (isOccluded && !isDreaming && keyguardState == KeyguardState.LOCKSCREEN) { .sample(transitionInteractor.startedKeyguardState, ::Pair) .collect { (isOccluded, keyguardState) -> if (isOccluded && keyguardState == KeyguardState.LOCKSCREEN) { startTransitionTo(KeyguardState.OCCLUDED) } } Loading packages/SystemUI/src/com/android/systemui/util/kotlin/Utils.kt +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui.util.kotlin class Utils { companion object { fun <A, B, C> toTriple(a: A, bc: Pair<B, C>) = Triple(a, bc.first, bc.second) fun <A, B, C> toTriple(ab: Pair<A, B>, c: C) = Triple(ab.first, ab.second, c) fun <A, B, C, D> toQuad(a: A, b: B, c: C, d: D) = Quad(a, b, c, d) fun <A, B, C, D> toQuad(a: A, bcd: Triple<B, C, D>) = Loading packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt +83 −12 Original line number Diff line number Diff line Loading @@ -433,7 +433,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { // GIVEN a prior transition has run to DREAMING_LOCKSCREEN_HOSTED runTransitionAndSetWakefulness( KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED) KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED ) // WHEN the lockscreen hosted dream stops keyguardRepository.setIsActiveDreamLockscreenHosted(false) Loading @@ -457,7 +459,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { testScope.runTest { // GIVEN a prior transition has run to DREAMING_LOCKSCREEN_HOSTED runTransitionAndSetWakefulness( KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED) KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED ) // WHEN biometrics succeeds with wake and unlock from dream mode keyguardRepository.setBiometricUnlockState( Loading Loading @@ -487,7 +491,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { // GIVEN a prior transition has run to DREAMING_LOCKSCREEN_HOSTED runTransitionAndSetWakefulness( KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED) KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED ) // WHEN the primary bouncer is set to show bouncerRepository.setPrimaryShow(true) Loading Loading @@ -515,7 +521,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { // GIVEN a prior transition has run to DREAMING_LOCKSCREEN_HOSTED runTransitionAndSetWakefulness( KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED) KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED ) // WHEN the device begins to sleep keyguardRepository.setIsActiveDreamLockscreenHosted(false) Loading Loading @@ -547,7 +555,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { // GIVEN a prior transition has run to DREAMING_LOCKSCREEN_HOSTED runTransitionAndSetWakefulness( KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED) KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED ) // WHEN the keyguard is occluded and the lockscreen hosted dream stops keyguardRepository.setIsActiveDreamLockscreenHosted(false) Loading Loading @@ -783,7 +793,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { testScope.runTest { // GIVEN a prior transition has run to ALTERNATE_BOUNCER runTransitionAndSetWakefulness( KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER) KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER ) // WHEN the alternateBouncer stops showing and then the primary bouncer shows bouncerRepository.setPrimaryShow(true) Loading @@ -808,7 +820,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { // GIVEN a prior transition has run to ALTERNATE_BOUNCER bouncerRepository.setAlternateVisible(true) runTransitionAndSetWakefulness( KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER) KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER ) // GIVEN the primary bouncer isn't showing, aod available and starting to sleep bouncerRepository.setPrimaryShow(false) Loading Loading @@ -838,7 +852,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { // GIVEN a prior transition has run to ALTERNATE_BOUNCER bouncerRepository.setAlternateVisible(true) runTransitionAndSetWakefulness( KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER) KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER ) // GIVEN the primary bouncer isn't showing, aod not available and starting to sleep // to sleep Loading Loading @@ -869,7 +885,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { // GIVEN a prior transition has run to ALTERNATE_BOUNCER bouncerRepository.setAlternateVisible(true) runTransitionAndSetWakefulness( KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER) KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER ) // GIVEN the primary bouncer isn't showing and device not sleeping bouncerRepository.setPrimaryShow(false) Loading Loading @@ -980,7 +998,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { // GIVEN a prior transition has run to PRIMARY_BOUNCER bouncerRepository.setPrimaryShow(true) runTransitionAndSetWakefulness( KeyguardState.DREAMING_LOCKSCREEN_HOSTED, KeyguardState.PRIMARY_BOUNCER) KeyguardState.DREAMING_LOCKSCREEN_HOSTED, KeyguardState.PRIMARY_BOUNCER ) // WHEN the primary bouncer stops showing and lockscreen hosted dream still active bouncerRepository.setPrimaryShow(false) Loading Loading @@ -1160,6 +1180,57 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { coroutineContext.cancelChildren() } @Test fun dreamingToOccluded() = testScope.runTest { // GIVEN a prior transition has run to DREAMING keyguardRepository.setDreaming(true) runTransitionAndSetWakefulness(KeyguardState.LOCKSCREEN, KeyguardState.DREAMING) runCurrent() // WHEN the keyguard is occluded and device wakes up and is no longer dreaming keyguardRepository.setDreaming(false) keyguardRepository.setKeyguardOccluded(true) powerInteractor.setAwakeForTest() runCurrent() val info = withArgCaptor<TransitionInfo> { verify(transitionRepository).startTransition(capture(), anyBoolean()) } // THEN a transition to OCCLUDED should occur assertThat(info.ownerName).isEqualTo("FromDreamingTransitionInteractor") assertThat(info.from).isEqualTo(KeyguardState.DREAMING) assertThat(info.to).isEqualTo(KeyguardState.OCCLUDED) assertThat(info.animator).isNotNull() coroutineContext.cancelChildren() } @Test fun lockscreenToOccluded() = testScope.runTest { // GIVEN a prior transition has run to LOCKSCREEN runTransitionAndSetWakefulness(KeyguardState.GONE, KeyguardState.LOCKSCREEN) runCurrent() // WHEN the keyguard is occluded keyguardRepository.setKeyguardOccluded(true) runCurrent() val info = withArgCaptor<TransitionInfo> { verify(transitionRepository).startTransition(capture(), anyBoolean()) } // THEN a transition to OCCLUDED should occur assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor") assertThat(info.from).isEqualTo(KeyguardState.LOCKSCREEN) assertThat(info.to).isEqualTo(KeyguardState.OCCLUDED) assertThat(info.animator).isNotNull() coroutineContext.cancelChildren() } @Test fun aodToOccluded() = testScope.runTest { Loading Loading
packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt +4 −21 Original line number Diff line number Diff line Loading @@ -29,9 +29,7 @@ import com.android.systemui.util.kotlin.sample import javax.inject.Inject import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @SysUISingleton Loading Loading @@ -64,29 +62,14 @@ constructor( private fun listenForDreamingToOccluded() { scope.launch { keyguardInteractor.isDreaming // Add a slight delay, as dreaming and occluded events will arrive with a small gap // in time. This prevents a transition to OCCLUSION happening prematurely. .onEach { delay(50) } .sample( combine( keyguardInteractor.isKeyguardOccluded, transitionInteractor.startedKeyguardTransitionStep, ::Pair, ), ::toTriple ) .collect { (isDreaming, isOccluded, lastStartedTransition) -> combine(keyguardInteractor.isKeyguardOccluded, keyguardInteractor.isDreaming, ::Pair) .sample(transitionInteractor.startedKeyguardTransitionStep, ::toTriple) .collect { (isOccluded, isDreaming, lastStartedTransition) -> if ( isOccluded && !isDreaming && (lastStartedTransition.to == KeyguardState.DREAMING || lastStartedTransition.to == KeyguardState.LOCKSCREEN) lastStartedTransition.to == KeyguardState.DREAMING ) { // At the moment, checking for LOCKSCREEN state above provides a corrective // action. There's no great signal to determine when the dream is ending // and a transition to OCCLUDED is beginning directly. For now, the solution // is DREAMING->LOCKSCREEN->OCCLUDED startTransitionTo(KeyguardState.OCCLUDED) } } Loading
packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt +3 −10 Original line number Diff line number Diff line Loading @@ -318,16 +318,9 @@ constructor( private fun listenForLockscreenToOccluded() { scope.launch { keyguardInteractor.isKeyguardOccluded .sample( combine( transitionInteractor.startedKeyguardState, keyguardInteractor.isDreaming, ::Pair ), ::toTriple ) .collect { (isOccluded, keyguardState, isDreaming) -> if (isOccluded && !isDreaming && keyguardState == KeyguardState.LOCKSCREEN) { .sample(transitionInteractor.startedKeyguardState, ::Pair) .collect { (isOccluded, keyguardState) -> if (isOccluded && keyguardState == KeyguardState.LOCKSCREEN) { startTransitionTo(KeyguardState.OCCLUDED) } } Loading
packages/SystemUI/src/com/android/systemui/util/kotlin/Utils.kt +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui.util.kotlin class Utils { companion object { fun <A, B, C> toTriple(a: A, bc: Pair<B, C>) = Triple(a, bc.first, bc.second) fun <A, B, C> toTriple(ab: Pair<A, B>, c: C) = Triple(ab.first, ab.second, c) fun <A, B, C, D> toQuad(a: A, b: B, c: C, d: D) = Quad(a, b, c, d) fun <A, B, C, D> toQuad(a: A, bcd: Triple<B, C, D>) = Loading
packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt +83 −12 Original line number Diff line number Diff line Loading @@ -433,7 +433,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { // GIVEN a prior transition has run to DREAMING_LOCKSCREEN_HOSTED runTransitionAndSetWakefulness( KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED) KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED ) // WHEN the lockscreen hosted dream stops keyguardRepository.setIsActiveDreamLockscreenHosted(false) Loading @@ -457,7 +459,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { testScope.runTest { // GIVEN a prior transition has run to DREAMING_LOCKSCREEN_HOSTED runTransitionAndSetWakefulness( KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED) KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED ) // WHEN biometrics succeeds with wake and unlock from dream mode keyguardRepository.setBiometricUnlockState( Loading Loading @@ -487,7 +491,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { // GIVEN a prior transition has run to DREAMING_LOCKSCREEN_HOSTED runTransitionAndSetWakefulness( KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED) KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED ) // WHEN the primary bouncer is set to show bouncerRepository.setPrimaryShow(true) Loading Loading @@ -515,7 +521,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { // GIVEN a prior transition has run to DREAMING_LOCKSCREEN_HOSTED runTransitionAndSetWakefulness( KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED) KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED ) // WHEN the device begins to sleep keyguardRepository.setIsActiveDreamLockscreenHosted(false) Loading Loading @@ -547,7 +555,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { // GIVEN a prior transition has run to DREAMING_LOCKSCREEN_HOSTED runTransitionAndSetWakefulness( KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED) KeyguardState.GONE, KeyguardState.DREAMING_LOCKSCREEN_HOSTED ) // WHEN the keyguard is occluded and the lockscreen hosted dream stops keyguardRepository.setIsActiveDreamLockscreenHosted(false) Loading Loading @@ -783,7 +793,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { testScope.runTest { // GIVEN a prior transition has run to ALTERNATE_BOUNCER runTransitionAndSetWakefulness( KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER) KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER ) // WHEN the alternateBouncer stops showing and then the primary bouncer shows bouncerRepository.setPrimaryShow(true) Loading @@ -808,7 +820,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { // GIVEN a prior transition has run to ALTERNATE_BOUNCER bouncerRepository.setAlternateVisible(true) runTransitionAndSetWakefulness( KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER) KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER ) // GIVEN the primary bouncer isn't showing, aod available and starting to sleep bouncerRepository.setPrimaryShow(false) Loading Loading @@ -838,7 +852,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { // GIVEN a prior transition has run to ALTERNATE_BOUNCER bouncerRepository.setAlternateVisible(true) runTransitionAndSetWakefulness( KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER) KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER ) // GIVEN the primary bouncer isn't showing, aod not available and starting to sleep // to sleep Loading Loading @@ -869,7 +885,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { // GIVEN a prior transition has run to ALTERNATE_BOUNCER bouncerRepository.setAlternateVisible(true) runTransitionAndSetWakefulness( KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER) KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER ) // GIVEN the primary bouncer isn't showing and device not sleeping bouncerRepository.setPrimaryShow(false) Loading Loading @@ -980,7 +998,9 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { // GIVEN a prior transition has run to PRIMARY_BOUNCER bouncerRepository.setPrimaryShow(true) runTransitionAndSetWakefulness( KeyguardState.DREAMING_LOCKSCREEN_HOSTED, KeyguardState.PRIMARY_BOUNCER) KeyguardState.DREAMING_LOCKSCREEN_HOSTED, KeyguardState.PRIMARY_BOUNCER ) // WHEN the primary bouncer stops showing and lockscreen hosted dream still active bouncerRepository.setPrimaryShow(false) Loading Loading @@ -1160,6 +1180,57 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { coroutineContext.cancelChildren() } @Test fun dreamingToOccluded() = testScope.runTest { // GIVEN a prior transition has run to DREAMING keyguardRepository.setDreaming(true) runTransitionAndSetWakefulness(KeyguardState.LOCKSCREEN, KeyguardState.DREAMING) runCurrent() // WHEN the keyguard is occluded and device wakes up and is no longer dreaming keyguardRepository.setDreaming(false) keyguardRepository.setKeyguardOccluded(true) powerInteractor.setAwakeForTest() runCurrent() val info = withArgCaptor<TransitionInfo> { verify(transitionRepository).startTransition(capture(), anyBoolean()) } // THEN a transition to OCCLUDED should occur assertThat(info.ownerName).isEqualTo("FromDreamingTransitionInteractor") assertThat(info.from).isEqualTo(KeyguardState.DREAMING) assertThat(info.to).isEqualTo(KeyguardState.OCCLUDED) assertThat(info.animator).isNotNull() coroutineContext.cancelChildren() } @Test fun lockscreenToOccluded() = testScope.runTest { // GIVEN a prior transition has run to LOCKSCREEN runTransitionAndSetWakefulness(KeyguardState.GONE, KeyguardState.LOCKSCREEN) runCurrent() // WHEN the keyguard is occluded keyguardRepository.setKeyguardOccluded(true) runCurrent() val info = withArgCaptor<TransitionInfo> { verify(transitionRepository).startTransition(capture(), anyBoolean()) } // THEN a transition to OCCLUDED should occur assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor") assertThat(info.from).isEqualTo(KeyguardState.LOCKSCREEN) assertThat(info.to).isEqualTo(KeyguardState.OCCLUDED) assertThat(info.animator).isNotNull() coroutineContext.cancelChildren() } @Test fun aodToOccluded() = testScope.runTest { Loading