diff options
15 files changed, 348 insertions, 199 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt index 6a0d5954fc44..c4dfe9afeb2a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt @@ -383,7 +383,12 @@ constructor( "isFaceAuthEnrolledAndEnabled" ), Pair(keyguardRepository.isKeyguardGoingAway.isFalse(), "keyguardNotGoingAway"), - Pair(powerInteractor.isAsleep.isFalse(), "deviceNotAsleep"), + Pair( + keyguardTransitionInteractor + .isInTransitionToStateWhere(KeyguardState::deviceIsAsleepInState) + .isFalse(), + "deviceNotTransitioningToAsleepState" + ), Pair( keyguardInteractor.isSecureCameraActive .isFalse() diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt index 3eef6aa37122..8d5d73f88ca1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt @@ -115,7 +115,8 @@ class KeyguardTransitionRepositoryImpl @Inject constructor() : KeyguardTransitio private var updateTransitionId: UUID? = null init { - // Seed with transitions signaling a boot into lockscreen state + // Seed with transitions signaling a boot into lockscreen state. If updating this, please + // also update FakeKeyguardTransitionRepository. emitTransition( TransitionStep( KeyguardState.OFF, diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt index 00951c30fbe5..f0ff77ebf1ea 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt @@ -12,7 +12,6 @@ import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepos import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory import com.android.systemui.keyguard.shared.model.KeyguardState -import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest import com.android.systemui.power.domain.interactor.PowerInteractorFactory @@ -45,7 +44,6 @@ class ResourceTrimmerTest : SysuiTestCase() { private val keyguardTransitionRepository = FakeKeyguardTransitionRepository() private lateinit var powerInteractor: PowerInteractor - @Mock private lateinit var globalWindowManager: GlobalWindowManager private lateinit var resourceTrimmer: ResourceTrimmer @@ -181,8 +179,10 @@ class ResourceTrimmerTest : SysuiTestCase() { @Test fun keyguardTransitionsToGone_trimsFontCache() = testScope.runTest { - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(KeyguardState.LOCKSCREEN, KeyguardState.GONE) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + testScope ) verify(globalWindowManager, times(1)) .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) @@ -194,8 +194,10 @@ class ResourceTrimmerTest : SysuiTestCase() { fun keyguardTransitionsToGone_flagDisabled_doesNotTrimFontCache() = testScope.runTest { featureFlags.set(Flags.TRIM_FONT_CACHES_AT_UNLOCK, false) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(KeyguardState.LOCKSCREEN, KeyguardState.GONE) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + testScope ) // Memory hidden should still be called. verify(globalWindowManager, times(1)) diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt index 9bb2434f84ac..8d9bc751fbc9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt @@ -32,7 +32,6 @@ import android.hardware.face.FaceManager import android.hardware.face.FaceSensorProperties import android.hardware.face.FaceSensorPropertiesInternal import android.os.CancellationSignal -import android.util.Log import android.view.Display import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest @@ -637,7 +636,19 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { @Test fun authenticateDoesNotRunWhenDeviceIsGoingToSleep() = - testScope.runTest { testGatingCheckForFaceAuth { powerInteractor.setAsleepForTest() } } + testScope.runTest { + testGatingCheckForFaceAuth { + powerInteractor.setAsleepForTest() + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.AOD, + ) + ) + runCurrent() + } + } @Test fun authenticateDoesNotRunWhenSecureCameraIsActive() = @@ -733,13 +744,10 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { allPreconditionsToRunFaceAuthAreTrue() - Log.i("TEST", "started waking") - keyguardTransitionRepository.sendTransitionStep( - TransitionStep( - from = KeyguardState.LOCKSCREEN, - to = KeyguardState.OFF, - transitionState = TransitionState.FINISHED, - ) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.OFF, + testScope ) runCurrent() keyguardTransitionRepository.sendTransitionStep( @@ -751,15 +759,11 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { ) runCurrent() - Log.i("TEST", "sending display off") displayRepository.emit(setOf(display(0, 0, Display.DEFAULT_DISPLAY, Display.STATE_OFF))) displayRepository.emitDisplayChangeEvent(Display.DEFAULT_DISPLAY) - Log.i("TEST", "sending step") - runCurrent() - Log.i("TEST", "About to assert if face auth can run.") assertThat(canFaceAuthRun()).isTrue() } @@ -768,12 +772,10 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { testScope.runTest { testGatingCheckForFaceAuth { powerInteractor.onFinishedWakingUp() - keyguardTransitionRepository.sendTransitionStep( - TransitionStep( - from = KeyguardState.OFF, - to = KeyguardState.LOCKSCREEN, - transitionState = TransitionState.FINISHED, - ) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.OFF, + to = KeyguardState.LOCKSCREEN, + testScope ) runCurrent() @@ -923,7 +925,19 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { @Test fun detectDoesNotRunWhenDeviceSleepingStartingToSleep() = - testScope.runTest { testGatingCheckForDetect { powerInteractor.setAsleepForTest() } } + testScope.runTest { + testGatingCheckForDetect { + powerInteractor.setAsleepForTest() + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.AOD, + ) + ) + runCurrent() + } + } @Test fun detectDoesNotRunWhenSecureCameraIsActive() = @@ -1016,14 +1030,11 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { @Test fun schedulesFaceManagerWatchdogWhenKeyguardIsGoneFromDozing() = testScope.runTest { - keyguardTransitionRepository.sendTransitionStep( - TransitionStep( - from = KeyguardState.DOZING, - to = KeyguardState.GONE, - transitionState = TransitionState.FINISHED - ) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.DOZING, + to = KeyguardState.GONE, + testScope ) - runCurrent() verify(faceManager).scheduleWatchdog() } @@ -1031,14 +1042,11 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { @Test fun schedulesFaceManagerWatchdogWhenKeyguardIsGoneFromAod() = testScope.runTest { - keyguardTransitionRepository.sendTransitionStep( - TransitionStep( - from = KeyguardState.AOD, - to = KeyguardState.GONE, - transitionState = TransitionState.FINISHED - ) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.AOD, + to = KeyguardState.GONE, + testScope ) - runCurrent() verify(faceManager).scheduleWatchdog() } @@ -1046,14 +1054,11 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { @Test fun schedulesFaceManagerWatchdogWhenKeyguardIsGoneFromLockscreen() = testScope.runTest { - keyguardTransitionRepository.sendTransitionStep( - TransitionStep( - from = KeyguardState.LOCKSCREEN, - to = KeyguardState.GONE, - transitionState = TransitionState.FINISHED - ) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + testScope ) - runCurrent() verify(faceManager).scheduleWatchdog() } @@ -1061,14 +1066,11 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { @Test fun schedulesFaceManagerWatchdogWhenKeyguardIsGoneFromBouncer() = testScope.runTest { - keyguardTransitionRepository.sendTransitionStep( - TransitionStep( - from = KeyguardState.PRIMARY_BOUNCER, - to = KeyguardState.GONE, - transitionState = TransitionState.FINISHED - ) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.PRIMARY_BOUNCER, + to = KeyguardState.GONE, + testScope ) - runCurrent() verify(faceManager).scheduleWatchdog() } @@ -1251,6 +1253,11 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { keyguardRepository.setKeyguardShowing(true) displayRepository.emit(setOf(display(0, 0, Display.DEFAULT_DISPLAY, Display.STATE_ON))) displayRepository.emitDisplayChangeEvent(Display.DEFAULT_DISPLAY) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.AOD, + to = KeyguardState.LOCKSCREEN, + testScope + ) runCurrent() } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt index e87adf5e424b..e75f5570248e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt @@ -26,8 +26,6 @@ import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepos import com.android.systemui.keyguard.shared.model.DismissAction import com.android.systemui.keyguard.shared.model.KeyguardDone import com.android.systemui.keyguard.shared.model.KeyguardState -import com.android.systemui.keyguard.shared.model.TransitionState -import com.android.systemui.keyguard.shared.model.TransitionStep import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.StandardTestDispatcher @@ -179,8 +177,10 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() { assertThat(executeDismissAction).isNull() // WHEN the keyguard is GONE - transitionRepository.sendTransitionStep( - TransitionStep(to = KeyguardState.GONE, transitionState = TransitionState.FINISHED) + transitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + testScope ) assertThat(executeDismissAction).isNotNull() } @@ -198,11 +198,10 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() { willAnimateOnLockscreen = true, ) ) - transitionRepository.sendTransitionStep( - TransitionStep( - to = KeyguardState.AOD, - transitionState = TransitionState.FINISHED, - ) + transitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.AOD, + testScope ) assertThat(resetDismissAction).isEqualTo(Unit) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt index 0c74a38fea04..98f0211587ea 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt @@ -21,7 +21,6 @@ import android.content.Intent import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.logging.UiEventLogger -import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.FakeFeatureFlags @@ -29,7 +28,7 @@ import com.android.systemui.flags.Flags import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.shared.model.KeyguardState -import com.android.systemui.keyguard.shared.model.TransitionStep +import com.android.systemui.res.R import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat @@ -265,17 +264,17 @@ class KeyguardLongPressInteractorTest : SysuiTestCase() { underTest.onLongPress() assertThat(isMenuVisible).isTrue() - keyguardTransitionRepository.sendTransitionStep( - TransitionStep( - to = KeyguardState.GONE, - ), + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + testScope ) assertThat(isMenuVisible).isFalse() - keyguardTransitionRepository.sendTransitionStep( - TransitionStep( - to = KeyguardState.LOCKSCREEN, - ), + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.GONE, + to = KeyguardState.LOCKSCREEN, + testScope ) assertThat(isMenuVisible).isFalse() } @@ -312,10 +311,10 @@ class KeyguardLongPressInteractorTest : SysuiTestCase() { keyguardState: KeyguardState = KeyguardState.LOCKSCREEN, isQuickSettingsVisible: Boolean = false, ) { - keyguardTransitionRepository.sendTransitionStep( - TransitionStep( - to = keyguardState, - ), + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.AOD, + to = keyguardState, + testScope = testScope ) keyguardRepository.setQuickSettingsVisible(isVisible = isQuickSettingsVisible) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt index 16f2fa22d5fb..6eed427e9297 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt @@ -231,12 +231,10 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { surfaceBehindIsAnimatingFlow.emit(true) runCurrent() - transitionRepository.sendTransitionStep( - TransitionStep( - transitionState = TransitionState.FINISHED, - from = KeyguardState.LOCKSCREEN, - to = KeyguardState.GONE, - ) + transitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + testScope ) runCurrent() diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowTest.kt index 3efe38295f3d..a04ea2e4fa9c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlowTest.kt @@ -72,7 +72,7 @@ class KeyguardTransitionAnimationFlowTest : SysuiTestCase() { onFinish = { 10f }, ) var animationValues = collectLastValue(flow) - repository.sendTransitionStep(step(1f, TransitionState.FINISHED)) + repository.sendTransitionStep(step(1f, TransitionState.FINISHED), validateStep = false) assertThat(animationValues()).isEqualTo(10f) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModelTest.kt index edcaa1d65f49..30e48669205f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModelTest.kt @@ -751,14 +751,10 @@ class UdfpsLockscreenViewModelTest : SysuiTestCase() { } private suspend fun givenTransitionToLockscreenFinished() { - transitionRepository.sendTransitionStep( - TransitionStep( - from = KeyguardState.AOD, - to = KeyguardState.LOCKSCREEN, - value = 1f, - transitionState = TransitionState.FINISHED, - ownerName = "givenTransitionToLockscreenFinished", - ) + transitionRepository.sendTransitionSteps( + from = KeyguardState.AOD, + to = KeyguardState.LOCKSCREEN, + testScope ) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt index a4c2a0850ce4..3bfdb84249ac 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt @@ -31,7 +31,6 @@ import com.android.internal.logging.InstanceId import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.keyguard.TestScopeProvider -import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager @@ -39,8 +38,6 @@ import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepos import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory import com.android.systemui.keyguard.shared.model.KeyguardState -import com.android.systemui.keyguard.shared.model.TransitionState -import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.media.controls.MediaTestUtils import com.android.systemui.media.controls.models.player.MediaData import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaData @@ -52,6 +49,7 @@ import com.android.systemui.media.controls.util.MediaUiEventLogger import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.FalsingManager import com.android.systemui.qs.PageIndicator +import com.android.systemui.res.R import com.android.systemui.statusbar.notification.collection.provider.OnReorderingAllowedListener import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider import com.android.systemui.statusbar.policy.ConfigurationController @@ -810,8 +808,10 @@ class MediaCarouselControllerTest : SysuiTestCase() { mediaCarouselController.mediaCarousel = mediaCarousel val job = mediaCarouselController.listenForAnyStateToGoneKeyguardTransition(this) - transitionRepository.sendTransitionStep( - TransitionStep(to = KeyguardState.GONE, transitionState = TransitionState.FINISHED) + transitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + this ) verify(mediaCarousel).visibility = View.VISIBLE diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt index 6c1f537e754f..2ee016b2c87c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt @@ -28,8 +28,6 @@ import com.android.systemui.dump.logcatLogBuffer import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.shared.model.KeyguardState -import com.android.systemui.keyguard.shared.model.TransitionState -import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.StatusBarState import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder @@ -51,8 +49,6 @@ import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.withArgCaptor import com.android.systemui.util.settings.FakeSettings import com.google.common.truth.Truth.assertThat -import java.util.function.Consumer -import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestCoroutineScheduler @@ -66,6 +62,8 @@ import org.mockito.Mockito.anyString import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.never import org.mockito.Mockito.verify +import java.util.function.Consumer +import kotlin.time.Duration.Companion.seconds import org.mockito.Mockito.`when` as whenever @SmallTest @@ -131,8 +129,10 @@ class KeyguardCoordinatorTest : SysuiTestCase() { collectionListener.onEntryAdded(fakeEntry) // WHEN: The device transitions to AOD - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(to = KeyguardState.AOD, transitionState = TransitionState.STARTED), + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.GONE, + to = KeyguardState.AOD, + this.testScheduler, ) testScheduler.runCurrent() @@ -147,8 +147,10 @@ class KeyguardCoordinatorTest : SysuiTestCase() { keyguardRepository.setKeyguardShowing(false) whenever(statusBarStateController.isExpanded).thenReturn(false) runKeyguardCoordinatorTest { - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + this.testScheduler, ) // WHEN: A notification is posted @@ -161,8 +163,10 @@ class KeyguardCoordinatorTest : SysuiTestCase() { // WHEN: The keyguard is now showing keyguardRepository.setKeyguardShowing(true) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.GONE, to = KeyguardState.AOD) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.GONE, + to = KeyguardState.AOD, + this.testScheduler, ) testScheduler.runCurrent() @@ -171,8 +175,10 @@ class KeyguardCoordinatorTest : SysuiTestCase() { // WHEN: The keyguard goes away keyguardRepository.setKeyguardShowing(false) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.AOD, to = KeyguardState.GONE) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.AOD, + to = KeyguardState.GONE, + this.testScheduler, ) testScheduler.runCurrent() @@ -337,8 +343,10 @@ class KeyguardCoordinatorTest : SysuiTestCase() { runKeyguardCoordinatorTest { val fakeEntry = NotificationEntryBuilder().build() collectionListener.onEntryAdded(fakeEntry) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.AOD, to = KeyguardState.LOCKSCREEN) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.AOD, + to = KeyguardState.LOCKSCREEN, + this.testScheduler, ) testScheduler.runCurrent() @@ -348,15 +356,19 @@ class KeyguardCoordinatorTest : SysuiTestCase() { // WHEN: Keyguard is no longer showing keyguardRepository.setKeyguardShowing(false) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + this.testScheduler, ) testScheduler.runCurrent() // WHEN: Keyguard is shown again keyguardRepository.setKeyguardShowing(true) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.GONE, to = KeyguardState.AOD) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.GONE, + to = KeyguardState.AOD, + this.testScheduler, ) testScheduler.runCurrent() @@ -370,16 +382,20 @@ class KeyguardCoordinatorTest : SysuiTestCase() { // GIVEN: Keyguard is showing, unseen notification is present keyguardRepository.setKeyguardShowing(true) runKeyguardCoordinatorTest { - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.GONE, + to = KeyguardState.LOCKSCREEN, + this.testScheduler, ) val fakeEntry = NotificationEntryBuilder().build() collectionListener.onEntryAdded(fakeEntry) // WHEN: Keyguard is no longer showing keyguardRepository.setKeyguardShowing(false) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + this.testScheduler, ) // WHEN: Keyguard is shown again @@ -397,8 +413,10 @@ class KeyguardCoordinatorTest : SysuiTestCase() { keyguardRepository.setKeyguardShowing(true) keyguardRepository.setIsDozing(false) runKeyguardCoordinatorTest { - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.GONE, + to = KeyguardState.LOCKSCREEN, + this.testScheduler, ) val firstEntry = NotificationEntryBuilder().setId(1).build() collectionListener.onEntryAdded(firstEntry) @@ -419,15 +437,19 @@ class KeyguardCoordinatorTest : SysuiTestCase() { // WHEN: the keyguard is no longer showing keyguardRepository.setKeyguardShowing(false) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + this.testScheduler, ) testScheduler.runCurrent() // WHEN: Keyguard is shown again keyguardRepository.setKeyguardShowing(true) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.GONE, + to = KeyguardState.LOCKSCREEN, + this.testScheduler, ) testScheduler.runCurrent() @@ -445,8 +467,10 @@ class KeyguardCoordinatorTest : SysuiTestCase() { keyguardRepository.setKeyguardShowing(true) keyguardRepository.setIsDozing(false) runKeyguardCoordinatorTest { - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.GONE, + to = KeyguardState.LOCKSCREEN, + this.testScheduler, ) testScheduler.runCurrent() @@ -473,15 +497,19 @@ class KeyguardCoordinatorTest : SysuiTestCase() { // WHEN: the keyguard is no longer showing keyguardRepository.setKeyguardShowing(false) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + this.testScheduler, ) testScheduler.runCurrent() // WHEN: Keyguard is shown again keyguardRepository.setKeyguardShowing(true) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.GONE, + to = KeyguardState.LOCKSCREEN, + this.testScheduler, ) testScheduler.runCurrent() @@ -496,8 +524,10 @@ class KeyguardCoordinatorTest : SysuiTestCase() { keyguardRepository.setKeyguardShowing(true) keyguardRepository.setIsDozing(false) runKeyguardCoordinatorTest { - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.GONE, + to = KeyguardState.LOCKSCREEN, + this.testScheduler, ) testScheduler.runCurrent() @@ -524,15 +554,19 @@ class KeyguardCoordinatorTest : SysuiTestCase() { // WHEN: the keyguard is no longer showing keyguardRepository.setKeyguardShowing(false) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + this.testScheduler, ) testScheduler.runCurrent() // WHEN: Keyguard is shown again keyguardRepository.setKeyguardShowing(true) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.GONE, + to = KeyguardState.LOCKSCREEN, + this.testScheduler, ) testScheduler.runCurrent() @@ -547,8 +581,10 @@ class KeyguardCoordinatorTest : SysuiTestCase() { keyguardRepository.setKeyguardShowing(true) keyguardRepository.setIsDozing(false) runKeyguardCoordinatorTest { - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.GONE, + to = KeyguardState.LOCKSCREEN, + this.testScheduler, ) testScheduler.runCurrent() @@ -571,15 +607,19 @@ class KeyguardCoordinatorTest : SysuiTestCase() { // WHEN: the keyguard is no longer showing keyguardRepository.setKeyguardShowing(false) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + this.testScheduler, ) testScheduler.runCurrent() // WHEN: Keyguard is shown again keyguardRepository.setKeyguardShowing(true) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep(from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.GONE, + to = KeyguardState.LOCKSCREEN, + this.testScheduler, ) testScheduler.runCurrent() diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt index 41c7071a616d..14d188c69525 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt @@ -370,11 +370,10 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() { scope.runTest { val isVisible by collectLastValue(underTest.isVisible) runCurrent() - keyguardTransitionRepository.sendTransitionStep( - TransitionStep( - to = KeyguardState.GONE, - transitionState = TransitionState.FINISHED, - ) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.OFF, + to = KeyguardState.GONE, + scope, ) whenever(screenOffAnimController.shouldShowAodIconsWhenShade()).thenReturn(false) runCurrent() diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt index 0a7dc4e05633..60421c981e6d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt @@ -191,13 +191,10 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { testScope.runTest { val isOnLockscreen by collectLastValue(underTest.isOnLockscreen) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep( - from = KeyguardState.LOCKSCREEN, - to = KeyguardState.GONE, - value = 1f, - transitionState = TransitionState.FINISHED - ) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + testScope, ) assertThat(isOnLockscreen).isFalse() @@ -212,19 +209,17 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { ) assertThat(isOnLockscreen).isTrue() - keyguardTransitionRepository.sendTransitionStep( - TransitionStep( - to = KeyguardState.LOCKSCREEN, - transitionState = TransitionState.FINISHED - ) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.GONE, + to = KeyguardState.LOCKSCREEN, + this, ) assertThat(isOnLockscreen).isTrue() - keyguardTransitionRepository.sendTransitionStep( - TransitionStep( - to = KeyguardState.PRIMARY_BOUNCER, - transitionState = TransitionState.FINISHED - ) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.PRIMARY_BOUNCER, + testScope, ) assertThat(isOnLockscreen).isTrue() } @@ -237,11 +232,10 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { // First on AOD shadeRepository.setLockscreenShadeExpansion(0f) shadeRepository.setQsExpansion(0f) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep( - to = KeyguardState.OCCLUDED, - transitionState = TransitionState.FINISHED - ) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.OCCLUDED, + testScope, ) assertThat(isOnLockscreenWithoutShade).isFalse() @@ -271,12 +265,13 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { testScope.runTest { val position by collectLastValue(underTest.position) - // Start on lockscreen - showLockscreen() - // When not in split shade overrideResource(R.bool.config_use_split_notification_shade, false) configurationRepository.onAnyConfigurationChange() + runCurrent() + + // Start on lockscreen + showLockscreen() keyguardInteractor.sharedNotificationContainerPosition.value = SharedNotificationContainerPosition(top = 1f, bottom = 2f) @@ -290,12 +285,13 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { testScope.runTest { val position by collectLastValue(underTest.position) - // Start on lockscreen - showLockscreen() - // When in split shade overrideResource(R.bool.config_use_split_notification_shade, true) configurationRepository.onAnyConfigurationChange() + runCurrent() + + // Start on lockscreen + showLockscreen() keyguardInteractor.sharedNotificationContainerPosition.value = SharedNotificationContainerPosition(top = 1f, bottom = 2f) @@ -372,27 +368,25 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { assertThat(maxNotifications).isEqualTo(-1) } - private suspend fun showLockscreen() { + private suspend fun TestScope.showLockscreen() { shadeRepository.setLockscreenShadeExpansion(0f) shadeRepository.setQsExpansion(0f) keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep( - to = KeyguardState.LOCKSCREEN, - transitionState = TransitionState.FINISHED - ) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.AOD, + to = KeyguardState.LOCKSCREEN, + this, ) } - private suspend fun showLockscreenWithShadeExpanded() { + private suspend fun TestScope.showLockscreenWithShadeExpanded() { shadeRepository.setLockscreenShadeExpansion(1f) shadeRepository.setQsExpansion(0f) keyguardRepository.setStatusBarState(StatusBarState.SHADE_LOCKED) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep( - to = KeyguardState.LOCKSCREEN, - transitionState = TransitionState.FINISHED - ) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.AOD, + to = KeyguardState.LOCKSCREEN, + this, ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt index 842d548c8358..688f739f61f8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt @@ -99,13 +99,10 @@ class CollapsedStatusBarViewModelImplTest : SysuiTestCase() { testScope.runTest { val job = underTest.isTransitioningFromLockscreenToOccluded.launchIn(this) - keyguardTransitionRepository.sendTransitionStep( - TransitionStep( - KeyguardState.LOCKSCREEN, - KeyguardState.OCCLUDED, - value = 0f, - TransitionState.FINISHED, - ) + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.OCCLUDED, + this.testScheduler, ) assertThat(underTest.isTransitioningFromLockscreenToOccluded.value).isFalse() @@ -312,7 +309,10 @@ class CollapsedStatusBarViewModelImplTest : SysuiTestCase() { KeyguardState.DREAMING, value = 1.0f, TransitionState.FINISHED, - ) + ), + // We're intentionally not sending STARTED to validate that FINISHED steps are + // ignored. + validateStep = false, ) assertThat(emissions).isEmpty() diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt index 71e2bc1339a6..b90ad8cd8745 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt @@ -19,6 +19,7 @@ package com.android.systemui.keyguard.data.repository import android.annotation.FloatRange import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionInfo import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep @@ -26,9 +27,13 @@ import dagger.Binds import dagger.Module import java.util.UUID import javax.inject.Inject +import junit.framework.Assert.fail import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.test.TestCoroutineScheduler +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runCurrent /** Fake implementation of [KeyguardTransitionRepository] */ @SysUISingleton @@ -38,7 +43,111 @@ class FakeKeyguardTransitionRepository @Inject constructor() : KeyguardTransitio MutableSharedFlow<TransitionStep>(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) override val transitions: SharedFlow<TransitionStep> = _transitions - suspend fun sendTransitionStep(step: TransitionStep) { + init { + _transitions.tryEmit( + TransitionStep( + transitionState = TransitionState.STARTED, + from = KeyguardState.OFF, + to = KeyguardState.LOCKSCREEN, + ) + ) + + _transitions.tryEmit( + TransitionStep( + transitionState = TransitionState.FINISHED, + from = KeyguardState.OFF, + to = KeyguardState.LOCKSCREEN, + ) + ) + } + + /** + * Sends STARTED, RUNNING, and FINISHED TransitionSteps between [from] and [to], calling + * [runCurrent] after each step. + */ + suspend fun sendTransitionSteps( + from: KeyguardState, + to: KeyguardState, + testScope: TestScope, + ) { + sendTransitionSteps(from, to, testScope.testScheduler) + } + + /** + * Sends STARTED, RUNNING, and FINISHED TransitionSteps between [from] and [to], calling + * [runCurrent] after each step. + */ + suspend fun sendTransitionSteps( + from: KeyguardState, + to: KeyguardState, + testScheduler: TestCoroutineScheduler, + ) { + sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + from = from, + to = to, + value = 0f, + ) + ) + testScheduler.runCurrent() + + sendTransitionStep( + TransitionStep( + transitionState = TransitionState.RUNNING, + from = from, + to = to, + value = 0.5f + ) + ) + testScheduler.runCurrent() + + sendTransitionStep( + TransitionStep( + transitionState = TransitionState.FINISHED, + from = from, + to = to, + value = 1f, + ) + ) + testScheduler.runCurrent() + } + + /** + * Directly emits the provided TransitionStep, which can be useful in tests for testing behavior + * during specific phases of a transition (such as asserting values while a transition has + * STARTED but not FINISHED). + * + * WARNING: You can get the transition repository into undefined states using this method - for + * example, you could send a FINISHED step to LOCKSCREEN having never sent a STARTED step. This + * can get flows that combine startedStep/finishedStep into a bad state. + * + * If you are just trying to get the transition repository FINISHED in a certain state, use + * [sendTransitionSteps] - this will send STARTED, RUNNING, and FINISHED steps for you which + * ensures that [KeyguardTransitionInteractor] flows will be in the correct state. + * + * If you're testing something involving transitions themselves and are sure you want to send + * only a FINISHED step, override [validateStep]. + */ + suspend fun sendTransitionStep(step: TransitionStep, validateStep: Boolean = true) { + _transitions.replayCache.getOrNull(0)?.let { lastStep -> + if ( + validateStep && + step.transitionState == TransitionState.FINISHED && + !(lastStep.transitionState == TransitionState.STARTED || + lastStep.transitionState == TransitionState.RUNNING) + ) { + fail( + "Attempted to send a FINISHED TransitionStep without a prior " + + "STARTED/RUNNING step. This leaves the FakeKeyguardTransitionRepository " + + "in an undefined state and should not be done. Pass " + + "allowInvalidStep=true to sendTransitionStep if you are trying to test " + + "this specific and" + + "incorrect state." + ) + } + } + _transitions.emit(step) } |