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

Commit 17c4a0d1 authored by Jorim Jaggi's avatar Jorim Jaggi Committed by Android (Google) Code Review
Browse files

Merge "Make sure app transition are started simultaneously"

parents 4ea33ae8 d6d97169
Loading
Loading
Loading
Loading
+33 −2
Original line number Original line Diff line number Diff line
@@ -67,6 +67,9 @@ class SurfaceAnimationRunner {
    @VisibleForTesting
    @VisibleForTesting
    final ArrayMap<SurfaceControl, RunningAnimation> mRunningAnimations = new ArrayMap<>();
    final ArrayMap<SurfaceControl, RunningAnimation> mRunningAnimations = new ArrayMap<>();


    @GuardedBy("mLock")
    private boolean mAnimationStartDeferred;

    SurfaceAnimationRunner() {
    SurfaceAnimationRunner() {
        this(null /* callbackProvider */, null /* animatorFactory */, new Transaction());
        this(null /* callbackProvider */, null /* animatorFactory */, new Transaction());
    }
    }
@@ -86,13 +89,41 @@ class SurfaceAnimationRunner {
                : SfValueAnimator::new;
                : SfValueAnimator::new;
    }
    }


    /**
     * Defers starting of animations until {@link #continueStartingAnimations} is called. This
     * method is NOT nestable.
     *
     * @see #continueStartingAnimations
     */
    void deferStartingAnimations() {
        synchronized (mLock) {
            mAnimationStartDeferred = true;
        }
    }

    /**
     * Continues starting of animations.
     *
     * @see #deferStartingAnimations
     */
    void continueStartingAnimations() {
        synchronized (mLock) {
            mAnimationStartDeferred = false;
            if (!mPendingAnimations.isEmpty()) {
                mChoreographer.postFrameCallback(this::startAnimations);
            }
        }
    }

    void startAnimation(AnimationSpec a, SurfaceControl animationLeash, Transaction t,
    void startAnimation(AnimationSpec a, SurfaceControl animationLeash, Transaction t,
            Runnable finishCallback) {
            Runnable finishCallback) {
        synchronized (mLock) {
        synchronized (mLock) {
            final RunningAnimation runningAnim = new RunningAnimation(a, animationLeash,
            final RunningAnimation runningAnim = new RunningAnimation(a, animationLeash,
                    finishCallback);
                    finishCallback);
            mPendingAnimations.put(animationLeash, runningAnim);
            mPendingAnimations.put(animationLeash, runningAnim);
            mChoreographer.postFrameCallback(this::stepAnimation);
            if (!mAnimationStartDeferred) {
                mChoreographer.postFrameCallback(this::startAnimations);
            }


            // Some animations (e.g. move animations) require the initial transform to be applied
            // Some animations (e.g. move animations) require the initial transform to be applied
            // immediately.
            // immediately.
@@ -185,7 +216,7 @@ class SurfaceAnimationRunner {
        a.mAnimSpec.apply(t, a.mLeash, currentPlayTime);
        a.mAnimSpec.apply(t, a.mLeash, currentPlayTime);
    }
    }


    private void stepAnimation(long frameTimeNanos) {
    private void startAnimations(long frameTimeNanos) {
        synchronized (mLock) {
        synchronized (mLock) {
            startPendingAnimationsLocked();
            startPendingAnimationsLocked();
        }
        }
+22 −15
Original line number Original line Diff line number Diff line
@@ -349,21 +349,28 @@ class WindowSurfacePlacer {
            animLp = null;
            animLp = null;
        }
        }


        final int layoutRedo;
        mService.mSurfaceAnimationRunner.deferStartingAnimations();
        try {
            processApplicationsAnimatingInPlace(transit);
            processApplicationsAnimatingInPlace(transit);


            mTmpLayerAndToken.token = null;
            mTmpLayerAndToken.token = null;
            handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
            handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
            final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
            final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
        final AppWindowToken topOpeningApp = handleOpeningApps(transit, animLp, voiceInteraction);
            final AppWindowToken topOpeningApp = handleOpeningApps(transit, animLp,
                    voiceInteraction);


            mService.mAppTransition.setLastAppTransition(transit, topOpeningApp, topClosingApp);
            mService.mAppTransition.setLastAppTransition(transit, topOpeningApp, topClosingApp);


            final int flags = mService.mAppTransition.getTransitFlags();
            final int flags = mService.mAppTransition.getTransitFlags();
        int layoutRedo = mService.mAppTransition.goodToGo(transit, topOpeningApp,
            layoutRedo = mService.mAppTransition.goodToGo(transit, topOpeningApp,
                    topClosingApp, mService.mOpeningApps, mService.mClosingApps);
                    topClosingApp, mService.mOpeningApps, mService.mClosingApps);
            handleNonAppWindowsInTransition(transit, flags);
            handleNonAppWindowsInTransition(transit, flags);
            mService.mAppTransition.postAnimationCallback();
            mService.mAppTransition.postAnimationCallback();
            mService.mAppTransition.clear();
            mService.mAppTransition.clear();
        } finally {
            mService.mSurfaceAnimationRunner.continueStartingAnimations();
        }


        mService.mTaskSnapshotController.onTransitionStarting();
        mService.mTaskSnapshotController.onTransitionStarting();


+14 −0
Original line number Original line Diff line number Diff line
@@ -162,6 +162,20 @@ public class SurfaceAnimationRunnerTest extends WindowTestsBase {
        verify(mMockAnimationSpec, atLeastOnce()).apply(any(), any(), eq(0L));
        verify(mMockAnimationSpec, atLeastOnce()).apply(any(), any(), eq(0L));
    }
    }


    @Test
    public void testDeferStartingAnimations() throws Exception {
        mSurfaceAnimationRunner.deferStartingAnimations();
        mSurfaceAnimationRunner.startAnimation(createTranslateAnimation(), mMockSurface,
                mMockTransaction, this::finishedCallback);
        waitUntilNextFrame();
        assertTrue(mSurfaceAnimationRunner.mRunningAnimations.isEmpty());
        mSurfaceAnimationRunner.continueStartingAnimations();
        waitUntilNextFrame();
        assertFalse(mSurfaceAnimationRunner.mRunningAnimations.isEmpty());
        mFinishCallbackLatch.await(1, SECONDS);
        assertFinishCallbackCalled();
    }

    private void waitUntilNextFrame() throws Exception {
    private void waitUntilNextFrame() throws Exception {
        final CountDownLatch latch = new CountDownLatch(1);
        final CountDownLatch latch = new CountDownLatch(1);
        mSurfaceAnimationRunner.mChoreographer.postCallback(Choreographer.CALLBACK_COMMIT,
        mSurfaceAnimationRunner.mChoreographer.postCallback(Choreographer.CALLBACK_COMMIT,