diff options
5 files changed, 227 insertions, 141 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt index 75192021dab6..e121790f07b0 100644 --- a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt @@ -27,6 +27,8 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.keyguard.data.repository.KeyguardRepository +import com.android.systemui.scene.domain.interactor.SceneInteractor +import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.user.data.repository.UserRepository import com.android.systemui.util.time.SystemClock import javax.inject.Inject @@ -42,6 +44,7 @@ import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch @@ -57,6 +60,7 @@ constructor( @Background private val backgroundDispatcher: CoroutineDispatcher, private val userRepository: UserRepository, private val keyguardRepository: KeyguardRepository, + sceneInteractor: SceneInteractor, private val clock: SystemClock, ) { /** @@ -93,7 +97,7 @@ constructor( repository.isUnlocked, authenticationMethod, ) { isUnlocked, authenticationMethod -> - authenticationMethod is DomainLayerAuthenticationMethodModel.None || isUnlocked + !authenticationMethod.isSecure || isUnlocked } .stateIn( scope = applicationScope, @@ -101,6 +105,44 @@ constructor( initialValue = true, ) + /** + * Whether the lockscreen has been dismissed (by any method). This can be false even when the + * device is unlocked, e.g. when swipe to unlock is enabled. + * + * Note: + * - `false` doesn't mean the lockscreen is visible (it may be occluded or covered by other UI). + * - `true` doesn't mean the lockscreen is invisible (since this state changes before the + * transition occurs). + */ + private val isLockscreenDismissed = + sceneInteractor.desiredScene + .map { it.key } + .filter { currentScene -> + currentScene == SceneKey.Gone || currentScene == SceneKey.Lockscreen + } + .map { it == SceneKey.Gone } + .distinctUntilChanged() + + /** + * Whether it's currently possible to swipe up to dismiss the lockscreen without requiring + * authentication. This returns false whenever the lockscreen has been dismissed. + * + * Note: `true` doesn't mean the lockscreen is visible. It may be occluded or covered by other + * UI. + */ + val canSwipeToDismiss = + combine(authenticationMethod, isLockscreenDismissed) { + authenticationMethod, + isLockscreenDismissed -> + authenticationMethod is DomainLayerAuthenticationMethodModel.Swipe && + !isLockscreenDismissed + } + .stateIn( + scope = applicationScope, + started = SharingStarted.WhileSubscribed(), + initialValue = false, + ) + /** The current authentication throttling state, only meaningful if [isThrottled] is `true`. */ val throttling: StateFlow<AuthenticationThrottlingModel> = repository.throttling diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt index f46d0eb449a0..11e85d0d85e1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt @@ -18,7 +18,6 @@ package com.android.systemui.keyguard.ui.viewmodel import com.android.systemui.R import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor -import com.android.systemui.authentication.domain.model.AuthenticationMethodModel import com.android.systemui.bouncer.domain.interactor.BouncerInteractor import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon @@ -27,7 +26,6 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.scene.shared.model.SceneKey import javax.inject.Inject import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map @@ -53,14 +51,15 @@ constructor( ) /** The key of the scene we should switch to when swiping up. */ - val upDestinationSceneKey: Flow<SceneKey> = - authenticationInteractor.authenticationMethod.map { authenticationMethod -> - if (authenticationMethod is AuthenticationMethodModel.Swipe) { - SceneKey.Gone - } else { - SceneKey.Bouncer - } - } + val upDestinationSceneKey = + authenticationInteractor.canSwipeToDismiss + .map { canSwipeToDismiss -> upDestinationSceneKey(canSwipeToDismiss) } + .stateIn( + scope = applicationScope, + started = SharingStarted.WhileSubscribed(), + initialValue = + upDestinationSceneKey(authenticationInteractor.canSwipeToDismiss.value), + ) /** Notifies that the lock button on the lock screen was clicked. */ fun onLockButtonClicked() { @@ -73,30 +72,24 @@ constructor( } private fun upDestinationSceneKey( - isSwipeToUnlockEnabled: Boolean, + canSwipeToDismiss: Boolean, ): SceneKey { - return if (isSwipeToUnlockEnabled) SceneKey.Gone else SceneKey.Bouncer + return if (canSwipeToDismiss) SceneKey.Gone else SceneKey.Bouncer } private fun lockIcon( isUnlocked: Boolean, ): Icon { - return Icon.Resource( - res = - if (isUnlocked) { - R.drawable.ic_device_lock_off - } else { - R.drawable.ic_device_lock_on - }, - contentDescription = - ContentDescription.Resource( - res = - if (isUnlocked) { - R.string.accessibility_unlock_button - } else { - R.string.accessibility_lock_icon - } - ) - ) + return if (isUnlocked) { + Icon.Resource( + R.drawable.ic_device_lock_off, + ContentDescription.Resource(R.string.accessibility_unlock_button) + ) + } else { + Icon.Resource( + R.drawable.ic_device_lock_on, + ContentDescription.Resource(R.string.accessibility_lock_icon) + ) + } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt index d848cd46e509..fc7d20aeb356 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt @@ -27,6 +27,8 @@ import com.android.systemui.authentication.shared.model.AuthenticationPatternCoo import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel import com.android.systemui.coroutines.collectLastValue import com.android.systemui.scene.SceneTestUtils +import com.android.systemui.scene.shared.model.SceneKey +import com.android.systemui.scene.shared.model.SceneModel import com.google.common.truth.Truth.assertThat import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.seconds @@ -46,9 +48,11 @@ class AuthenticationInteractorTest : SysuiTestCase() { private val utils = SceneTestUtils(this) private val testScope = utils.testScope private val repository: AuthenticationRepository = utils.authenticationRepository() + private val sceneInteractor = utils.sceneInteractor() private val underTest = utils.authenticationInteractor( repository = repository, + sceneInteractor = sceneInteractor, ) @Test @@ -75,10 +79,10 @@ class AuthenticationInteractorTest : SysuiTestCase() { val authMethod by collectLastValue(underTest.authenticationMethod) runCurrent() - utils.authenticationRepository.setAuthenticationMethod( - DataLayerAuthenticationMethodModel.None - ) - utils.authenticationRepository.setLockscreenEnabled(true) + utils.authenticationRepository.apply { + setAuthenticationMethod(DataLayerAuthenticationMethodModel.None) + setLockscreenEnabled(true) + } assertThat(authMethod).isEqualTo(DomainLayerAuthenticationMethodModel.Swipe) assertThat(underTest.getAuthenticationMethod()) @@ -91,10 +95,10 @@ class AuthenticationInteractorTest : SysuiTestCase() { val authMethod by collectLastValue(underTest.authenticationMethod) runCurrent() - utils.authenticationRepository.setAuthenticationMethod( - DataLayerAuthenticationMethodModel.None - ) - utils.authenticationRepository.setLockscreenEnabled(false) + utils.authenticationRepository.apply { + setAuthenticationMethod(DataLayerAuthenticationMethodModel.None) + setLockscreenEnabled(false) + } assertThat(authMethod).isEqualTo(DomainLayerAuthenticationMethodModel.None) assertThat(underTest.getAuthenticationMethod()) @@ -104,51 +108,87 @@ class AuthenticationInteractorTest : SysuiTestCase() { @Test fun isUnlocked_whenAuthMethodIsNoneAndLockscreenDisabled_isTrue() = testScope.runTest { - utils.authenticationRepository.setAuthenticationMethod( - DataLayerAuthenticationMethodModel.None - ) - utils.authenticationRepository.setLockscreenEnabled(false) - val isUnlocked by collectLastValue(underTest.isUnlocked) - // Toggle isUnlocked, twice. - // - // This is done because the underTest.isUnlocked flow doesn't receive values from - // just changing the state above; the actual isUnlocked state needs to change to - // cause the logic under test to "pick up" the current state again. - // - // It is done twice to make sure that we don't actually change the isUnlocked - // state from what it originally was. - utils.authenticationRepository.setUnlocked( - !utils.authenticationRepository.isUnlocked.value - ) - runCurrent() - utils.authenticationRepository.setUnlocked( - !utils.authenticationRepository.isUnlocked.value - ) - runCurrent() + utils.authenticationRepository.apply { + setAuthenticationMethod(DataLayerAuthenticationMethodModel.None) + setLockscreenEnabled(false) + // Toggle isUnlocked, twice. + // + // This is done because the underTest.isUnlocked flow doesn't receive values from + // just changing the state above; the actual isUnlocked state needs to change to + // cause the logic under test to "pick up" the current state again. + // + // It is done twice to make sure that we don't actually change the isUnlocked state + // from what it originally was. + setUnlocked(!utils.authenticationRepository.isUnlocked.value) + runCurrent() + setUnlocked(!utils.authenticationRepository.isUnlocked.value) + runCurrent() + } + assertThat(isUnlocked).isTrue() } @Test - fun isUnlocked_whenAuthMethodIsNoneAndLockscreenEnabled_isFalse() = + fun isUnlocked_whenAuthMethodIsNoneAndLockscreenEnabled_isTrue() = testScope.runTest { - utils.authenticationRepository.setAuthenticationMethod( - DataLayerAuthenticationMethodModel.None - ) - utils.authenticationRepository.setLockscreenEnabled(true) + utils.authenticationRepository.apply { + setAuthenticationMethod(DataLayerAuthenticationMethodModel.None) + setLockscreenEnabled(true) + } val isUnlocked by collectLastValue(underTest.isUnlocked) - assertThat(isUnlocked).isFalse() + assertThat(isUnlocked).isTrue() + } + + @Test + fun canSwipeToDismiss_onLockscreenWithSwipe_isTrue() = + testScope.runTest { + utils.authenticationRepository.apply { + setAuthenticationMethod(DataLayerAuthenticationMethodModel.None) + setLockscreenEnabled(true) + } + switchToScene(SceneKey.Lockscreen) + + val canSwipeToDismiss by collectLastValue(underTest.canSwipeToDismiss) + assertThat(canSwipeToDismiss).isTrue() + } + + @Test + fun canSwipeToDismiss_onLockscreenWithPin_isFalse() = + testScope.runTest { + utils.authenticationRepository.apply { + setAuthenticationMethod(DataLayerAuthenticationMethodModel.Pin) + setLockscreenEnabled(true) + } + switchToScene(SceneKey.Lockscreen) + + val canSwipeToDismiss by collectLastValue(underTest.canSwipeToDismiss) + assertThat(canSwipeToDismiss).isFalse() + } + + @Test + fun canSwipeToDismiss_afterLockscreenDismissedInSwipeMode_isFalse() = + testScope.runTest { + utils.authenticationRepository.apply { + setAuthenticationMethod(DataLayerAuthenticationMethodModel.None) + setLockscreenEnabled(true) + } + switchToScene(SceneKey.Lockscreen) + switchToScene(SceneKey.Gone) + + val canSwipeToDismiss by collectLastValue(underTest.canSwipeToDismiss) + assertThat(canSwipeToDismiss).isFalse() } @Test fun isAuthenticationRequired_lockedAndSecured_true() = testScope.runTest { - utils.authenticationRepository.setUnlocked(false) - runCurrent() - utils.authenticationRepository.setAuthenticationMethod( - DataLayerAuthenticationMethodModel.Password - ) + utils.authenticationRepository.apply { + setUnlocked(false) + runCurrent() + setAuthenticationMethod(DataLayerAuthenticationMethodModel.Password) + } assertThat(underTest.isAuthenticationRequired()).isTrue() } @@ -156,11 +196,11 @@ class AuthenticationInteractorTest : SysuiTestCase() { @Test fun isAuthenticationRequired_lockedAndNotSecured_false() = testScope.runTest { - utils.authenticationRepository.setUnlocked(false) - runCurrent() - utils.authenticationRepository.setAuthenticationMethod( - DataLayerAuthenticationMethodModel.None - ) + utils.authenticationRepository.apply { + setUnlocked(false) + runCurrent() + setAuthenticationMethod(DataLayerAuthenticationMethodModel.None) + } assertThat(underTest.isAuthenticationRequired()).isFalse() } @@ -168,11 +208,11 @@ class AuthenticationInteractorTest : SysuiTestCase() { @Test fun isAuthenticationRequired_unlockedAndSecured_false() = testScope.runTest { - utils.authenticationRepository.setUnlocked(true) - runCurrent() - utils.authenticationRepository.setAuthenticationMethod( - DataLayerAuthenticationMethodModel.Password - ) + utils.authenticationRepository.apply { + setUnlocked(true) + runCurrent() + setAuthenticationMethod(DataLayerAuthenticationMethodModel.Password) + } assertThat(underTest.isAuthenticationRequired()).isFalse() } @@ -180,11 +220,11 @@ class AuthenticationInteractorTest : SysuiTestCase() { @Test fun isAuthenticationRequired_unlockedAndNotSecured_false() = testScope.runTest { - utils.authenticationRepository.setUnlocked(true) - runCurrent() - utils.authenticationRepository.setAuthenticationMethod( - DataLayerAuthenticationMethodModel.None - ) + utils.authenticationRepository.apply { + setUnlocked(true) + runCurrent() + setAuthenticationMethod(DataLayerAuthenticationMethodModel.None) + } assertThat(underTest.isAuthenticationRequired()).isFalse() } @@ -221,11 +261,12 @@ class AuthenticationInteractorTest : SysuiTestCase() { @Test fun authenticate_withCorrectMaxLengthPin_returnsTrue() = testScope.runTest { - utils.authenticationRepository.setAuthenticationMethod( - DataLayerAuthenticationMethodModel.Pin - ) val pin = List(16) { 9 } - utils.authenticationRepository.overrideCredential(pin) + utils.authenticationRepository.apply { + setAuthenticationMethod(DataLayerAuthenticationMethodModel.Pin) + overrideCredential(pin) + } + assertThat(underTest.authenticate(pin)).isTrue() } @@ -308,10 +349,10 @@ class AuthenticationInteractorTest : SysuiTestCase() { fun tryAutoConfirm_withAutoConfirmPinAndShorterPin_returnsNullAndHasNoEffect() = testScope.runTest { val isThrottled by collectLastValue(underTest.isThrottled) - utils.authenticationRepository.setAuthenticationMethod( - DataLayerAuthenticationMethodModel.Pin - ) - utils.authenticationRepository.setAutoConfirmEnabled(true) + utils.authenticationRepository.apply { + setAuthenticationMethod(DataLayerAuthenticationMethodModel.Pin) + setAutoConfirmEnabled(true) + } assertThat( underTest.authenticate( FakeAuthenticationRepository.DEFAULT_PIN.toMutableList().apply { @@ -328,10 +369,10 @@ class AuthenticationInteractorTest : SysuiTestCase() { fun tryAutoConfirm_withAutoConfirmWrongPinCorrectLength_returnsFalseAndDoesNotUnlockDevice() = testScope.runTest { val isUnlocked by collectLastValue(underTest.isUnlocked) - utils.authenticationRepository.setAuthenticationMethod( - DataLayerAuthenticationMethodModel.Pin - ) - utils.authenticationRepository.setAutoConfirmEnabled(true) + utils.authenticationRepository.apply { + setAuthenticationMethod(DataLayerAuthenticationMethodModel.Pin) + setAutoConfirmEnabled(true) + } assertThat( underTest.authenticate( FakeAuthenticationRepository.DEFAULT_PIN.map { it + 1 }, @@ -346,10 +387,10 @@ class AuthenticationInteractorTest : SysuiTestCase() { fun tryAutoConfirm_withAutoConfirmLongerPin_returnsFalseAndDoesNotUnlockDevice() = testScope.runTest { val isUnlocked by collectLastValue(underTest.isUnlocked) - utils.authenticationRepository.setAuthenticationMethod( - DataLayerAuthenticationMethodModel.Pin - ) - utils.authenticationRepository.setAutoConfirmEnabled(true) + utils.authenticationRepository.apply { + setAuthenticationMethod(DataLayerAuthenticationMethodModel.Pin) + setAutoConfirmEnabled(true) + } assertThat( underTest.authenticate( FakeAuthenticationRepository.DEFAULT_PIN + listOf(7), @@ -364,10 +405,10 @@ class AuthenticationInteractorTest : SysuiTestCase() { fun tryAutoConfirm_withAutoConfirmCorrectPin_returnsTrueAndUnlocksDevice() = testScope.runTest { val isUnlocked by collectLastValue(underTest.isUnlocked) - utils.authenticationRepository.setAuthenticationMethod( - DataLayerAuthenticationMethodModel.Pin - ) - utils.authenticationRepository.setAutoConfirmEnabled(true) + utils.authenticationRepository.apply { + setAuthenticationMethod(DataLayerAuthenticationMethodModel.Pin) + setAutoConfirmEnabled(true) + } assertThat( underTest.authenticate( FakeAuthenticationRepository.DEFAULT_PIN, @@ -382,10 +423,10 @@ class AuthenticationInteractorTest : SysuiTestCase() { fun tryAutoConfirm_withoutAutoConfirmButCorrectPin_returnsNullAndHasNoEffects() = testScope.runTest { val isUnlocked by collectLastValue(underTest.isUnlocked) - utils.authenticationRepository.setAuthenticationMethod( - DataLayerAuthenticationMethodModel.Pin - ) - utils.authenticationRepository.setAutoConfirmEnabled(false) + utils.authenticationRepository.apply { + setAuthenticationMethod(DataLayerAuthenticationMethodModel.Pin) + setAutoConfirmEnabled(false) + } assertThat( underTest.authenticate( FakeAuthenticationRepository.DEFAULT_PIN, @@ -505,10 +546,10 @@ class AuthenticationInteractorTest : SysuiTestCase() { fun hintedPinLength_withoutAutoConfirm_isNull() = testScope.runTest { val hintedPinLength by collectLastValue(underTest.hintedPinLength) - utils.authenticationRepository.setAuthenticationMethod( - DataLayerAuthenticationMethodModel.Pin - ) - utils.authenticationRepository.setAutoConfirmEnabled(false) + utils.authenticationRepository.apply { + setAuthenticationMethod(DataLayerAuthenticationMethodModel.Pin) + setAutoConfirmEnabled(false) + } assertThat(hintedPinLength).isNull() } @@ -517,15 +558,15 @@ class AuthenticationInteractorTest : SysuiTestCase() { fun hintedPinLength_withAutoConfirmPinTooShort_isNull() = testScope.runTest { val hintedPinLength by collectLastValue(underTest.hintedPinLength) - utils.authenticationRepository.setAuthenticationMethod( - DataLayerAuthenticationMethodModel.Pin - ) - utils.authenticationRepository.overrideCredential( - buildList { - repeat(utils.authenticationRepository.hintedPinLength - 1) { add(it + 1) } - } - ) - utils.authenticationRepository.setAutoConfirmEnabled(true) + utils.authenticationRepository.apply { + setAuthenticationMethod(DataLayerAuthenticationMethodModel.Pin) + overrideCredential( + buildList { + repeat(utils.authenticationRepository.hintedPinLength - 1) { add(it + 1) } + } + ) + setAutoConfirmEnabled(true) + } assertThat(hintedPinLength).isNull() } @@ -534,13 +575,15 @@ class AuthenticationInteractorTest : SysuiTestCase() { fun hintedPinLength_withAutoConfirmPinAtRightLength_isSameLength() = testScope.runTest { val hintedPinLength by collectLastValue(underTest.hintedPinLength) - utils.authenticationRepository.setAuthenticationMethod( - DataLayerAuthenticationMethodModel.Pin - ) - utils.authenticationRepository.setAutoConfirmEnabled(true) - utils.authenticationRepository.overrideCredential( - buildList { repeat(utils.authenticationRepository.hintedPinLength) { add(it + 1) } } - ) + utils.authenticationRepository.apply { + setAuthenticationMethod(DataLayerAuthenticationMethodModel.Pin) + setAutoConfirmEnabled(true) + overrideCredential( + buildList { + repeat(utils.authenticationRepository.hintedPinLength) { add(it + 1) } + } + ) + } assertThat(hintedPinLength).isEqualTo(utils.authenticationRepository.hintedPinLength) } @@ -549,16 +592,20 @@ class AuthenticationInteractorTest : SysuiTestCase() { fun hintedPinLength_withAutoConfirmPinTooLong_isNull() = testScope.runTest { val hintedPinLength by collectLastValue(underTest.hintedPinLength) - utils.authenticationRepository.setAuthenticationMethod( - DataLayerAuthenticationMethodModel.Pin - ) - utils.authenticationRepository.overrideCredential( - buildList { - repeat(utils.authenticationRepository.hintedPinLength + 1) { add(it + 1) } - } - ) - utils.authenticationRepository.setAutoConfirmEnabled(true) + utils.authenticationRepository.apply { + setAuthenticationMethod(DataLayerAuthenticationMethodModel.Pin) + overrideCredential( + buildList { + repeat(utils.authenticationRepository.hintedPinLength + 1) { add(it + 1) } + } + ) + setAutoConfirmEnabled(true) + } assertThat(hintedPinLength).isNull() } + + private fun switchToScene(sceneKey: SceneKey) { + sceneInteractor.changeScene(SceneModel(sceneKey), "reason") + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt index 45d7a5ebb60a..23f243c8ebda 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt @@ -84,22 +84,24 @@ class LockscreenSceneViewModelTest : SysuiTestCase() { } @Test - fun upTransitionSceneKey_swipeToUnlockEnabled_gone() = + fun upTransitionSceneKey_canSwipeToUnlock_gone() = testScope.runTest { val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.None) utils.authenticationRepository.setLockscreenEnabled(true) - utils.authenticationRepository.setUnlocked(false) + utils.authenticationRepository.setUnlocked(true) + sceneInteractor.changeScene(SceneModel(SceneKey.Lockscreen), "reason") assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Gone) } @Test - fun upTransitionSceneKey_swipeToUnlockNotEnabled_bouncer() = + fun upTransitionSceneKey_cannotSwipeToUnlock_bouncer() = testScope.runTest { val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.authenticationRepository.setUnlocked(false) + sceneInteractor.changeScene(SceneModel(SceneKey.Lockscreen), "reason") assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Bouncer) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt index 507267e2d185..0829f31e3890 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt @@ -134,6 +134,7 @@ class SceneTestUtils( fun authenticationInteractor( repository: AuthenticationRepository, + sceneInteractor: SceneInteractor = sceneInteractor(), ): AuthenticationInteractor { return AuthenticationInteractor( applicationScope = applicationScope(), @@ -141,6 +142,7 @@ class SceneTestUtils( backgroundDispatcher = testDispatcher, userRepository = userRepository, keyguardRepository = keyguardRepository, + sceneInteractor = sceneInteractor, clock = mock { whenever(elapsedRealtime()).thenAnswer { testScope.currentTime } } ) } |