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

Commit 152bf970 authored by Josh Tsuji's avatar Josh Tsuji Committed by Automerger Merge Worker
Browse files

Merge "Don't always showSurfaceBehindKeyguard if keyguard exit is cancelled."...

Merge "Don't always showSurfaceBehindKeyguard if keyguard exit is cancelled." into tm-qpr-dev am: 5fdc7c47 am: 8728581c

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20788987



Change-Id: Iaa86527205bb0ee4bb3bbc63c5740d3b744a07cb
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 34facaa4 8728581c
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -344,7 +344,7 @@ class KeyguardUnlockAnimationController @Inject constructor(
                override fun onAnimationEnd(animation: Animator) {
                    Log.d(TAG, "surfaceBehindEntryAnimator#onAnimationEnd")
                    playingCannedUnlockAnimation = false
                    keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(
                    keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
                        false /* cancelled */
                    )
                }
@@ -579,7 +579,7 @@ class KeyguardUnlockAnimationController @Inject constructor(
            biometricUnlockControllerLazy.get().isWakeAndUnlock -> {
                Log.d(TAG, "playCannedUnlockAnimation, isWakeAndUnlock")
                setSurfaceBehindAppearAmount(1f)
                keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(
                keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
                    false /* cancelled */)
            }

@@ -627,7 +627,7 @@ class KeyguardUnlockAnimationController @Inject constructor(
                return@postDelayed
            }

            keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(
            keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
                false /* cancelled */)
        }, CANNED_UNLOCK_START_DELAY)
    }
@@ -740,7 +740,8 @@ class KeyguardUnlockAnimationController @Inject constructor(
                        !keyguardStateController.isFlingingToDismissKeyguardDuringSwipeGesture &&
                        dismissAmount >= DISMISS_AMOUNT_EXIT_KEYGUARD_THRESHOLD)) {
            setSurfaceBehindAppearAmount(1f)
            keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(false /* cancelled */)
            keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
                    false /* cancelled */)
        }
    }

+36 −21
Original line number Diff line number Diff line
@@ -144,12 +144,12 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.util.DeviceConfigProxy;

import dagger.Lazy;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.concurrent.Executor;

import dagger.Lazy;

