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

Commit caca26d9 authored by Jorim Jaggi's avatar Jorim Jaggi Committed by android-build-team Robot
Browse files

Fix issue with animations that couldn't be started

If we can't create a remote animation target for some reason
(removed from task, no main window, etc), SurfaceAnimator
called startAnimation but we never invoke the finish callback.

Thus, we need to make sure to also invoke the finish callback
when not using the AppWindowToken as part of the remote animation.

This actually happens if the main intent clears the task, like
Settings. In that case, it removes all sub activities, which then
get added to mClosingApps, which then are part of a transition.

It's questionable why this would need to happen, but we don't have
the risk budget to go down that rabbit hole.

Test: RemoteAnimationControllerTest
Test: Open Settings -> Network -> Wifi, press home, reopen
Settings, repeat 10x
Test: adb shell dumpsys window -a
Fixes: 76438155
Change-Id: Ib528d5c0d3559eb20522799af68ebbfb17b9801b
(cherry picked from commit b8a9cbe4)
parent 32c71581
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.wm;
import android.util.ArrayMap;
import android.util.ArraySet;

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

/**
@@ -88,4 +89,13 @@ class AnimatingAppWindowTokenRegistry {
        }
        mTmpRunnableList.clear();
    }

    void dump(PrintWriter pw, String header, String prefix) {
        if (!mAnimatingTokens.isEmpty() || !mFinishedTokens.isEmpty()) {
            pw.print(prefix); pw.println(header);
            prefix = prefix + "  ";
            pw.print(prefix); pw.print("mAnimatingTokens="); pw.println(mAnimatingTokens);
            pw.print(prefix); pw.print("mFinishedTokens="); pw.println(mFinishedTokens);
        }
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -134,11 +134,18 @@ class RemoteAnimationController {
    private RemoteAnimationTarget[] createAnimations() {
        final ArrayList<RemoteAnimationTarget> targets = new ArrayList<>();
        for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
            final RemoteAnimationAdapterWrapper wrapper = mPendingAnimations.get(i);
            final RemoteAnimationTarget target =
                    mPendingAnimations.get(i).createRemoteAppAnimation();
            if (target != null) {
                targets.add(target);
            } else {

                // We can't really start an animation but we still need to make sure to finish the
                // pending animation that was started by SurfaceAnimator
                if (wrapper.mCapturedFinishCallback != null) {
                    wrapper.mCapturedFinishCallback.onAnimationFinished(wrapper);
                }
                mPendingAnimations.remove(i);
            }
        }
+1 −0
Original line number Diff line number Diff line
@@ -1387,6 +1387,7 @@ public class TaskStack extends WindowContainer<Task> implements
                token.dump(pw, "    ", dumpAll);
            }
        }
        mAnimatingAppWindowTokenRegistry.dump(pw, "AnimatingApps:", prefix);
    }

    @Override
+12 −0
Original line number Diff line number Diff line
@@ -197,4 +197,16 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
        assertEquals(1, appsCaptor.getValue().length);
        assertEquals(mMockLeash, appsCaptor.getValue()[0].leash);
    }

    @Test
    public void testRemovedBeforeStarted() throws Exception {
        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
        final AnimationAdapter adapter = mController.createAnimationAdapter(win.mAppToken,
                new Point(50, 100), new Rect(50, 100, 150, 150));
        adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
        win.mAppToken.removeImmediately();
        mController.goodToGo();
        verifyZeroInteractions(mMockRunner);
        verify(mFinishedCallback).onAnimationFinished(eq(adapter));
    }
}