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

Commit 0f31aa29 authored by Jerry Chang's avatar Jerry Chang
Browse files

Consolidate leaving split screen to pip mode behavior

Stop always putting another side to the bottom when a splitting task is
entering pip mode. Leave it to onStageHasChildrenChanged to handle, and
prevent expanding non-visible side to the top after dismissed the split
screen, so flows of leaving split to pip like swipe-to-home or launching
another fullscreen app won't expand another side to top unexpectedly.

When swipe-to-home from a split pair, it dismisses split screen.
However, it also performs fling divider to dismiss animation if one side
of the split is empty due to entering pip. Which might be conflicting
with each other and leaves the split layout modified with the fling
animation but not preperly reset divide position. Update to make sure it
always resets divide position and cancel running fling animation after
split screen dismissed.

Fix: 227727673
Test: atest WMShellUnitTests
Test: verify entering pip from split behavior with back-key, home-key
      and launching another fullscreen app.
Video: http://recall/-/fLARJNt42LVxc3tt86SneW/gvATxkQhdJ0APek6RwRHel
       http://recall/-/fLARJNt42LVxc3tt86SneW/QfHt9H0XtDNDSP3h1AA8K
       http://recall/-/fLARJNt42LVxc3tt86SneW/QnbdeWo2007s8ZuMf1Syn

Change-Id: I2c53ed21e4766d06180e670ee21534cd622db081
parent 96c49780
Loading
Loading
Loading
Loading
+17 −6
Original line number Original line Diff line number Diff line
@@ -122,6 +122,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
    private int mDensity;
    private int mDensity;


    private final boolean mDimNonImeSide;
    private final boolean mDimNonImeSide;
    private ValueAnimator mDividerFlingAnimator;


    public SplitLayout(String windowName, Context context, Configuration configuration,
    public SplitLayout(String windowName, Context context, Configuration configuration,
            SplitLayoutHandler splitLayoutHandler,
            SplitLayoutHandler splitLayoutHandler,
@@ -395,6 +396,10 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        mSplitWindowManager.release(t);
        mSplitWindowManager.release(t);
        mDisplayImeController.removePositionProcessor(mImePositionProcessor);
        mDisplayImeController.removePositionProcessor(mImePositionProcessor);
        mImePositionProcessor.reset();
        mImePositionProcessor.reset();
        if (mDividerFlingAnimator != null) {
            mDividerFlingAnimator.cancel();
        }
        resetDividerPosition();
    }
    }


    public void release() {
    public void release() {
@@ -577,13 +582,18 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
                    CUJ_SPLIT_SCREEN_RESIZE);
                    CUJ_SPLIT_SCREEN_RESIZE);
            return;
            return;
        }
        }
        ValueAnimator animator = ValueAnimator

        if (mDividerFlingAnimator != null) {
            mDividerFlingAnimator.cancel();
        }

        mDividerFlingAnimator = ValueAnimator
                .ofInt(from, to)
                .ofInt(from, to)
                .setDuration(duration);
                .setDuration(duration);
        animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
        mDividerFlingAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
        animator.addUpdateListener(
        mDividerFlingAnimator.addUpdateListener(
                animation -> updateDivideBounds((int) animation.getAnimatedValue()));
                animation -> updateDivideBounds((int) animation.getAnimatedValue()));
        animator.addListener(new AnimatorListenerAdapter() {
        mDividerFlingAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            @Override
            public void onAnimationEnd(Animator animation) {
            public void onAnimationEnd(Animator animation) {
                if (flingFinishedCallback != null) {
                if (flingFinishedCallback != null) {
@@ -591,14 +601,15 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
                }
                }
                InteractionJankMonitorUtils.endTracing(
                InteractionJankMonitorUtils.endTracing(
                        CUJ_SPLIT_SCREEN_RESIZE);
                        CUJ_SPLIT_SCREEN_RESIZE);
                mDividerFlingAnimator = null;
            }
            }


            @Override
            @Override
            public void onAnimationCancel(Animator animation) {
            public void onAnimationCancel(Animator animation) {
                setDividePosition(to, true /* applyLayoutChange */);
                mDividerFlingAnimator = null;
            }
            }
        });
        });
        animator.start();
        mDividerFlingAnimator.start();
    }
    }


    /** Switch both surface position with animation. */
    /** Switch both surface position with animation. */
