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

Commit 0ade739a authored by Caitlin Shkuratov's avatar Caitlin Shkuratov
Browse files

[Central Surfaces] Make KeyguardRepository.wakefulness a StateFlow.

In order to remove some CentralSurfaces references (specifically
mWakeUpComingFromTouch), it would be useful to be able to query the
current wakefulness status from KeyguardRepository. However, since
wakefulness is currently just a normal Flow, there's no way to get the
current value.

Converting this flow into a StateFlow gives us a few benefits:
1) Callers can query the flow for the current value instead of needing
   to collect on the flow.
2) Only one callback total is added to WakefulnessLifecycle, instead of
   one callback per flow consumer (14 as of this CL).

I believe this should be a no-op, since the wakefulness flow was already
emitting the current value when the flow starts, which mimicks StateFlow
behavior.

Bug: 284485594
Test: atest KeyguardRepositoryImplTest

Test: manual: verified via local logging that consumers of `wakefulness`
still (1) receive new values at the same times as before; (2) receive
the correct values. Specifically verified:
 - LightRevealScrimRepository.nonBiometricRevealEffect is notified
 whenever wakefulness changes
 - FromDozingTransitionInteractor.listenerForDozingToLockscreen is
 notified whenever wakefulness changes
 - FromPrimaryBouncerTransitionInteractor.listenForPrimaryBouncerToLockscreenOrOccluded
 fetches most recent value whenever primaryBouncerShowing state changes

Change-Id: I792953dd86b367b26540d408c3af9f83c502ea4d
parent 5026a169
Loading
Loading
Loading
Loading
+43 −37
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLoggin
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.common.shared.model.Position
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.doze.DozeMachine
import com.android.systemui.doze.DozeTransitionCallback
@@ -44,13 +45,16 @@ import com.android.systemui.statusbar.phone.DozeParameters
import com.android.systemui.statusbar.policy.KeyguardStateController
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.stateIn

/** Defines interface for classes that encapsulate application state for the keyguard. */
interface KeyguardRepository {
@@ -138,7 +142,7 @@ interface KeyguardRepository {
    val statusBarState: Flow<StatusBarState>

    /** Observable for device wake/sleep state */
    val wakefulness: Flow<WakefulnessModel>
    val wakefulness: StateFlow<WakefulnessModel>

    /** Observable for biometric unlock modes */
    val biometricUnlockState: Flow<BiometricUnlockModel>
@@ -202,7 +206,8 @@ constructor(
    private val dozeParameters: DozeParameters,
    private val authController: AuthController,
    private val dreamOverlayCallbackController: DreamOverlayCallbackController,
    @Main private val mainDispatcher: CoroutineDispatcher
    @Main private val mainDispatcher: CoroutineDispatcher,
    @Application private val scope: CoroutineScope,
) : KeyguardRepository {
    private val _animateBottomAreaDozingTransitions = MutableStateFlow(false)
    override val animateBottomAreaDozingTransitions =
@@ -486,7 +491,8 @@ constructor(
        awaitClose { biometricUnlockController.removeListener(callback) }
    }

    override val wakefulness: Flow<WakefulnessModel> = conflatedCallbackFlow {
    override val wakefulness: StateFlow<WakefulnessModel> =
        conflatedCallbackFlow {
                val observer =
                    object : WakefulnessLifecycle.Observer {
                        override fun onStartedWakingUp() {
@@ -513,20 +519,20 @@ constructor(
                            trySendWithFailureLogging(
                                WakefulnessModel.fromWakefulnessLifecycle(wakefulnessLifecycle),
                                TAG,
                        "updated wakefulness state"
                                "updated wakefulness state",
                            )
                        }
                    }

                wakefulnessLifecycle.addObserver(observer)
        trySendWithFailureLogging(
            WakefulnessModel.fromWakefulnessLifecycle(wakefulnessLifecycle),
            TAG,
            "initial wakefulness state"
        )

                awaitClose { wakefulnessLifecycle.removeObserver(observer) }
            }
            .stateIn(
                scope,
                // Use Eagerly so that we're always listening and never miss an event.
                SharingStarted.Eagerly,
                initialValue = WakefulnessModel.fromWakefulnessLifecycle(wakefulnessLifecycle),
            )

    override val fingerprintSensorLocation: Flow<Point?> = conflatedCallbackFlow {
        fun sendFpLocation() {
+2 −1
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import javax.inject.Inject
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
@@ -99,7 +100,7 @@ constructor(
    }

    /** The device wake/sleep state */
    val wakefulnessModel: Flow<WakefulnessModel> = repository.wakefulness
    val wakefulnessModel: StateFlow<WakefulnessModel> = repository.wakefulness

    /**
     * Dozing and dreaming have overlapping events. If the doze state remains in FINISH, it means
+2 −3
Original line number Diff line number Diff line
@@ -97,7 +97,8 @@ class KeyguardRepositoryImplTest : SysuiTestCase() {
                dozeParameters,
                authController,
                dreamOverlayCallbackController,
                mainDispatcher
                mainDispatcher,
                testScope.backgroundScope,
            )
    }

@@ -343,8 +344,6 @@ class KeyguardRepositoryImplTest : SysuiTestCase() {
                )

            job.cancel()
            runCurrent()
            verify(wakefulnessLifecycle).removeObserver(captor.value)
        }

    @Test
+1 −1
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ class FakeKeyguardRepository : KeyguardRepository {
        MutableStateFlow(
            WakefulnessModel(WakefulnessState.ASLEEP, WakeSleepReason.OTHER, WakeSleepReason.OTHER)
        )
    override val wakefulness: Flow<WakefulnessModel> = _wakefulnessModel
    override val wakefulness = _wakefulnessModel

    private val _isUdfpsSupported = MutableStateFlow(false)