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

Commit 16d0d07d authored by Chavi Weingarten's avatar Chavi Weingarten Committed by chaviw
Browse files

Fix flicker with remote animations

There was a race condition where we notified the controlling app
already about transition start, which itself started the animation
and applied the transform of the first frame. However, a little
bit later, we applied the pending transaction from window manager,
which overrode the properties again, leading to a flicker.

Original CL: ag/3535475

Test: go/wm-smoke
Test: Press home button, observe never a flicker
Bug: Surprisingly there isn't one yet.

Change-Id: I84b2e0fd4dcd7a01687e18f428a8f900ed43d75f
parent 44c16575
Loading
Loading
Loading
Loading
+11 −7
Original line number Diff line number Diff line
@@ -96,13 +96,17 @@ class RemoteAnimationController {
        // Scale the timeout with the animator scale the controlling app is using.
        mHandler.postDelayed(mTimeoutRunnable,
                (long) (TIMEOUT_MS * mService.getCurrentAnimatorScale()));

        final RemoteAnimationTarget[] animations = createAnimations();
        mService.mAnimator.addAfterPrepareSurfacesRunnable(() -> {
            try {
            mRemoteAnimationAdapter.getRunner().onAnimationStart(createAnimations(),
                mRemoteAnimationAdapter.getRunner().onAnimationStart(animations,
                        mFinishedCallback);
            } catch (RemoteException e) {
                Slog.e(TAG, "Failed to start remote animation", e);
                onAnimationFinished();
            }
        });
    }

    private RemoteAnimationTarget[] createAnimations() {
+2 −0
Original line number Diff line number Diff line
@@ -588,6 +588,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> {
                    "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
        }

        mService.mAnimator.executeAfterPrepareSurfacesRunnables();

        final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked;

        // If we are ready to perform an app transition, check through all of the app tokens to be
+16 −1
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ public class WindowAnimator {
     * executed and the corresponding transaction is closed and applied.
     */
    private final ArrayList<Runnable> mAfterPrepareSurfacesRunnables = new ArrayList<>();
    private boolean mInExecuteAfterPrepareSurfacesRunnables;

    WindowAnimator(final WindowManagerService service) {
        mService = service;
@@ -434,11 +435,24 @@ public class WindowAnimator {
     * the corresponding transaction is closed and applied.
     */
    void addAfterPrepareSurfacesRunnable(Runnable r) {
        // If runnables are already being handled in executeAfterPrepareSurfacesRunnable, then just
        // immediately execute the runnable passed in.
        if (mInExecuteAfterPrepareSurfacesRunnables) {
            r.run();
            return;
        }

        mAfterPrepareSurfacesRunnables.add(r);
        scheduleAnimation();
    }

    private void executeAfterPrepareSurfacesRunnables() {
    void executeAfterPrepareSurfacesRunnables() {

        // Don't even think about to start recursing!
        if (mInExecuteAfterPrepareSurfacesRunnables) {
            return;
        }
        mInExecuteAfterPrepareSurfacesRunnables = true;

        // Traverse in order they were added.
        final int size = mAfterPrepareSurfacesRunnables.size();
@@ -446,5 +460,6 @@ public class WindowAnimator {
            mAfterPrepareSurfacesRunnables.get(i).run();
        }
        mAfterPrepareSurfacesRunnables.clear();
        mInExecuteAfterPrepareSurfacesRunnables = false;
    }
}