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

Commit 4f82f66e authored by Chandru S's avatar Chandru S
Browse files

Minor cleanup of dismiss action interactor to hide state that it doesn't have to expose.

 - Hides internals of the interactor as private properties and makes the interactor "activateable"
 - The interactor is now responsible for orchestrating the execution of the dismiss action based on various triggers, this was being done by KeyguardDismissActionBinder before
 - Also invokes notifyKeyguardAuthenticatedHandled to reset biometric authenticated state stored in KeyguardBouncerRepository, this was previously done by KeyguardBouncerViewBinder

Flag: com.android.systemui.compose_bouncer
Bug: 310005730
Test: atest KeyguardDismissActionInteractorTest
Change-Id: I789996d187353ecf9c3065ad8e33187b30a0e98d
parent dd64bf8d
Loading
Loading
Loading
Loading
+109 −78
Original line number Diff line number Diff line
@@ -19,25 +19,24 @@ package com.android.systemui.keyguard.domain.interactor

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.app.tracing.coroutines.launchTraced
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.keyguardRepository
import com.android.systemui.keyguard.shared.model.DismissAction
import com.android.systemui.keyguard.shared.model.KeyguardDone
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testScope
import com.android.systemui.power.data.repository.fakePowerRepository
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.power.shared.model.WakeSleepReason
import com.android.systemui.power.shared.model.WakefulnessState
import com.android.systemui.scene.data.repository.Idle
@@ -45,12 +44,12 @@ import com.android.systemui.scene.data.repository.Transition
import com.android.systemui.scene.data.repository.setSceneTransition
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -76,25 +75,13 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() {
        MockitoAnnotations.initMocks(this)

        dismissInteractor = kosmos.keyguardDismissInteractor
        underTest =
            KeyguardDismissActionInteractor(
                repository = keyguardRepository,
                transitionInteractor = kosmos.keyguardTransitionInteractor,
                dismissInteractor = dismissInteractor,
                applicationScope = testScope.backgroundScope,
                deviceUnlockedInteractor = { kosmos.deviceUnlockedInteractor },
                powerInteractor = kosmos.powerInteractor,
                alternateBouncerInteractor = kosmos.alternateBouncerInteractor,
                shadeInteractor = { kosmos.shadeInteractor },
                keyguardInteractor = { kosmos.keyguardInteractor },
                sceneInteractor = { kosmos.sceneInteractor },
            )
        underTest = kosmos.keyguardDismissActionInteractor
    }

    @Test
    fun updateDismissAction_onRepoChange() =
        testScope.runTest {
            val dismissAction by collectLastValue(underTest.dismissAction)
            val dismissAction by collectLastValue(keyguardRepository.dismissAction)

            val newDismissAction =
                DismissAction.RunImmediately(
@@ -152,11 +139,16 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() {
        }

    @Test
    fun executeDismissAction_dismissKeyguardRequestWithImmediateDismissAction_biometricAuthed() =
    fun dismissActionExecuted_ImmediateDismissAction_biometricAuthed() =
        testScope.runTest {
            val executeDismissAction by collectLastValue(underTest.executeDismissAction)
            val keyguardDoneTiming by collectLastValue(kosmos.keyguardRepository.keyguardDone)
            var wasDismissActionInvoked = false
            startInteractor()

            val onDismissAction = { KeyguardDone.IMMEDIATE }
            val onDismissAction = {
                wasDismissActionInvoked = true
                KeyguardDone.IMMEDIATE
            }
            keyguardRepository.setDismissAction(
                DismissAction.RunImmediately(
                    onDismissAction = onDismissAction,
@@ -166,16 +158,48 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() {
                )
            )
            kosmos.fakeKeyguardBouncerRepository.setKeyguardAuthenticatedBiometrics(true)
            assertThat(executeDismissAction).isEqualTo(onDismissAction)
            runCurrent()

            assertThat(wasDismissActionInvoked).isTrue()
            assertThat(keyguardDoneTiming).isEqualTo(KeyguardDone.IMMEDIATE)
            assertThat(keyguardRepository.dismissAction.value).isEqualTo(DismissAction.None)
        }

    @Test
    fun executeDismissAction_dismissKeyguardRequestWithoutImmediateDismissAction() =
    fun dismissActionExecuted_LaterKeyguardDoneTimingIsStored_biometricAuthed() =
        testScope.runTest {
            val executeDismissAction by collectLastValue(underTest.executeDismissAction)
            val keyguardDoneTiming by collectLastValue(kosmos.keyguardRepository.keyguardDone)
            var wasDismissActionInvoked = false
            startInteractor()

            val onDismissAction = {
                wasDismissActionInvoked = true
                KeyguardDone.LATER
            }
            keyguardRepository.setDismissAction(
                DismissAction.RunImmediately(
                    onDismissAction = onDismissAction,
                    onCancelAction = {},
                    message = "message",
                    willAnimateOnLockscreen = true,
                )
            )
            kosmos.fakeKeyguardBouncerRepository.setKeyguardAuthenticatedBiometrics(true)
            runCurrent()

            assertThat(wasDismissActionInvoked).isTrue()
            assertThat(keyguardDoneTiming).isEqualTo(KeyguardDone.LATER)
            assertThat(keyguardRepository.dismissAction.value).isEqualTo(DismissAction.None)
        }

    @Test
    fun dismissActionExecuted_WithoutImmediateDismissAction() =
        testScope.runTest {
            var wasDismissActionInvoked = false
            startInteractor()

            // WHEN a keyguard action will run after the keyguard is gone
            val onDismissAction = {}
            val onDismissAction = { wasDismissActionInvoked = true }
            keyguardRepository.setDismissAction(
                DismissAction.RunAfterKeyguardGone(
                    dismissAction = onDismissAction,
@@ -184,33 +208,39 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() {
                    willAnimateOnLockscreen = true,
                )
            )
            assertThat(executeDismissAction).isNull()
            assertThat(wasDismissActionInvoked).isFalse()

            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
                SuccessFingerprintAuthenticationStatus(0, true)
            )
            kosmos.setSceneTransition(Idle(Scenes.Gone))
            kosmos.sceneInteractor.changeScene(Scenes.Gone, "")
            runCurrent()

            assertThat(executeDismissAction).isNotNull()
            assertThat(wasDismissActionInvoked).isTrue()
            assertThat(keyguardRepository.dismissAction.value).isEqualTo(DismissAction.None)
        }

    @Test
    fun resetDismissAction() =
        testScope.runTest {
            kosmos.setSceneTransition(Idle(Scenes.Bouncer))
            val resetDismissAction by collectLastValue(underTest.resetDismissAction)
            var wasOnCancelInvoked = false
            startInteractor()
            keyguardRepository.setDismissAction(
                DismissAction.RunAfterKeyguardGone(
                    dismissAction = {},
                    onCancelAction = {},
                    onCancelAction = { wasOnCancelInvoked = true },
                    message = "message",
                    willAnimateOnLockscreen = true,
                )
            )
            assertThat(resetDismissAction).isNull()
            assertThat(wasOnCancelInvoked).isFalse()
            kosmos.setSceneTransition(Idle(Scenes.Lockscreen))
            assertThat(resetDismissAction).isEqualTo(Unit)
            runCurrent()

            assertThat(wasOnCancelInvoked).isTrue()
            assertThat(keyguardRepository.dismissAction.value).isEqualTo(DismissAction.None)
        }

    @Test
@@ -220,21 +250,25 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() {
            kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                AuthenticationMethodModel.None
            )
            val resetDismissAction by collectLastValue(underTest.resetDismissAction)
            keyguardRepository.setDismissAction(
            var wasOnCancelInvoked = false

            val dismissAction =
                DismissAction.RunAfterKeyguardGone(
                    dismissAction = {},
                    onCancelAction = {},
                    onCancelAction = { wasOnCancelInvoked = true },
                    message = "message",
                    willAnimateOnLockscreen = true,
                )
            )
            assertThat(resetDismissAction).isNull()
            keyguardRepository.setDismissAction(dismissAction)
            assertThat(wasOnCancelInvoked).isFalse()

            kosmos.setSceneTransition(
                Transition(from = Scenes.Bouncer, to = Scenes.Shade, progress = flowOf(1f))
            )
            assertThat(resetDismissAction).isNull()
            runCurrent()

            assertThat(wasOnCancelInvoked).isFalse()
            assertThat(keyguardRepository.dismissAction.value).isEqualTo(dismissAction)
        }

    @Test
@@ -244,29 +278,34 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() {
            kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                AuthenticationMethodModel.None
            )
            val resetDismissAction by collectLastValue(underTest.resetDismissAction)
            var wasOnCancelInvoked = false
            startInteractor()

            keyguardRepository.setDismissAction(
                DismissAction.RunAfterKeyguardGone(
                    dismissAction = {},
                    onCancelAction = {},
                    onCancelAction = { wasOnCancelInvoked = true },
                    message = "message",
                    willAnimateOnLockscreen = true,
                )
            )
            assertThat(resetDismissAction).isNull()
            assertThat(wasOnCancelInvoked).isFalse()
            kosmos.fakePowerRepository.updateWakefulness(
                rawState = WakefulnessState.ASLEEP,
                lastWakeReason = WakeSleepReason.POWER_BUTTON,
                lastSleepReason = WakeSleepReason.TIMEOUT,
                powerButtonLaunchGestureTriggered = false,
            )
            assertThat(resetDismissAction).isEqualTo(Unit)
            runCurrent()

            assertThat(wasOnCancelInvoked).isTrue()
            assertThat(keyguardRepository.dismissAction.value).isEqualTo(DismissAction.None)
        }

    @Test
    fun setDismissAction_callsCancelRunnableOnPreviousDismissAction() =
        testScope.runTest {
            val dismissAction by collectLastValue(underTest.dismissAction)
            val dismissAction by collectLastValue(keyguardRepository.dismissAction)
            var previousDismissActionCancelCalled = false
            keyguardRepository.setDismissAction(
                DismissAction.RunImmediately(
@@ -293,27 +332,6 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() {
            assertThat(dismissAction).isEqualTo(newDismissAction)
        }

    @Test
    fun handleDismissAction() =
        testScope.runTest {
            val dismissAction by collectLastValue(underTest.dismissAction)
            underTest.handleDismissAction()
            assertThat(dismissAction).isEqualTo(DismissAction.None)
        }

    @Test
    fun setKeyguardDone() =
        testScope.runTest {
            val keyguardDoneTiming by collectLastValue(dismissInteractor.keyguardDone)
            runCurrent()

            underTest.setKeyguardDone(KeyguardDone.LATER)
            assertThat(keyguardDoneTiming).isEqualTo(KeyguardDone.LATER)

            underTest.setKeyguardDone(KeyguardDone.IMMEDIATE)
            assertThat(keyguardDoneTiming).isEqualTo(KeyguardDone.IMMEDIATE)
        }

    @Test
    @EnableSceneContainer
    fun dismissAction_executesBeforeItsReset_sceneContainerOn_swipeAuth_fromQsScene() =
@@ -324,11 +342,11 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() {
                MutableStateFlow<ObservableTransitionState>(
                    ObservableTransitionState.Idle(currentScene!!)
                )
            startInteractor()

            kosmos.sceneInteractor.setTransitionState(transitionState)
            val executeDismissAction by collectLastValue(underTest.executeDismissAction)
            val resetDismissAction by collectLastValue(underTest.resetDismissAction)
            assertThat(executeDismissAction).isNull()
            assertThat(resetDismissAction).isNull()
            var wasDismissActionInvoked = false
            var wasCancelActionInvoked = false
            kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                AuthenticationMethodModel.None
            )
@@ -338,20 +356,23 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() {
            transitionState.value = ObservableTransitionState.Idle(Scenes.QuickSettings)
            assertThat(currentScene).isEqualTo(Scenes.QuickSettings)

            assertThat(executeDismissAction).isNull()
            assertThat(resetDismissAction).isNull()
            assertThat(wasDismissActionInvoked).isFalse()
            assertThat(wasCancelActionInvoked).isFalse()

            val dismissAction =
                DismissAction.RunImmediately(
                    onDismissAction = { KeyguardDone.LATER },
                    onCancelAction = {},
                    onDismissAction = {
                        wasDismissActionInvoked = true
                        KeyguardDone.LATER
                    },
                    onCancelAction = { wasCancelActionInvoked = true },
                    message = "message",
                    willAnimateOnLockscreen = true,
                )
            underTest.setDismissAction(dismissAction)
            // Should still be null because the transition to Gone has not yet happened.
            assertThat(executeDismissAction).isNull()
            assertThat(resetDismissAction).isNull()
            // Should still not be run because the transition to Gone has not yet happened.
            assertThat(wasDismissActionInvoked).isFalse()
            assertThat(wasCancelActionInvoked).isFalse()

            transitionState.value =
                ObservableTransitionState.Transition.ChangeScene(
@@ -366,8 +387,8 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() {
                    isInPreviewStage = flowOf(false),
                )
            runCurrent()
            assertThat(executeDismissAction).isNull()
            assertThat(resetDismissAction).isNull()
            assertThat(wasDismissActionInvoked).isFalse()
            assertThat(wasCancelActionInvoked).isFalse()

            transitionState.value =
                ObservableTransitionState.Transition.ChangeScene(
@@ -384,7 +405,17 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() {
            kosmos.sceneInteractor.changeScene(Scenes.Gone, "")
            assertThat(currentScene).isEqualTo(Scenes.Gone)
            runCurrent()
            assertThat(executeDismissAction).isNotNull()
            assertThat(resetDismissAction).isNull()

            assertThat(wasDismissActionInvoked).isTrue()
            assertThat(wasCancelActionInvoked).isFalse()
        }

    private fun TestScope.startInteractor() {
        testScope.backgroundScope.launchTraced(
            "KeyguardDismissActionInteractorTest#startInteractor"
        ) {
            underTest.activate()
        }
        runCurrent()
    }
}
+85 −39
Original line number Diff line number Diff line
@@ -17,7 +17,9 @@

package com.android.systemui.keyguard.domain.interactor

import com.android.keyguard.logging.KeyguardLogger
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -27,28 +29,31 @@ import com.android.systemui.keyguard.shared.model.DismissAction
import com.android.systemui.keyguard.shared.model.KeyguardDone
import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.log.core.LogLevel
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.util.kotlin.Utils.Companion.sampleFilter
import com.android.systemui.util.kotlin.sample
import dagger.Lazy
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
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.filterNot
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch

/** Encapsulates business-logic for actions to run when the keyguard is dismissed. */
@ExperimentalCoroutinesApi
@@ -66,10 +71,10 @@ constructor(
    shadeInteractor: Lazy<ShadeInteractor>,
    keyguardInteractor: Lazy<KeyguardInteractor>,
    sceneInteractor: Lazy<SceneInteractor>,
) {
    val dismissAction: Flow<DismissAction> = repository.dismissAction

    val onCancel: Flow<Runnable> = dismissAction.map { it.onCancelAction }
    private val keyguardLogger: KeyguardLogger,
    private val primaryBouncerInteractor: PrimaryBouncerInteractor,
) : ExclusiveActivatable() {
    private val dismissAction: Flow<DismissAction> = repository.dismissAction

    // TODO (b/268240415): use message in alt + primary bouncer message
    // message to show to the user about the dismiss action, else empty string
@@ -90,10 +95,24 @@ constructor(
            )

    private val finishedTransitionToGone: Flow<Unit> =
        if (SceneContainerFlag.isEnabled) {
            // Using sceneInteractor instead of transitionInteractor because of a race
            // condition that forms between transitionInteractor (transitionState) and
            // isOnShadeWhileUnlocked where the latter emits false before the former emits
            // true, causing the merge to not emit until it's too late.
            sceneInteractor
                .get()
                .currentScene
                .map { it == Scenes.Gone }
                .distinctUntilChanged()
                .filter { it }
                .map {}
        } else {
            transitionInteractor
                .isFinishedIn(scene = Scenes.Gone, stateWithoutSceneContainer = GONE)
                .filter { it }
                .map {}
        }

    /**
     * True if the any variation of the notification shade or quick settings is showing AND the
@@ -125,30 +144,8 @@ constructor(
            }
        }

    val executeDismissAction: Flow<() -> KeyguardDone> =
        merge(
                if (SceneContainerFlag.isEnabled) {
                    // Using currentScene instead of finishedTransitionToGone because of a race
                    // condition that forms between finishedTransitionToGone and
                    // isOnShadeWhileUnlocked where the latter emits false before the former emits
                    // true, causing the merge to not emit until it's too late.
                    sceneInteractor
                        .get()
                        .currentScene
                        .map { it == Scenes.Gone }
                        .distinctUntilChanged()
                        .filter { it }
                } else {
                    finishedTransitionToGone
                },
                isOnShadeWhileUnlocked.filter { it }.map {},
                dismissInteractor.dismissKeyguardRequestWithImmediateDismissAction,
            )
            .sample(dismissAction)
            .filterNot { it is DismissAction.None }
            .map { it.onDismissAction }

    val resetDismissAction: Flow<Unit> =
    /** Flow that emits whenever we need to reset the dismiss action */
    private val resetDismissAction: Flow<Unit> =
        combine(
                if (SceneContainerFlag.isEnabled) {
                    // Using currentScene instead of isFinishedIn because of a race condition that
@@ -205,13 +202,62 @@ constructor(
        repository.setDismissAction(dismissAction)
    }

    fun handleDismissAction() {
        if (ComposeBouncerFlags.isUnexpectedlyInLegacyMode()) return
        repository.setDismissAction(DismissAction.None)
    /** Launch any relevant coroutines that are required by this interactor. */
    override suspend fun onActivated(): Nothing {
        coroutineScope {
            launch {
                merge(finishedTransitionToGone, isOnShadeWhileUnlocked.filter { it }.map {})
                    .collect {
                        log("finishedTransitionToGone")
                        runDismissAction()
                    }
            }

    suspend fun setKeyguardDone(keyguardDoneTiming: KeyguardDone) {
        if (ComposeBouncerFlags.isUnexpectedlyInLegacyMode()) return
            launch {
                dismissInteractor.dismissKeyguardRequestWithImmediateDismissAction.collect {
                    log("eventsThatRequireKeyguardDismissal")
                    runDismissAction()
                }
            }

            launch {
                resetDismissAction.collect {
                    log("resetDismissAction")
                    repository.dismissAction.value.onCancelAction.run()
                    clearDismissAction()
                }
            }

            launch { repository.dismissAction.collect { log("updatedDismissAction=$it") } }
            awaitCancellation()
        }
    }

    /** Run the dismiss action and starts the dismiss keyguard transition. */
    private suspend fun runDismissAction() {
        val dismissAction = repository.dismissAction.value
        var keyguardDoneTiming: KeyguardDone = KeyguardDone.IMMEDIATE
        if (dismissAction != DismissAction.None) {
            keyguardDoneTiming = dismissAction.onDismissAction.invoke()
            dismissInteractor.setKeyguardDone(keyguardDoneTiming)
            clearDismissAction()
        }
        if (!SceneContainerFlag.isEnabled) {
            // This is required to reset some state flows in the repository which ideally should be
            // sharedFlows but are not due to performance concerns.
            primaryBouncerInteractor.notifyKeyguardAuthenticatedHandled()
        }
    }

    private fun clearDismissAction() {
        repository.setDismissAction(DismissAction.None)
    }

    private fun log(message: String) {
        keyguardLogger.log(TAG, LogLevel.DEBUG, message)
    }

    companion object {
        private const val TAG = "KeyguardDismissAction"
    }
}
+1 −30

File changed.

Preview size limit exceeded, changes collapsed.

+5 −0
Original line number Diff line number Diff line
@@ -16,11 +16,14 @@

package com.android.systemui.keyguard.domain.interactor

import com.android.keyguard.logging.KeyguardLogger
import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
import com.android.systemui.bouncer.domain.interactor.primaryBouncerInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
import com.android.systemui.keyguard.data.repository.keyguardRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.shade.domain.interactor.shadeInteractor
@@ -40,5 +43,7 @@ val Kosmos.keyguardDismissActionInteractor by
            shadeInteractor = { shadeInteractor },
            keyguardInteractor = { keyguardInteractor },
            sceneInteractor = { sceneInteractor },
            keyguardLogger = KeyguardLogger(logcatLogBuffer("keyguard-logger-for-test")),
            primaryBouncerInteractor = primaryBouncerInteractor,
        )
    }