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

Commit 68653abe authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Fix another animation leak

Need to make sure to clean up the animations in case one of them
gets removed.

Test: AnimatingAppWindowTokenTest
Change-Id: I6da71679fc95ec67a1359cc8284fde782997fae6
Fixes: 77635513
parent 706fbe7e
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();
    }
}