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

Commit caedd597 authored by Matt Pietal's avatar Matt Pietal
Browse files

Transitions - Update for canceled state

When transitions are canceled a new one begins, existing animations
could be left in an incorrect state (position, alpha), so make sure to
end them where they should be. Also, if a transition is started
halfway, make sure to emit events to inform the ViewModel where it
should be at that point in time.

Also, prevent oscillating events for dreaming by adding in a slight
delay.

Bug: 260637747
Test: atest KeyguardScenariosTest

Change-Id: I03c9f25175f745e5eca93ab1ba74cd7f7005ee28
parent d707fcf7
Loading
Loading
Loading
Loading
+15 −24
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ import com.android.systemui.animation.Interpolators
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.BiometricUnlockModel.Companion.isWakeAndUnlock
import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
import com.android.systemui.keyguard.shared.model.DozeStateModel
import com.android.systemui.keyguard.shared.model.DozeStateModel.Companion.isDozeOff
import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -56,7 +56,7 @@ constructor(
        scope.launch {
            // Using isDreamingWithOverlay provides an optimized path to LOCKSCREEN state, which
            // otherwise would have gone through OCCLUDED first
            keyguardInteractor.isDreamingWithOverlay
            keyguardInteractor.isAbleToDream
                .sample(
                    combine(
                        keyguardInteractor.dozeTransitionModel,
@@ -65,8 +65,7 @@ constructor(
                    ),
                    ::toTriple
                )
                .collect { triple ->
                    val (isDreaming, dozeTransitionModel, lastStartedTransition) = triple
                .collect { (isDreaming, dozeTransitionModel, lastStartedTransition) ->
                    if (
                        !isDreaming &&
                            isDozeOff(dozeTransitionModel.to) &&
@@ -96,8 +95,7 @@ constructor(
                    ),
                    ::toTriple
                )
                .collect { triple ->
                    val (isDreaming, isOccluded, lastStartedTransition) = triple
                .collect { (isDreaming, isOccluded, lastStartedTransition) ->
                    if (
                        isOccluded &&
                            !isDreaming &&
@@ -123,14 +121,8 @@ constructor(

    private fun listenForDreamingToGone() {
        scope.launch {
            keyguardInteractor.biometricUnlockState
                .sample(keyguardTransitionInteractor.finishedKeyguardState, ::Pair)
                .collect { pair ->
                    val (biometricUnlockState, keyguardState) = pair
                    if (
                        keyguardState == KeyguardState.DREAMING &&
                            isWakeAndUnlock(biometricUnlockState)
                    ) {
            keyguardInteractor.biometricUnlockState.collect { biometricUnlockState ->
                if (biometricUnlockState == BiometricUnlockModel.WAKE_AND_UNLOCK_FROM_DREAM) {
                    keyguardTransitionRepository.startTransition(
                        TransitionInfo(
                            name,
@@ -151,8 +143,7 @@ constructor(
                    keyguardTransitionInteractor.finishedKeyguardState,
                    ::Pair
                )
                .collect { pair ->
                    val (dozeTransitionModel, keyguardState) = pair
                .collect { (dozeTransitionModel, keyguardState) ->
                    if (
                        dozeTransitionModel.to == DozeStateModel.DOZE &&
                            keyguardState == KeyguardState.DREAMING
+13 −2
Original line number Diff line number Diff line
@@ -32,12 +32,15 @@ import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.keyguard.shared.model.WakefulnessModel
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.CommandQueue.Callbacks
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.merge

/**
@@ -89,15 +92,23 @@ constructor(
    /**
     * Dozing and dreaming have overlapping events. If the doze state remains in FINISH, it means
     * that doze mode is not running and DREAMING is ok to commence.
     *
     * Allow a brief moment to prevent rapidly oscillating between true/false signals.
     */
    val isAbleToDream: Flow<Boolean> =
        merge(isDreaming, isDreamingWithOverlay)
            .sample(
            .combine(
                dozeTransitionModel,
                { isDreaming, dozeTransitionModel ->
                    isDreaming && isDozeOff(dozeTransitionModel.to)
                }
            )
            .flatMapLatest { isAbleToDream ->
                flow {
                    delay(50)
                    emit(isAbleToDream)
                }
            }
            .distinctUntilChanged()

    /** Whether the keyguard is showing or not. */
+13 −3
Original line number Diff line number Diff line
@@ -22,10 +22,14 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.domain.interactor.FromDreamingTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.AnimationParams
import com.android.systemui.keyguard.shared.model.TransitionState.CANCELED
import com.android.systemui.keyguard.shared.model.TransitionState.FINISHED
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge

/**
 * Breaks down DREAMING->LOCKSCREEN transition into discrete steps for corresponding views to
@@ -49,9 +53,15 @@ constructor(

    /** Lockscreen views y-translation */
    fun lockscreenTranslationY(translatePx: Int): Flow<Float> {
        return flowForAnimation(LOCKSCREEN_TRANSLATION_Y).map { value ->
        return merge(
            flowForAnimation(LOCKSCREEN_TRANSLATION_Y).map { value ->
                -translatePx + (EMPHASIZED_DECELERATE.getInterpolation(value) * translatePx)
        }
            },
            // On end, reset the translation to 0
            interactor.dreamingToLockscreenTransition
                .filter { it.transitionState == FINISHED || it.transitionState == CANCELED }
                .map { 0f }
        )
    }

    /** Lockscreen views alpha */
+3 −2
Original line number Diff line number Diff line
@@ -21,7 +21,8 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.domain.interactor.FromGoneTransitionInteractor.Companion.TO_DREAMING_DURATION
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.AnimationParams
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionState.CANCELED
import com.android.systemui.keyguard.shared.model.TransitionState.FINISHED
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.flow.Flow
@@ -45,7 +46,7 @@ constructor(
            },
            // On end, reset the translation to 0
            interactor.goneToDreamingTransition
                .filter { step -> step.transitionState == TransitionState.FINISHED }
                .filter { it.transitionState == FINISHED || it.transitionState == CANCELED }
                .map { 0f }
        )
    }
+3 −2
Original line number Diff line number Diff line
@@ -21,7 +21,8 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor.Companion.TO_DREAMING_DURATION
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.AnimationParams
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionState.CANCELED
import com.android.systemui.keyguard.shared.model.TransitionState.FINISHED
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.flow.Flow
@@ -48,7 +49,7 @@ constructor(
            },
            // On end, reset the translation to 0
            interactor.lockscreenToDreamingTransition
                .filter { step -> step.transitionState == TransitionState.FINISHED }
                .filter { it.transitionState == FINISHED || it.transitionState == CANCELED }
                .map { 0f }
        )
    }
Loading