+1 −14
Original line number Original line Diff line number Diff line
@@ -1035,7 +1035,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        mIsDividerRemoteAnimating = false;
        mIsDividerRemoteAnimating = false;


        mSplitLayout.getInvisibleBounds(mTempRect1);
        mSplitLayout.getInvisibleBounds(mTempRect1);
        if (childrenToTop == null) {
        if (childrenToTop == null || childrenToTop.getTopVisibleChildTaskId() == INVALID_TASK_ID) {
            mSideStage.removeAllTasks(wct, false /* toTop */);
            mSideStage.removeAllTasks(wct, false /* toTop */);
            mMainStage.deactivate(wct, false /* toTop */);
            mMainStage.deactivate(wct, false /* toTop */);
            wct.reorder(mRootTaskInfo.token, false /* onTop */);
            wct.reorder(mRootTaskInfo.token, false /* onTop */);
@@ -1294,13 +1294,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        }
        }
    }
    }


    private void onStageChildTaskEnterPip() {
        // When the exit split-screen is caused by one of the task enters auto pip,
        // we want both tasks to be put to bottom instead of top, otherwise it will end up
        // a fullscreen plus a pinned task instead of pinned only at the end of the transition.
        exitSplitScreen(null, EXIT_REASON_CHILD_TASK_ENTER_PIP);
    }

    private void updateRecentTasksSplitPair() {
    private void updateRecentTasksSplitPair() {
        if (!mShouldUpdateRecents) {
        if (!mShouldUpdateRecents) {
            return;
            return;
@@ -2063,7 +2056,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            // Update divider state after animation so that it is still around and positioned
            // Update divider state after animation so that it is still around and positioned
            // properly for the animation itself.
            // properly for the animation itself.
            mSplitLayout.release();
            mSplitLayout.release();
            mSplitLayout.resetDividerPosition();
            mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
            mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
        }
        }
    }
    }
@@ -2339,11 +2331,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            StageCoordinator.this.onStageChildTaskStatusChanged(this, taskId, present, visible);
            StageCoordinator.this.onStageChildTaskStatusChanged(this, taskId, present, visible);
        }
        }


        @Override
        public void onChildTaskEnterPip() {
            StageCoordinator.this.onStageChildTaskEnterPip();
        }

        @Override
        @Override
        public void onRootTaskVanished() {
        public void onRootTaskVanished() {
            reset();
            reset();
+0 −6
Original line number Original line Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.wm.shell.splitscreen;


import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.RemoteAnimationTarget.MODE_OPENING;
import static android.view.RemoteAnimationTarget.MODE_OPENING;


@@ -74,8 +73,6 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {


        void onChildTaskStatusChanged(int taskId, boolean present, boolean visible);
        void onChildTaskStatusChanged(int taskId, boolean present, boolean visible);


        void onChildTaskEnterPip();

        void onRootTaskVanished();
        void onRootTaskVanished();


        void onNoLongerSupportMultiWindow();
        void onNoLongerSupportMultiWindow();
@@ -257,9 +254,6 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
                // Status is managed/synchronized by the transition lifecycle.
                // Status is managed/synchronized by the transition lifecycle.
                return;
                return;
            }
            }
            if (taskInfo.getWindowingMode() == WINDOWING_MODE_PINNED) {
                mCallbacks.onChildTaskEnterPip();
            }
            sendStatusChanged();
            sendStatusChanged();
        } else {
        } else {
            throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo
            throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo