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

Commit 615e4aaa authored by Winson Chung's avatar Winson Chung
Browse files

Cancel running split decor animations before finishing the current resize transition

- One possible flow for this:
  1) play a pending split resize animation with a transition that
     includes a snapshot -> this creates a SplitDecorManager animation
     which directly animates the snapshot leash
  2) have another resize which triggers setup of a new pending resize
     animation -> this cancels the current animation which cleans up/
     releases the existing transition's surfaces, but nothing notifies
     SplitDecorManager, so that animation continues to play
  3) Next frame comes in, SplitDecorManager's animation tries to update
     the surface that has already been released -> crash
- This change just cancels any existing animations (which will remove
  the decor) before creating a new pending resize animation and
  finishing the previous transition

Fixes: 325306101
Test: Presubmit (not reproducible)
Change-Id: Id77f02871bfd684e8dd814b3a38a94e06049e210
parent a9a83eed
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -138,8 +138,10 @@ public class SplitDecorManager extends WindowlessWindowManager {
        mViewHost.setView(rootLayout, lp);
    }

    /** Releases the surfaces for split decor. */
    public void release(SurfaceControl.Transaction t) {
    /**
     * Cancels any currently running animations.
     */
    public void cancelRunningAnimations() {
        if (mFadeAnimator != null) {
            if (mFadeAnimator.isRunning()) {
                mFadeAnimator.cancel();
@@ -152,6 +154,11 @@ public class SplitDecorManager extends WindowlessWindowManager {
            }
            mScreenshotAnimator = null;
        }
    }

    /** Releases the surfaces for split decor. */
    public void release(SurfaceControl.Transaction t) {
        cancelRunningAnimations();
        if (mViewHost != null) {
            mViewHost.release();
            mViewHost = null;
+9 −11
Original line number Diff line number Diff line
@@ -403,25 +403,23 @@ class SplitScreenTransitions {
    IBinder startResizeTransition(WindowContainerTransaction wct,
            Transitions.TransitionHandler handler,
            @Nullable TransitionConsumedCallback consumedCallback,
            @Nullable TransitionFinishedCallback finishCallback) {
            @Nullable TransitionFinishedCallback finishCallback,
            @NonNull SplitDecorManager mainDecor, @NonNull SplitDecorManager sideDecor) {
        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
                "  splitTransition deduced Resize split screen.");
        ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "setResizeTransition: hasPendingResize=%b",
                mPendingResize != null);
        if (mPendingResize != null) {
            mainDecor.cancelRunningAnimations();
            sideDecor.cancelRunningAnimations();
            mPendingResize.cancel(null);
            mAnimations.clear();
            onFinish(null /* wct */);
        }

        IBinder transition = mTransitions.startTransition(TRANSIT_CHANGE, wct, handler);
        setResizeTransition(transition, consumedCallback, finishCallback);
        return transition;
    }

    void setResizeTransition(@NonNull IBinder transition,
            @Nullable TransitionConsumedCallback consumedCallback,
            @Nullable TransitionFinishedCallback finishCallback) {
        mPendingResize = new TransitSession(transition, consumedCallback, finishCallback);
        ProtoLog.v(WM_SHELL_TRANSITIONS, "  splitTransition "
                + " deduced Resize split screen");
        ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "setResizeTransition");
        return transition;
    }

    void mergeAnimation(IBinder transition, TransitionInfo info, SurfaceControl.Transaction t,
+4 −4
Original line number Diff line number Diff line
@@ -2311,7 +2311,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                        mSplitLayout.setDividerInteractive(true, false, "onSplitResizeConsumed");
                    }, (finishWct, t) -> {
                        mSplitLayout.setDividerInteractive(true, false, "onSplitResizeFinish");
            });
                    }, mMainStage.getSplitDecorManager(), mSideStage.getSplitDecorManager());
        } else {
            // Only need screenshot for legacy case because shell transition should screenshot
            // itself during transition.