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

Commit 8481951b authored by Lucas Silva's avatar Lucas Silva
Browse files

Fix race condition in DREAM->LOCKSCREEN transition

When the dream ends, there is a race condition between the isDreaming
signal and the occluded signal. To ensure that we let occluded flip to
false first before dreaming does, in order to avoid erronously
transitioning to an OCCLUDED state, we add a small debounce to the
dreaming signal.

Flag: NA
Bug: 331240295
Test: verified DREAMING->LOCKSCREEN and DREAMING->OCCLUDED works
correctly by looking at KeyguardTransitionRepository logs

Change-Id: Ib5a1a61f89eed7f8541a1b2ce0d9e7a7344605e5
parent 74217e5c
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -35,7 +35,9 @@ import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.launch

@SysUISingleton
@@ -106,6 +108,7 @@ constructor(
        }
    }

    @OptIn(FlowPreview::class)
    private fun listenForDreamingToOccluded() {
        if (KeyguardWmStateRefactor.isEnabled) {
            scope.launch {
@@ -121,13 +124,24 @@ constructor(
            scope.launch {
                combine(
                        keyguardInteractor.isKeyguardOccluded,
                        keyguardInteractor.isDreaming,
                        keyguardInteractor.isDreaming
                            // Debounce the dreaming signal since there is a race condition between
                            // the occluded and dreaming signals. We therefore add a small delay
                            // to give enough time for occluded to flip to false when the dream
                            // ends, to avoid transitioning to OCCLUDED erroneously when exiting
                            // the dream.
                            .debounce(100.milliseconds),
                        ::Pair
                    )
                    .filterRelevantKeyguardStateAnd { (isOccluded, isDreaming) ->
                        isOccluded && !isDreaming
                    }
                    .collect { startTransitionTo(KeyguardState.OCCLUDED) }
                    .collect {
                        startTransitionTo(
                            toState = KeyguardState.OCCLUDED,
                            ownerReason = "Occluded but no longer dreaming",
                        )
                    }
            }
        }
    }