From eb43fa68df7956a5ac364de5930bd15e4ddbdf31 Mon Sep 17 00:00:00 2001 From: Beverly Date: Fri, 21 Apr 2023 14:27:36 +0000 Subject: [PATCH] Support additional keyguard transitions * PrimaryBouncer => Occluded * Occluded => AlternateBouncer Test: atest KeyguardTransitionScenariosTest Test: manually check KeyguardLog (adb shell settings put global systemui/buffer/KeyguardLog v) for transitions Bug: 278719514 Change-Id: I2b7026c7bb9b054e44bf064899619ee49dbb8795 --- .../FromOccludedTransitionInteractor.kt | 23 ++++ .../FromPrimaryBouncerTransitionInteractor.kt | 63 ++++++++--- .../KeyguardTransitionScenariosTest.kt | 101 ++++++++++++++---- 3 files changed, 151 insertions(+), 36 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt index 1fbfff95ab7eb..c0d5abc04e5d5 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt @@ -48,6 +48,7 @@ constructor( listenForOccludedToDreaming() listenForOccludedToAodOrDozing() listenForOccludedToGone() + listenForOccludedToAlternateBouncer() } private fun listenForOccludedToDreaming() { @@ -167,6 +168,28 @@ constructor( } } + private fun listenForOccludedToAlternateBouncer() { + scope.launch { + keyguardInteractor.alternateBouncerShowing + .sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair) + .collect { (isAlternateBouncerShowing, lastStartedTransitionStep) -> + if ( + isAlternateBouncerShowing && + lastStartedTransitionStep.to == KeyguardState.OCCLUDED + ) { + keyguardTransitionRepository.startTransition( + TransitionInfo( + ownerName = name, + from = KeyguardState.OCCLUDED, + to = KeyguardState.ALTERNATE_BOUNCER, + animator = getAnimator(), + ) + ) + } + } + } + } + private fun getAnimator(duration: Duration = DEFAULT_DURATION): ValueAnimator { return ValueAnimator().apply { setInterpolator(Interpolators.LINEAR) 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 94961cbf4240d..a681c43be19f5 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 @@ -48,10 +48,51 @@ constructor( override fun start() { listenForPrimaryBouncerToGone() - listenForPrimaryBouncerToLockscreenAodOrDozing() + listenForPrimaryBouncerToAodOrDozing() + listenForPrimaryBouncerToLockscreenOrOccluded() } - private fun listenForPrimaryBouncerToLockscreenAodOrDozing() { + private fun listenForPrimaryBouncerToLockscreenOrOccluded() { + scope.launch { + keyguardInteractor.primaryBouncerShowing + .sample( + combine( + keyguardInteractor.wakefulnessModel, + keyguardTransitionInteractor.startedKeyguardTransitionStep, + keyguardInteractor.isKeyguardOccluded, + ::toTriple + ), + ::toQuad + ) + .collect { (isBouncerShowing, wakefulnessState, lastStartedTransitionStep, occluded) + -> + if ( + !isBouncerShowing && + lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER && + (wakefulnessState.state == WakefulnessState.AWAKE || + wakefulnessState.state == WakefulnessState.STARTING_TO_WAKE) + ) { + val to = + if (occluded) { + KeyguardState.OCCLUDED + } else { + KeyguardState.LOCKSCREEN + } + + keyguardTransitionRepository.startTransition( + TransitionInfo( + ownerName = name, + from = KeyguardState.PRIMARY_BOUNCER, + to = to, + animator = getAnimator(), + ) + ) + } + } + } + } + + private fun listenForPrimaryBouncerToAodOrDozing() { scope.launch { keyguardInteractor.primaryBouncerShowing .sample( @@ -68,21 +109,17 @@ constructor( -> if ( !isBouncerShowing && - lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER + lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER && + (wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP || + wakefulnessState.state == WakefulnessState.ASLEEP) ) { val to = - if ( - wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP || - wakefulnessState.state == WakefulnessState.ASLEEP - ) { - if (isAodAvailable) { - KeyguardState.AOD - } else { - KeyguardState.DOZING - } + if (isAodAvailable) { + KeyguardState.AOD } else { - KeyguardState.LOCKSCREEN + KeyguardState.DOZING } + keyguardTransitionRepository.startTransition( TransitionInfo( ownerName = name, 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 fe65236c699fa..344df0acc409c 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 @@ -180,7 +180,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun DREAMINGtoLOCKSCREEN() = + fun dreamingToLockscreen() = testScope.runTest { // GIVEN a device is dreaming keyguardRepository.setDreamingWithOverlay(true) @@ -215,7 +215,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun LOCKSCREENtoPRIMARY_BOUNCERviaBouncerShowingCall() = + fun lockscreenToPrimaryBouncerViaBouncerShowingCall() = testScope.runTest { // GIVEN a device that has at least woken up keyguardRepository.setWakefulnessModel(startingToWake()) @@ -242,7 +242,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun OCCLUDEDtoDOZING() = + fun occludedToDozing() = testScope.runTest { // GIVEN a device with AOD not available keyguardRepository.setAodAvailable(false) @@ -269,7 +269,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun OCCLUDEDtoAOD() = + fun occludedToAod() = testScope.runTest { // GIVEN a device with AOD available keyguardRepository.setAodAvailable(true) @@ -296,7 +296,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun LOCKSCREENtoDREAMING() = + fun lockscreenToDreaming() = testScope.runTest { // GIVEN a device that is not dreaming or dozing keyguardRepository.setDreamingWithOverlay(false) @@ -327,7 +327,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun LOCKSCREENtoDOZING() = + fun lockscreenToDozing() = testScope.runTest { // GIVEN a device with AOD not available keyguardRepository.setAodAvailable(false) @@ -354,7 +354,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun LOCKSCREENtoAOD() = + fun lockscreenToAod() = testScope.runTest { // GIVEN a device with AOD available keyguardRepository.setAodAvailable(true) @@ -381,7 +381,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun DOZINGtoLOCKSCREEN() = + fun dozingToLockscreen() = testScope.runTest { // GIVEN a prior transition has run to DOZING runTransition(KeyguardState.LOCKSCREEN, KeyguardState.DOZING) @@ -404,7 +404,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun DOZINGtoLOCKSCREENcannotBeInterrupedByDREAMING() = + fun dozingToLockscreenCannotBeInterruptedByDreaming() = testScope.runTest { // GIVEN a prior transition has started to LOCKSCREEN transitionRepository.sendTransitionStep( @@ -430,7 +430,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun DOZINGtoGONE() = + fun dozingToGone() = testScope.runTest { // GIVEN a prior transition has run to DOZING runTransition(KeyguardState.LOCKSCREEN, KeyguardState.DOZING) @@ -453,7 +453,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun GONEtoDOZING() = + fun goneToDozing() = testScope.runTest { // GIVEN a device with AOD not available keyguardRepository.setAodAvailable(false) @@ -480,7 +480,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun GONEtoAOD() = + fun goneToAod() = testScope.runTest { // GIVEN a device with AOD available keyguardRepository.setAodAvailable(true) @@ -507,7 +507,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun GONEtoLOCKSREEN() = + fun goneToLockscreen() = testScope.runTest { // GIVEN a prior transition has run to GONE runTransition(KeyguardState.LOCKSCREEN, KeyguardState.GONE) @@ -530,7 +530,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun GONEtoDREAMING() = + fun goneToDreaming() = testScope.runTest { // GIVEN a device that is not dreaming or dozing keyguardRepository.setDreamingWithOverlay(false) @@ -561,7 +561,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun ALTERNATE_BOUNCERtoPRIMARY_BOUNCER() = + fun alternateBouncerToPrimaryBouncer() = testScope.runTest { // GIVEN a prior transition has run to ALTERNATE_BOUNCER runTransition(KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER) @@ -584,7 +584,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun ALTERNATE_BOUNCERtoAOD() = + fun alternateBoucnerToAod() = testScope.runTest { // GIVEN a prior transition has run to ALTERNATE_BOUNCER bouncerRepository.setAlternateVisible(true) @@ -613,7 +613,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun ALTERNATE_BOUNCERtoDOZING() = + fun alternateBouncerToDozing() = testScope.runTest { // GIVEN a prior transition has run to ALTERNATE_BOUNCER bouncerRepository.setAlternateVisible(true) @@ -643,7 +643,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun ALTERNATE_BOUNCERtoLOCKSCREEN() = + fun alternateBouncerToLockscreen() = testScope.runTest { // GIVEN a prior transition has run to ALTERNATE_BOUNCER bouncerRepository.setAlternateVisible(true) @@ -671,7 +671,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun PRIMARY_BOUNCERtoAOD() = + fun primaryBouncerToAod() = testScope.runTest { // GIVEN a prior transition has run to PRIMARY_BOUNCER bouncerRepository.setPrimaryShow(true) @@ -699,7 +699,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun PRIMARY_BOUNCERtoDOZING() = + fun primaryBouncerToDozing() = testScope.runTest { // GIVEN a prior transition has run to PRIMARY_BOUNCER bouncerRepository.setPrimaryShow(true) @@ -727,7 +727,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun PRIMARY_BOUNCERtoLOCKSCREEN() = + fun primaryBouncerToLockscreen() = testScope.runTest { // GIVEN a prior transition has run to PRIMARY_BOUNCER bouncerRepository.setPrimaryShow(true) @@ -754,7 +754,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun OCCLUDEDtoGONE() = + fun occludedToGone() = testScope.runTest { // GIVEN a device on lockscreen keyguardRepository.setKeyguardShowing(true) @@ -785,7 +785,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun OCCLUDEDtoLOCKSCREEN() = + fun occludedToLockscreen() = testScope.runTest { // GIVEN a device on lockscreen keyguardRepository.setKeyguardShowing(true) @@ -813,6 +813,61 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { coroutineContext.cancelChildren() } + @Test + fun occludedToAlternateBouncer() = + testScope.runTest { + + // GIVEN a prior transition has run to OCCLUDED + runTransition(KeyguardState.LOCKSCREEN, KeyguardState.OCCLUDED) + keyguardRepository.setKeyguardOccluded(true) + runCurrent() + + // WHEN alternate bouncer shows + bouncerRepository.setAlternateVisible(true) + runCurrent() + + val info = + withArgCaptor { + verify(mockTransitionRepository).startTransition(capture(), anyBoolean()) + } + // THEN a transition to AlternateBouncer should occur + assertThat(info.ownerName).isEqualTo("FromOccludedTransitionInteractor") + assertThat(info.from).isEqualTo(KeyguardState.OCCLUDED) + assertThat(info.to).isEqualTo(KeyguardState.ALTERNATE_BOUNCER) + assertThat(info.animator).isNotNull() + + coroutineContext.cancelChildren() + } + + @Test + fun primaryBouncerToOccluded() = + testScope.runTest { + // GIVEN device not sleeping + keyguardRepository.setWakefulnessModel(startingToWake()) + + // GIVEN a prior transition has run to PRIMARY_BOUNCER + runTransition(KeyguardState.LOCKSCREEN, KeyguardState.PRIMARY_BOUNCER) + bouncerRepository.setPrimaryShow(true) + runCurrent() + + // WHEN the keyguard is occluded and primary bouncer stops showing + keyguardRepository.setKeyguardOccluded(true) + bouncerRepository.setPrimaryShow(false) + runCurrent() + + val info = + withArgCaptor { + verify(mockTransitionRepository).startTransition(capture(), anyBoolean()) + } + // THEN a transition to AlternateBouncer should occur + assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor") + assertThat(info.from).isEqualTo(KeyguardState.PRIMARY_BOUNCER) + assertThat(info.to).isEqualTo(KeyguardState.OCCLUDED) + assertThat(info.animator).isNotNull() + + coroutineContext.cancelChildren() + } + private fun startingToWake() = WakefulnessModel( WakefulnessState.STARTING_TO_WAKE,