From 5b85373d3ed65c523da930960ad1dae7d3d7b4de Mon Sep 17 00:00:00 2001 From: Matt Pietal Date: Thu, 2 Feb 2023 12:50:41 +0000 Subject: [PATCH 1/2] Transitions - Legacy dream -> lockscreen flicker It briefly shows lockscreen content before hiding and fading in nicely. This is due to the possible ordering of occlusion/dreaming events so make sure to start the transition as soon as either changes. Fixes: 267600416 Test: atest KeyguardTransitionScenariosTest Change-Id: I337d0189af72e052b805a213d0faa8f6b528811d --- .../FromDreamingTransitionInteractor.kt | 12 +++-- .../KeyguardTransitionScenariosTest.kt | 52 ++++++++++++++++++- 2 files changed, 60 insertions(+), 4 deletions(-) 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 81a58286aab75..8715d1f550697 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 @@ -34,6 +34,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @@ -56,9 +57,14 @@ constructor( private fun listenForDreamingToLockscreen() { scope.launch { - // Using isDreamingWithOverlay provides an optimized path to LOCKSCREEN state, which - // otherwise would have gone through OCCLUDED first - keyguardInteractor.isAbleToDream + // Dependending on the dream, either dream state or occluded change will change first, + // so listen for both + combine(keyguardInteractor.isAbleToDream, keyguardInteractor.isKeyguardOccluded) { + isAbleToDream, + isKeyguardOccluded -> + isAbleToDream && isKeyguardOccluded + } + .distinctUntilChanged() .sample( combine( keyguardInteractor.dozeTransitionModel, 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 702f376350927..d29e7ed082ceb 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 @@ -149,7 +149,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { } @Test - fun `DREAMING to LOCKSCREEN`() = + fun `DREAMING to LOCKSCREEN - dreaming state changes first`() = testScope.runTest { // GIVEN a device is dreaming and occluded keyguardRepository.setDreamingWithOverlay(true) @@ -179,9 +179,59 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { ) // AND dreaming has stopped keyguardRepository.setDreamingWithOverlay(false) + advanceUntilIdle() + // AND then occluded has stopped + keyguardRepository.setKeyguardOccluded(false) + advanceUntilIdle() + + val info = + withArgCaptor { + verify(mockTransitionRepository).startTransition(capture()) + } + // THEN a transition to BOUNCER should occur + assertThat(info.ownerName).isEqualTo("FromDreamingTransitionInteractor") + assertThat(info.from).isEqualTo(KeyguardState.DREAMING) + assertThat(info.to).isEqualTo(KeyguardState.LOCKSCREEN) + assertThat(info.animator).isNotNull() + + coroutineContext.cancelChildren() + } + + @Test + fun `DREAMING to LOCKSCREEN - occluded state changes first`() = + testScope.runTest { + // GIVEN a device is dreaming and occluded + keyguardRepository.setDreamingWithOverlay(true) + keyguardRepository.setKeyguardOccluded(true) + runCurrent() + + // GIVEN a prior transition has run to DREAMING + runner.startTransition( + testScope, + TransitionInfo( + ownerName = "", + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.DREAMING, + animator = + ValueAnimator().apply { + duration = 10 + interpolator = Interpolators.LINEAR + }, + ) + ) + runCurrent() + reset(mockTransitionRepository) + + // WHEN doze is complete + keyguardRepository.setDozeTransitionModel( + DozeTransitionModel(from = DozeStateModel.DOZE, to = DozeStateModel.FINISH) + ) // AND occluded has stopped keyguardRepository.setKeyguardOccluded(false) advanceUntilIdle() + // AND then dreaming has stopped + keyguardRepository.setDreamingWithOverlay(false) + advanceUntilIdle() val info = withArgCaptor { From 05053527ad8e9d11d960c2eb9166ce4c30ee2d66 Mon Sep 17 00:00:00 2001 From: Matt Pietal Date: Mon, 6 Feb 2023 15:46:37 +0000 Subject: [PATCH 2/2] Allow UserSwitcherActivity in LockDownTask mode Devices can be locked down, such as supervised devices when the time limit has been passed. Most activities should be blocked, but the user switcher activity should always be allowed. Bug: 257493384 Test: manual Change-Id: Ifd7bc217e629a28190b81748f02af676d1adc40a --- packages/SystemUI/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index e96aead597b3c..fb4986b99c861 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -899,7 +899,7 @@ android:showWhenLocked="true" android:showForAllUsers="true" android:finishOnTaskLaunch="true" - android:launchMode="singleInstance" + android:lockTaskMode="if_whitelisted" android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden" android:visibleToInstantApps="true">