Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 477a9f05 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[flexiglass] Add a "canSwipeToDismissState" state." into udc-qpr-dev

parents 615cf195 ecc77c55
Loading
Loading
Loading
Loading
+43 −1
Original line number Diff line number Diff line
@@ -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

+22 −29
Original line number Diff line number Diff line
@@ -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)
            )
        }
    }
}
+155 −108
Original line number Diff line number Diff line
@@ -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)
            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.
            utils.authenticationRepository.setUnlocked(
                !utils.authenticationRepository.isUnlocked.value
            )
                // 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()
            utils.authenticationRepository.setUnlocked(
                !utils.authenticationRepository.isUnlocked.value
            )
                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)
            utils.authenticationRepository.apply {
                setUnlocked(false)
                runCurrent()
            utils.authenticationRepository.setAuthenticationMethod(
                DataLayerAuthenticationMethodModel.Password
            )
                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)
            utils.authenticationRepository.apply {
                setUnlocked(false)
                runCurrent()
            utils.authenticationRepository.setAuthenticationMethod(
                DataLayerAuthenticationMethodModel.None
            )
                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)
            utils.authenticationRepository.apply {
                setUnlocked(true)
                runCurrent()
            utils.authenticationRepository.setAuthenticationMethod(
                DataLayerAuthenticationMethodModel.Password
            )
                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)
            utils.authenticationRepository.apply {
                setUnlocked(true)
                runCurrent()
            utils.authenticationRepository.setAuthenticationMethod(
                DataLayerAuthenticationMethodModel.None
            )
                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(
            utils.authenticationRepository.apply {
                setAuthenticationMethod(DataLayerAuthenticationMethodModel.Pin)
                overrideCredential(
                    buildList {
                        repeat(utils.authenticationRepository.hintedPinLength - 1) { add(it + 1) }
                    }
                )
            utils.authenticationRepository.setAutoConfirmEnabled(true)
                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(
            utils.authenticationRepository.apply {
                setAuthenticationMethod(DataLayerAuthenticationMethodModel.Pin)
                overrideCredential(
                    buildList {
                        repeat(utils.authenticationRepository.hintedPinLength + 1) { add(it + 1) }
                    }
                )
            utils.authenticationRepository.setAutoConfirmEnabled(true)
                setAutoConfirmEnabled(true)
            }

            assertThat(hintedPinLength).isNull()
        }

    private fun switchToScene(sceneKey: SceneKey) {
        sceneInteractor.changeScene(SceneModel(sceneKey), "reason")
    }
}
+5 −3
Original line number Diff line number Diff line
@@ -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)
        }
+2 −0
Original line number Diff line number Diff line
@@ -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 } }
        )
    }