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

Commit 8d23a78b authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix another animation leak" into pi-dev

parents c63fdfe0 68653abe
Loading
Loading
Loading
Loading
+27 −8
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ class AnimatingAppWindowTokenRegistry {

    private ArrayList<Runnable> mTmpRunnableList = new ArrayList<>();

    private boolean mEndingDeferredFinish;

    /**
     * Notifies that an {@link AppWindowToken} has started animating.
     */
@@ -50,6 +52,11 @@ class AnimatingAppWindowTokenRegistry {
    void notifyFinished(AppWindowToken token) {
        mAnimatingTokens.remove(token);
        mFinishedTokens.remove(token);

        // If we were the last token, make sure the end all deferred finishes.
        if (mAnimatingTokens.isEmpty()) {
            endDeferringFinished();
        }
    }

    /**
@@ -78,8 +85,17 @@ class AnimatingAppWindowTokenRegistry {
    }

    private void endDeferringFinished() {
        // Copy it into a separate temp list to avoid modifying the collection while iterating as
        // calling the callback may call back into notifyFinished.

        // Don't start recursing. Running the finished listener invokes notifyFinished, which may
        // invoked us again.
        if (mEndingDeferredFinish) {
            return;
        }
        try {
            mEndingDeferredFinish = true;

            // Copy it into a separate temp list to avoid modifying the collection while iterating
            // as calling the callback may call back into notifyFinished.
            for (int i = mFinishedTokens.size() - 1; i >= 0; i--) {
                mTmpRunnableList.add(mFinishedTokens.valueAt(i));
            }
@@ -88,6 +104,9 @@ class AnimatingAppWindowTokenRegistry {
                mTmpRunnableList.get(i).run();
            }
            mTmpRunnableList.clear();
        } finally {
            mEndingDeferredFinish = false;
        }
    }

    void dump(PrintWriter pw, String header, String prefix) {
+21 −0
Original line number Diff line number Diff line
@@ -88,4 +88,25 @@ public class AnimatingAppWindowTokenRegistryTest extends WindowTestsBase {
        verify(mMockEndDeferFinishCallback1).run();
        verifyZeroInteractions(mMockEndDeferFinishCallback2);
    }

    @Test
    public void testContainerRemoved() throws Exception {
        final AppWindowToken window1 = createAppWindowToken(mDisplayContent,
                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
        final AppWindowToken window2 = createAppWindow(window1.getTask(), ACTIVITY_TYPE_STANDARD,
                "window2").mAppToken;
        final AnimatingAppWindowTokenRegistry registry =
                window1.getStack().getAnimatingAppWindowTokenRegistry();

        window1.startAnimation(window1.getPendingTransaction(), mAdapter, false /* hidden */);
        window2.startAnimation(window1.getPendingTransaction(), mAdapter, false /* hidden */);
        assertTrue(window1.isSelfAnimating());
        assertTrue(window2.isSelfAnimating());

        // Make sure that first animation finish is deferred, and removing the second window stops
        // finishes all pending deferred finishings.
        registry.notifyAboutToFinish(window1, mMockEndDeferFinishCallback1);
        window2.setParent(null);
        verify(mMockEndDeferFinishCallback1).run();
    }
}