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

Commit 00570e26 authored by Josh Tsuji's avatar Josh Tsuji Committed by Android (Google) Code Review
Browse files

Merge "Directly startTransition in KeyguardDismissTransitionInteractor." into main

parents c14127a6 886b887a
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.platform.test.annotations.RequiresFlagsEnabled
import android.platform.test.flag.junit.CheckFlagsRule
import android.platform.test.flag.junit.DeviceFlagsValueProvider
import android.view.IRemoteAnimationFinishedCallback
import android.view.RemoteAnimationTarget
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -39,11 +40,11 @@ import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.any
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever

@@ -230,12 +231,15 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() {
    @Test
    fun remoteAnimationInstantlyFinished_ifDismissTransitionNotStarted() {
        val mockedCallback = mock<IRemoteAnimationFinishedCallback>()
        whenever(keyguardDismissTransitionInteractor.startDismissKeyguardTransition(any()))
            .thenReturn(false)

        // Call the onAlreadyGone callback immediately.
        doAnswer { invocation -> (invocation.getArgument(1) as (() -> Unit)).invoke() }
            .whenever(keyguardDismissTransitionInteractor)
            .startDismissKeyguardTransition(any(), any())

        underTest.onKeyguardGoingAwayRemoteAnimationStart(
            transit = 0,
            apps = emptyArray(),
            apps = arrayOf(mock<RemoteAnimationTarget>()),
            wallpapers = emptyArray(),
            nonApps = emptyArray(),
            finishedCallback = mockedCallback,
+18 −19
Original line number Diff line number Diff line
@@ -174,16 +174,14 @@ constructor(
        if (!isKeyguardGoingAway) {
            // Since WM triggered this, we're likely not transitioning to GONE yet. See if we can
            // start that transition.
            val startedDismiss =
            keyguardDismissTransitionInteractor.startDismissKeyguardTransition(
                    reason = "Going away remote animation started"
                )

            if (!startedDismiss) {
                // If the transition wasn't started, we're already GONE. This can happen with timing
                // issues, where the remote animation took a long time to start, and something else
                // caused us to unlock in the meantime. Since we're already GONE, simply end the
                // remote animatiom immediately.
                reason = "Going away remote animation started",
                onAlreadyGone = {
                    // Called if we're already GONE by the time the dismiss transition would have
                    // started. This can happen due to timing issues, where the remote animation
                    // took a long time to start, and something else caused us to unlock in the
                    // meantime. Since we're already GONE, simply end the remote animation
                    // immediately.
                    Log.d(
                        TAG,
                        "onKeyguardGoingAwayRemoteAnimationStart: " +
@@ -191,8 +189,9 @@ constructor(
                            "Ending remote animation.",
                    )
                    finishedCallback.onAnimationFinished()
                return
            }
                    isKeyguardGoingAway = false
                },
            )

            isKeyguardGoingAway = true
        }
+53 −27
Original line number Diff line number Diff line
@@ -16,23 +16,31 @@

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

import android.animation.ValueAnimator
import android.util.Log
import com.android.systemui.Flags.transitionRaceCondition
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCER
import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
import com.android.systemui.keyguard.shared.model.KeyguardState.DOZING
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.keyguard.shared.model.TransitionInfo
import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

@SysUISingleton
class KeyguardDismissTransitionInteractor
@Inject
constructor(
    @Background private val scope: CoroutineScope,
    private val repository: KeyguardTransitionRepository,
    private val fromLockscreenTransitionInteractor: FromLockscreenTransitionInteractor,
    private val fromPrimaryBouncerTransitionInteractor: FromPrimaryBouncerTransitionInteractor,
@@ -43,47 +51,65 @@ constructor(
) {

    /**
     * Called to start a transition that will ultimately dismiss the keyguard from the current
     * state.
     * Launches a coroutine to start a transition that will ultimately dismiss the keyguard from the
     * current state.
     *
     * This is called exclusively by sources that can authoritatively say we should be unlocked,
     * including KeyguardSecurityContainerController and WindowManager.
     *
     * Returns [false] if the transition was not started, because we're already GONE or we don't
     * know how to dismiss keyguard from the current state.
     * This is one of the few transitions that is started outside of the From*TransitionInteractor
     * classes. This is because this is an external call that must be respected, so it doesn't
     * matter what state we're in/coming from - we must transition from that state to GONE.
     *
     * Invokes [onAlreadyGone] if the transition was not started because we're already GONE by the
     * time the coroutine runs.
     */
    fun startDismissKeyguardTransition(reason: String = ""): Boolean {
        if (SceneContainerFlag.isEnabled) return false
    @JvmOverloads
    fun startDismissKeyguardTransition(reason: String = "", onAlreadyGone: (() -> Unit)? = null) {
        if (SceneContainerFlag.isEnabled) return
        Log.d(TAG, "#startDismissKeyguardTransition(reason=$reason)")

        scope.launch {
            val startedState =
                if (transitionRaceCondition()) {
                    repository.currentTransitionInfo.to
                } else {
                    repository.currentTransitionInfoInternal.value.to
                }

            val animator: ValueAnimator? =
                when (startedState) {
            LOCKSCREEN -> fromLockscreenTransitionInteractor.dismissKeyguard()
            PRIMARY_BOUNCER -> fromPrimaryBouncerTransitionInteractor.dismissPrimaryBouncer()
            ALTERNATE_BOUNCER -> fromAlternateBouncerTransitionInteractor.dismissAlternateBouncer()
            AOD -> fromAodTransitionInteractor.dismissAod()
            DOZING -> fromDozingTransitionInteractor.dismissFromDozing()
            KeyguardState.OCCLUDED -> fromOccludedTransitionInteractor.dismissFromOccluded()
            KeyguardState.GONE -> {
                    LOCKSCREEN -> fromLockscreenTransitionInteractor
                    PRIMARY_BOUNCER -> fromPrimaryBouncerTransitionInteractor
                    ALTERNATE_BOUNCER -> fromAlternateBouncerTransitionInteractor
                    AOD -> fromAodTransitionInteractor
                    DOZING -> fromDozingTransitionInteractor
                    OCCLUDED -> fromOccludedTransitionInteractor
                    else -> null
                }?.getDefaultAnimatorForTransitionsToState(KeyguardState.GONE)

            if (startedState != KeyguardState.GONE && animator != null) {
                repository.startTransition(
                    TransitionInfo(
                        "KeyguardDismissTransitionInteractor" +
                            if (reason.isNotBlank()) "($reason)" else "",
                        startedState,
                        KeyguardState.GONE,
                        animator,
                        TransitionModeOnCanceled.LAST_VALUE,
                    )
                )
            } else {
                Log.i(
                    TAG,
                    "Already transitioning to GONE; ignoring startDismissKeyguardTransition.",
                    "Can't transition to GONE from $startedState; " +
                        "ignoring startDismissKeyguardTransition.",
                )
                return false
                onAlreadyGone?.invoke()
            }
            else -> {
                Log.e(TAG, "We don't know how to dismiss keyguard from state $startedState.")
                return false
        }
    }

        return true
    }

    companion object {
        private val TAG = KeyguardDismissTransitionInteractor::class.simpleName
    }
+2 −0
Original line number Diff line number Diff line
@@ -18,10 +18,12 @@ package com.android.systemui.keyguard.domain.interactor

import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope

val Kosmos.keyguardDismissTransitionInteractor: KeyguardDismissTransitionInteractor by
    Kosmos.Fixture {
        KeyguardDismissTransitionInteractor(
            scope = testScope,
            repository = keyguardTransitionRepository,
            fromLockscreenTransitionInteractor = fromLockscreenTransitionInteractor,
            fromPrimaryBouncerTransitionInteractor = fromPrimaryBouncerTransitionInteractor,