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

Commit 6814d301 authored by Simon (Qiong) Sun's avatar Simon (Qiong) Sun
Browse files

Clean up Split Decor on aborted resizing transition

The Split resizing transition could be aborted, for example, when a foldable device is locked while transitioning between folded and unfolded states. This change cleans up the Split Decor in onTransitionConsumed when the transition is aborted to ensure it's released correctly, preventing leaks.

This fix addresses a bug where the Split Decor would not be cleaned up properly, resulting in a persistent veil overlay.

Bug: 438464320
Flag: EXEMPT bug fix
Test: 1. Unfold a foldable device and pin the taskbar. 2. Split two apps at a 10:90 ratio. 3. Fold the device. 4. Unfold the device and verify that the veil overlay has disappeared. 5. Repeat this process multiple times to ensure the issue is consistently resolved.
Change-Id: I041f8baa9d9036e64cccde08147b6aec793883df
parent 1f332672
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -667,7 +667,7 @@ public class SplitDecorManager extends WindowlessWindowManager {
    }

    /** Release or hide decor hint. */
    private void releaseDecor(SurfaceControl.Transaction t) {
    public void releaseDecor(SurfaceControl.Transaction t) {
        if (mBackgroundLeash != null) {
            t.remove(mBackgroundLeash);
            mBackgroundLeash = null;
+9 −16
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;

import static com.android.wm.shell.Flags.enableFlexibleSplit;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TRANSITIONS;
import static com.android.wm.shell.shared.animation.Interpolators.ALPHA_IN;
@@ -446,7 +445,6 @@ class SplitScreenTransitions {
            Transitions.TransitionHandler handler,
            @Nullable TransitionConsumedCallback consumedCallback,
            @Nullable TransitionFinishedCallback finishCallback,
            @Nullable SplitDecorManager mainDecor, @Nullable SplitDecorManager sideDecor,
            @Nullable List<SplitDecorManager> decorManagers) {
        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
                "  splitTransition deduced Resize split screen.");
@@ -454,14 +452,9 @@ class SplitScreenTransitions {
                mPendingResize != null);
        if (mPendingResize != null) {
            mPendingResize.cancel(null);
            if (enableFlexibleSplit()) {
            for (SplitDecorManager stage : decorManagers) {
                stage.cancelRunningAnimations();
            }
            } else {
                mainDecor.cancelRunningAnimations();
                sideDecor.cancelRunningAnimations();
            }
            mAnimations.clear();
            onFinish(null /* wct */);
        }
@@ -506,20 +499,20 @@ class SplitScreenTransitions {
                mStageCoordinator.finishEnterSplitScreen(finishT);
            }

            mPendingEnter.onConsumed(aborted);
            mPendingEnter.onConsumed(aborted, finishT);
            mPendingEnter = null;
            mStageCoordinator.notifySplitAnimationStatus(false /*animationRunning*/);
            ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTransitionConsumed for enter transition");
        } else if (isPendingDismiss(transition)) {
            mPendingDismiss.onConsumed(aborted);
            mPendingDismiss.onConsumed(aborted, finishT);
            mPendingDismiss = null;
            ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTransitionConsumed for dismiss transition");
        } else if (isPendingResize(transition)) {
            mPendingResize.onConsumed(aborted);
            mPendingResize.onConsumed(aborted, finishT);
            mPendingResize = null;
            ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTransitionConsumed for resize transition");
        } else if (isPendingPassThrough(transition)) {
            mPendingRemotePassthrough.onConsumed(aborted);
            mPendingRemotePassthrough.onConsumed(aborted, finishT);
            mPendingRemotePassthrough.mRemoteHandler.onTransitionConsumed(transition, aborted,
                    finishT);
            mPendingRemotePassthrough = null;
@@ -602,7 +595,7 @@ class SplitScreenTransitions {

    /** Calls when the transition got consumed. */
    interface TransitionConsumedCallback {
        void onConsumed(boolean aborted);
        void onConsumed(boolean aborted, SurfaceControl.Transaction t);
    }

    /** Calls when the transition finished. */
@@ -668,9 +661,9 @@ class SplitScreenTransitions {
            setFinishedCallback(finishedCb);
        }

        void onConsumed(boolean aborted) {
        void onConsumed(boolean aborted, SurfaceControl.Transaction finishT) {
            if (mConsumedCallback != null) {
                mConsumedCallback.onConsumed(aborted);
                mConsumedCallback.onConsumed(aborted, finishT);
            }
        }

+15 −7
Original line number Diff line number Diff line
@@ -2906,25 +2906,33 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            mTransactionPool.release(t);
            return;
        }
        List<SplitDecorManager> decorManagers = new ArrayList<>();
        SplitDecorManager mainDecor = null;
        SplitDecorManager sideDecor = null;
        final List<SplitDecorManager> decorManagers;
        if (enableFlexibleSplit()) {
            decorManagers = mStageOrderOperator.getActiveStages().stream()
                    .map(StageTaskListener::getSplitDecorManager)
                    .toList();
        } else {
            mainDecor = mMainStage.getSplitDecorManager();
            sideDecor = mSideStage.getSplitDecorManager();
            decorManagers = new ArrayList<>();
            final SplitDecorManager mainDecor = mMainStage.getSplitDecorManager();
            final SplitDecorManager sideDecor = mSideStage.getSplitDecorManager();
            if (mainDecor != null) {
                decorManagers.add(mainDecor);
            }
            if (sideDecor != null) {
                decorManagers.add(sideDecor);
            }
        }
        sendOnBoundsChanged();
        mSplitLayout.setDividerInteractive(false, false, "onSplitResizeStart");
        mSplitTransitions.startResizeTransition(wct, this, (aborted) -> {
        mSplitTransitions.startResizeTransition(wct, this, (aborted, finishT) -> {
            mSplitLayout.setDividerInteractive(true, false, "onSplitResizeConsumed");
            for (SplitDecorManager decor : decorManagers) {
                decor.releaseDecor(finishT);
            }
        }, (finishWct, t) -> {
            mSplitLayout.setDividerInteractive(true, false, "onSplitResizeFinish");
            mSplitLayout.populateTouchZones();
        }, mainDecor, sideDecor, decorManagers);
        }, decorManagers);

        if (enableFlexibleTwoAppSplit()) {
            switch (layout.calculateCurrentSnapPosition()) {