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

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

Merge "Fix issue with 0 duration animations"

parents 64d467ec a384403e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1923,6 +1923,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
                    mService.unregisterPointerEventListener(mService.mMousePositionTracker);
                }
            }
            mService.mAnimator.removeDisplayLocked(mDisplayId);

            // The pending transaction won't be applied so we should
            // just clean up any surfaces pending destruction.
            onPendingTransactionApplied();
+22 −16
Original line number Diff line number Diff line
@@ -72,23 +72,29 @@ class SurfaceAnimator {
                    target.mInnerAnimationFinishedCallback.onAnimationFinished(anim);
                    return;
                }

                // TODO: This should use pendingTransaction eventually, but right now things
                // happening on the animation finished callback are happening on the global
                // transaction.
                // For now we need to run this after it's guaranteed that the transaction that
                // reparents the surface onto the leash is executed already. Otherwise this may be
                // executed first, leading to surface loss, as the reparent operations wouldn't
                // be in order.
                mService.mAnimator.addAfterPrepareSurfacesRunnable(() -> {
                    if (anim != mAnimation) {
                        // Callback was from another animation - ignore.
                        return;
                    }

                    final Transaction t = new Transaction();
                    SurfaceControl.openTransaction();
                    try {
                        reset(t, true /* destroyLeash */);
                        animationFinishedCallback.run();
                    } finally {
                    // TODO: This should use pendingTransaction eventually, but right now things
                    // happening on the animation finished callback are happening on the global
                    // transaction.
                        SurfaceControl.mergeToGlobalTransaction(t);
                        SurfaceControl.closeTransaction();
                    }
                });
            }
        };
    }
+27 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import com.android.server.AnimationThread;
import com.android.server.policy.WindowManagerPolicy;

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

/**
 * Singleton class that carries out the animations and Surface operations in a separate task
@@ -87,6 +88,12 @@ public class WindowAnimator {
     */
    private boolean mAnimationFrameCallbackScheduled;

    /**
     * A list of runnable that need to be run after {@link WindowContainer#prepareSurfaces} is
     * executed and the corresponding transaction is closed and applied.
     */
    private final ArrayList<Runnable> mAfterPrepareSurfacesRunnables = new ArrayList<>();

    WindowAnimator(final WindowManagerService service) {
        mService = service;
        mContext = service.mContext;
@@ -262,6 +269,7 @@ public class WindowAnimator {
            mService.destroyPreservedSurfaceLocked();
            mService.mWindowPlacerLocked.destroyPendingSurfaces();

            executeAfterPrepareSurfacesRunnables();

            if (DEBUG_WINDOW_TRACE) {
                Slog.i(TAG, "!!! animate: exit mAnimating=" + mAnimating
@@ -425,4 +433,23 @@ public class WindowAnimator {
    void orAnimating(boolean animating) {
        mAnimating |= animating;
    }

    /**
     * Adds a runnable to be executed after {@link WindowContainer#prepareSurfaces} is called and
     * the corresponding transaction is closed and applied.
     */
    void addAfterPrepareSurfacesRunnable(Runnable r) {
        mAfterPrepareSurfacesRunnables.add(r);
        scheduleAnimation();
    }

    private void executeAfterPrepareSurfacesRunnables() {

        // Traverse in order they were added.
        final int size = mAfterPrepareSurfacesRunnables.size();
        for (int i = 0; i < size; i++) {
            mAfterPrepareSurfacesRunnables.get(i).run();
        }
        mAfterPrepareSurfacesRunnables.clear();
    }
}
+13 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;

/**
 * Test class for {@link SurfaceAnimatorTest}.
@@ -82,6 +83,7 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
        verify(mSpec).startAnimation(any(), any(), callbackCaptor.capture());

        callbackCaptor.getValue().onAnimationFinished(mSpec);
        waitUntilPrepareSurfaces();
        assertNotAnimating(mAnimatable);
        assertTrue(mAnimatable.mFinishedCallbackCalled);
        assertTrue(mAnimatable.mPendingDestroySurfaces.contains(mAnimatable.mLeash));
@@ -104,11 +106,13 @@ public class SurfaceAnimatorTest extends WindowTestsBase {

        // First animation was finished, but this shouldn't cancel the second animation
        callbackCaptor.getValue().onAnimationFinished(mSpec);
        waitUntilPrepareSurfaces();
        assertTrue(mAnimatable.mSurfaceAnimator.isAnimating());

        // Second animation was finished
        verify(mSpec2).startAnimation(any(), any(), callbackCaptor.capture());
        callbackCaptor.getValue().onAnimationFinished(mSpec2);
        waitUntilPrepareSurfaces();
        assertNotAnimating(mAnimatable);
        assertTrue(mAnimatable.mFinishedCallbackCalled);
    }
@@ -160,6 +164,7 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
        assertEquals(leash, mAnimatable2.mSurfaceAnimator.mLeash);
        assertFalse(mAnimatable.mPendingDestroySurfaces.contains(leash));
        callbackCaptor.getValue().onAnimationFinished(mSpec);
        waitUntilPrepareSurfaces();
        assertNotAnimating(mAnimatable2);
        assertTrue(mAnimatable2.mFinishedCallbackCalled);
        assertTrue(mAnimatable2.mPendingDestroySurfaces.contains(leash));
@@ -175,6 +180,14 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
        assertNull(animatable.mSurfaceAnimator.getAnimation());
    }

    private void waitUntilPrepareSurfaces() throws Exception {
        final CountDownLatch latch = new CountDownLatch(1);
        synchronized (sWm.mWindowMap) {
            sWm.mAnimator.addAfterPrepareSurfacesRunnable(latch::countDown);
        }
        latch.await();
    }

    private class MyAnimatable implements Animatable {

        final SurfaceControl mParent;
+1 −0
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ class WindowTestsBase {

        context.getDisplay().getDisplayInfo(mDisplayInfo);
        mDisplayContent = createNewDisplay();
        sWm.mAnimator.mInitialized = true;
        sWm.mDisplayEnabled = true;
        sWm.mDisplayReady = true;