/**
 * Mediates requests related to the keyguard.  This includes queries about the
 * state of the keyguard, power management events that effect whether the keyguard
@@ -2719,27 +2719,42 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
    }

    /**
     * Called if the keyguard exit animation has been cancelled, and we should dismiss to the
     * keyguard.
     * Called if the keyguard exit animation has been cancelled.
     *
     * This can happen due to the system cancelling the RemoteAnimation (due to a timeout, a new
     * app transition before finishing the current RemoteAnimation).
     * app transition before finishing the current RemoteAnimation, or the keyguard being re-shown).
     */
    private void handleCancelKeyguardExitAnimation() {
        if (mPendingLock) {
            Log.d(TAG, "#handleCancelKeyguardExitAnimation: keyguard exit animation cancelled. "
                    + "There's a pending lock, so we were cancelled because the device was locked "
                    + "again during the unlock sequence. We should end up locked.");

            // A lock is pending, meaning the keyguard exit animation was cancelled because we're
            // re-locking. We should just end the surface-behind animation without exiting the
            // keyguard. The pending lock will be handled by onFinishedGoingToSleep().
            finishSurfaceBehindRemoteAnimation(true);
        } else {
            Log.d(TAG, "#handleCancelKeyguardExitAnimation: keyguard exit animation cancelled. "
                    + "No pending lock, we should end up unlocked with the app/launcher visible.");

            // No lock is pending, so the animation was cancelled during the unlock sequence, but
            // we should end up unlocked. Show the surface and exit the keyguard.
            showSurfaceBehindKeyguard();
        onKeyguardExitRemoteAnimationFinished(true /* cancelled */);
            exitKeyguardAndFinishSurfaceBehindRemoteAnimation(true /* cancelled */);
        }
    }

    /**
     * Called when we're done running the keyguard exit animation.
     * Called when we're done running the keyguard exit animation, we should now end up unlocked.
     *
     * This will call {@link #mSurfaceBehindRemoteAnimationFinishedCallback} to let WM know that
     * we're done with the RemoteAnimation, actually hide the keyguard, and clean up state related
     * to the keyguard exit animation.
     * This will call {@link #handleCancelKeyguardExitAnimation()} to let WM know that we're done
     * with the RemoteAnimation, actually hide the keyguard, and clean up state related to the
     * keyguard exit animation.
     *
     * @param cancelled {@code true} if the animation was cancelled before it finishes.
     */
    public void onKeyguardExitRemoteAnimationFinished(boolean cancelled) {
    public void exitKeyguardAndFinishSurfaceBehindRemoteAnimation(boolean cancelled) {
        Log.d(TAG, "onKeyguardExitRemoteAnimationFinished");
        if (!mSurfaceBehindRemoteAnimationRunning && !mSurfaceBehindRemoteAnimationRequested) {
            Log.d(TAG, "skip onKeyguardExitRemoteAnimationFinished cancelled=" + cancelled
@@ -2768,10 +2783,6 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
            }

            finishSurfaceBehindRemoteAnimation(cancelled);
            mSurfaceBehindRemoteAnimationRequested = false;

            // The remote animation is over, so we're not going away anymore.
            mKeyguardStateController.notifyKeyguardGoingAway(false);

            // Dispatch the callback on animation finishes.
            mUpdateMonitor.dispatchKeyguardDismissAnimationFinished();
@@ -2830,13 +2841,17 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
        return mSurfaceBehindRemoteAnimationRunning;
    }

    /** If it's running, finishes the RemoteAnimation on the surface behind the keyguard. */
    /**
     * If it's running, finishes the RemoteAnimation on the surface behind the keyguard and resets
     * related state.
     *
     * This does not set keyguard state to either locked or unlocked, it simply ends the remote
     * animation on the surface behind the keyguard. This can be called by
     */
    void finishSurfaceBehindRemoteAnimation(boolean cancelled) {
        if (!mSurfaceBehindRemoteAnimationRunning) {
            return;
        }

        mSurfaceBehindRemoteAnimationRequested = false;
        mSurfaceBehindRemoteAnimationRunning = false;
        mKeyguardStateController.notifyKeyguardGoingAway(false);

        if (mSurfaceBehindRemoteAnimationFinishedCallback != null) {
            try {
+3 −3
Original line number Diff line number Diff line
@@ -124,7 +124,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {

        // Also expect we've immediately asked the keyguard view mediator to finish the remote
        // animation.
        verify(keyguardViewMediator, times(1)).onKeyguardExitRemoteAnimationFinished(
        verify(keyguardViewMediator, times(1)).exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
            false /* cancelled */)

        verifyNoMoreInteractions(surfaceTransactionApplier)
@@ -144,7 +144,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
        )

        // Since the animation is running, we should not have finished the remote animation.
        verify(keyguardViewMediator, times(0)).onKeyguardExitRemoteAnimationFinished(
        verify(keyguardViewMediator, times(0)).exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
            false /* cancelled */)
    }

@@ -272,7 +272,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() {
        assertTrue(remainingTargets.isEmpty())

        // Since the animation is running, we should not have finished the remote animation.
        verify(keyguardViewMediator, times(0)).onKeyguardExitRemoteAnimationFinished(
        verify(keyguardViewMediator, times(0)).exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
                false /* cancelled */)
    }
}
+73 −1
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ import com.android.keyguard.KeyguardDisplayManager;
import com.android.keyguard.KeyguardSecurityView;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.mediator.ScreenOnCoordinator;
import com.android.systemui.DejankUtils;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.biometrics.AuthController;
@@ -160,6 +161,8 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
                mScreenOffAnimationController, mAuthController, mShadeExpansionStateManager,
                mShadeWindowLogger);

        DejankUtils.setImmediate(true);

        createAndStartViewMediator();
    }

@@ -355,9 +358,69 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
        verify(mCentralSurfaces).updateIsKeyguard();
    }

    @Test
    @TestableLooper.RunWithLooper(setAsMainLooper = true)
    public void testCancelKeyguardExitAnimation_noPendingLock_keyguardWillNotBeShowing() {
        startMockKeyguardExitAnimation();
        cancelMockKeyguardExitAnimation();

        // There should not be a pending lock, but try to handle it anyway to ensure one isn't set.
        mViewMediator.maybeHandlePendingLock();
        TestableLooper.get(this).processAllMessages();

        assertFalse(mViewMediator.isShowingAndNotOccluded());
    }

    @Test
    @TestableLooper.RunWithLooper(setAsMainLooper = true)
    public void testCancelKeyguardExitAnimationDueToSleep_withPendingLock_keyguardWillBeShowing() {
        startMockKeyguardExitAnimation();

        mViewMediator.onStartedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON);
        mViewMediator.onFinishedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, false);

        cancelMockKeyguardExitAnimation();

        mViewMediator.maybeHandlePendingLock();
        TestableLooper.get(this).processAllMessages();

        assertTrue(mViewMediator.isShowingAndNotOccluded());
    }

    @Test
    @TestableLooper.RunWithLooper(setAsMainLooper = true)
    public void testCancelKeyguardExitAnimationThenSleep_withPendingLock_keyguardWillBeShowing() {
        startMockKeyguardExitAnimation();
        cancelMockKeyguardExitAnimation();

        mViewMediator.maybeHandlePendingLock();
        TestableLooper.get(this).processAllMessages();

        mViewMediator.onStartedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON);
        mViewMediator.onFinishedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, false);

        mViewMediator.maybeHandlePendingLock();
        TestableLooper.get(this).processAllMessages();

        assertTrue(mViewMediator.isShowingAndNotOccluded());
    }

    @Test
    @TestableLooper.RunWithLooper(setAsMainLooper = true)
    public void testStartKeyguardExitAnimation_expectSurfaceBehindRemoteAnimation() {
        startMockKeyguardExitAnimation();
        assertTrue(mViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind());
    }

    /**
     * Configures mocks appropriately, then starts the keyguard exit animation.
     */
    private void startMockKeyguardExitAnimation() {
        mViewMediator.onSystemReady();
        TestableLooper.get(this).processAllMessages();

        mViewMediator.setShowingLocked(true);

        RemoteAnimationTarget[] apps = new RemoteAnimationTarget[]{
                mock(RemoteAnimationTarget.class)
        };
@@ -366,10 +429,19 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
        };
        IRemoteAnimationFinishedCallback callback = mock(IRemoteAnimationFinishedCallback.class);

        when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(true);
        mViewMediator.startKeyguardExitAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY, apps, wallpapers,
                null, callback);
        TestableLooper.get(this).processAllMessages();
        assertTrue(mViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind());
    }

    /**
     * Configures mocks appropriately, then cancels the keyguard exit animation.
     */
    private void cancelMockKeyguardExitAnimation() {
        when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(false);
        mViewMediator.cancelKeyguardExitAnimation();
        TestableLooper.get(this).processAllMessages();
    }

    private void createAndStartViewMediator() {