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

Commit 025f8b58 authored by Jeremy Sim's avatar Jeremy Sim Committed by Android (Google) Code Review
Browse files

Merge "Flexible split: mBounds1 and mBounds2" into main

parents a9812d3c fd128546
Loading
Loading
Loading
Loading
+96 −71
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ import com.android.wm.shell.shared.split.SplitScreenConstants.SplitPosition;
import com.android.wm.shell.splitscreen.StageTaskListener;

import java.io.PrintWriter;
import java.util.List;
import java.util.function.Consumer;

/**
@@ -139,15 +140,21 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
    private final Rect mTempRect = new Rect();
    private final Rect mRootBounds = new Rect();
    private final Rect mDividerBounds = new Rect();
    // Bounds1 final position should be always at top or left
    private final Rect mBounds1 = new Rect();
    // Bounds2 final position should be always at bottom or right
    private final Rect mBounds2 = new Rect();
    /**
     * A list of stage bounds, kept in order from top/left to bottom/right. These are the sizes of
     * the app surfaces, not necessarily the same as the size of the rendered content.
     * See {@link #mContentBounds}.
     */
    private final List<Rect> mStageBounds = List.of(new Rect(), new Rect());
    /**
     * A list of app content bounds, kept in order from top/left to bottom/right. These are the
     * sizes of the rendered app contents, not necessarily the same as the size of the drawn app
     * surfaces. See {@link #mStageBounds}.
     */
    private final List<Rect> mContentBounds = List.of(new Rect(), new Rect());
    // The temp bounds outside of display bounds for side stage when split screen inactive to avoid
    // flicker next time active split screen.
    private final Rect mInvisibleBounds = new Rect();
    private final Rect mWinBounds1 = new Rect();
    private final Rect mWinBounds2 = new Rect();
    private final SplitLayoutHandler mSplitLayoutHandler;
    private final SplitWindowManager mSplitWindowManager;
    private final DisplayController mDisplayController;
@@ -233,26 +240,26 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        mDividerWindowWidth = mDividerSize + 2 * mDividerInsets;
    }

    /** Gets bounds of the primary split with screen based coordinate. */
    public Rect getBounds1() {
        return new Rect(mBounds1);
    /** Gets the bounds of the top/left app in screen-based coordinates. */
    public Rect getTopLeftBounds() {
        return mStageBounds.getFirst();
    }

    /** Gets bounds of the primary split with parent based coordinate. */
    public Rect getRefBounds1() {
        Rect outBounds = getBounds1();
        outBounds.offset(-mRootBounds.left, -mRootBounds.top);
        return outBounds;
    /** Gets the bounds of the bottom/right app in screen-based coordinates. */
    public Rect getBottomRightBounds() {
        return mStageBounds.getLast();
    }

    /** Gets bounds of the secondary split with screen based coordinate. */
    public Rect getBounds2() {
        return new Rect(mBounds2);
    /** Gets the bounds of the top/left app in parent-based coordinates. */
    public Rect getTopLeftRefBounds() {
        Rect outBounds = getTopLeftBounds();
        outBounds.offset(-mRootBounds.left, -mRootBounds.top);
        return outBounds;
    }

    /** Gets bounds of the secondary split with parent based coordinate. */
    public Rect getRefBounds2() {
        final Rect outBounds = getBounds2();
    /** Gets the bounds of the bottom/right app in parent-based coordinates. */
    public Rect getBottomRightRefBounds() {
        Rect outBounds = getBottomRightBounds();
        outBounds.offset(-mRootBounds.left, -mRootBounds.top);
        return outBounds;
    }
@@ -274,31 +281,42 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        return outBounds;
    }

    /** Gets bounds of the primary split with screen based coordinate on the param Rect. */
    public void getBounds1(Rect rect) {
        rect.set(mBounds1);
    /** Copies the top/left bounds to the provided Rect (screen-based coordinates). */
    public void copyTopLeftBounds(Rect rect) {
        rect.set(getTopLeftBounds());
    }

    /** Gets bounds of the primary split with parent based coordinate on the param Rect. */
    public void getRefBounds1(Rect rect) {
        getBounds1(rect);
    /** Copies the top/left bounds to the provided Rect (parent-based coordinates). */
    public void copyTopLeftRefBounds(Rect rect) {
        copyTopLeftBounds(rect);
        rect.offset(-mRootBounds.left, -mRootBounds.top);
    }

    /** Gets bounds of the secondary split with screen based coordinate on the param Rect. */
    public void getBounds2(Rect rect) {
        rect.set(mBounds2);
    /** Copies the bottom/right bounds to the provided Rect (screen-based coordinates). */
    public void copyBottomRightBounds(Rect rect) {
        rect.set(getBottomRightBounds());
    }

    /** Gets bounds of the secondary split with parent based coordinate on the param Rect. */
    public void getRefBounds2(Rect rect) {
        getBounds2(rect);
    /** Copies the bottom/right bounds to the provided Rect (parent-based coordinates). */
    public void copyBottomRightRefBounds(Rect rect) {
        copyBottomRightBounds(rect);
        rect.offset(-mRootBounds.left, -mRootBounds.top);
    }

    /** Gets root bounds of the whole split layout on the param Rect. */
    public void getRootBounds(Rect rect) {
        rect.set(mRootBounds);
    /**
     * Gets the content bounds of the top/left app (the bounds of where the app contents would be
     * drawn). Might be larger than the available surface space.
     */
    public Rect getTopLeftContentBounds() {
        return mContentBounds.getFirst();
    }

    /**
     * Gets the content bounds of the bottom/right app (the bounds of where the app contents would
     * be drawn). Might be larger than the available surface space.
     */
    public Rect getBottomRightContentBounds() {
        return mContentBounds.getLast();
    }

    /** Gets bounds of divider window with screen based coordinate on the param Rect. */
@@ -340,8 +358,10 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
     */
    public float getDividerPositionAsFraction() {
        return Math.min(1f, Math.max(0f, mIsLeftRightSplit
                ? (float) ((mBounds1.right + mBounds2.left) / 2f) / mBounds2.right
                : (float) ((mBounds1.bottom + mBounds2.top) / 2f) / mBounds2.bottom));
                ? (float) ((getTopLeftBounds().right + getBottomRightBounds().left) / 2f)
                        / getBottomRightBounds().right
                : (float) ((getTopLeftBounds().bottom + getBottomRightBounds().top) / 2f)
                        / getBottomRightBounds().bottom));
    }

    private void updateInvisibleRect() {
@@ -435,7 +455,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
    }

    private void updateBounds(int position) {
        updateBounds(position, mBounds1, mBounds2, mDividerBounds, true /* setEffectBounds */);
        updateBounds(position, getTopLeftBounds(), getBottomRightBounds(), mDividerBounds,
                true /* setEffectBounds */);
    }

    /** Updates recording bounds of divider window and both of the splits. */
@@ -638,8 +659,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        updateBounds(mDividerPosition);
        mWinToken1 = null;
        mWinToken2 = null;
        mWinBounds1.setEmpty();
        mWinBounds2.setEmpty();
        getTopLeftContentBounds().setEmpty();
        getBottomRightContentBounds().setEmpty();
    }

    /**
@@ -835,7 +856,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
                insets.left != 0 || insets.top != 0 || insets.right != 0 || insets.bottom != 0;

        final int dividerPos = mDividerSnapAlgorithm.calculateNonDismissingSnapTarget(
                mIsLeftRightSplit ? mBounds2.width() : mBounds2.height()).position;
                mIsLeftRightSplit ? getBottomRightBounds().width() : getBottomRightBounds().height()
        ).position;
        final Rect endBounds1 = new Rect();
        final Rect endBounds2 = new Rect();
        final Rect endDividerBounds = new Rect();
@@ -847,12 +869,12 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        endBounds2.offset(-mRootBounds.left, -mRootBounds.top);
        endDividerBounds.offset(-mRootBounds.left, -mRootBounds.top);

        ValueAnimator animator1 = moveSurface(t, topLeftStage, getRefBounds1(), endBounds1,
        ValueAnimator animator1 = moveSurface(t, topLeftStage, getTopLeftRefBounds(), endBounds1,
                -insets.left, -insets.top, true /* roundCorners */, true /* isGoingBehind */,
                shouldVeil);
        ValueAnimator animator2 = moveSurface(t, bottomRightStage, getRefBounds2(), endBounds2,
                insets.left, insets.top, true /* roundCorners */, false /* isGoingBehind */,
                shouldVeil);
        ValueAnimator animator2 = moveSurface(t, bottomRightStage, getBottomRightRefBounds(),
                endBounds2, insets.left, insets.top, true /* roundCorners */,
                false /* isGoingBehind */, shouldVeil);
        ValueAnimator animator3 = moveSurface(t, null /* stage */, getRefDividerBounds(),
                endDividerBounds, 0 /* offsetX */, 0 /* offsetY */, false /* roundCorners */,
                false /* isGoingBehind */, false /* addVeil */);
@@ -1059,10 +1081,10 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
            // Resets layer of divider bar to make sure it is always on top.
            t.setLayer(dividerLeash, Integer.MAX_VALUE);
        }
        getRefBounds1(mTempRect);
        copyTopLeftRefBounds(mTempRect);
        t.setPosition(leash1, mTempRect.left, mTempRect.top)
                .setWindowCrop(leash1, mTempRect.width(), mTempRect.height());
        getRefBounds2(mTempRect);
        copyBottomRightRefBounds(mTempRect);
        t.setPosition(leash2, mTempRect.left, mTempRect.top)
                .setWindowCrop(leash2, mTempRect.width(), mTempRect.height());

@@ -1084,15 +1106,17 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
    public boolean applyTaskChanges(WindowContainerTransaction wct,
            ActivityManager.RunningTaskInfo task1, ActivityManager.RunningTaskInfo task2) {
        boolean boundsChanged = false;
        if (!mBounds1.equals(mWinBounds1) || !task1.token.equals(mWinToken1)) {
            setTaskBounds(wct, task1, mBounds1);
            mWinBounds1.set(mBounds1);
        if (!getTopLeftBounds().equals(getTopLeftContentBounds())
                || !task1.token.equals(mWinToken1)) {
            setTaskBounds(wct, task1, getTopLeftBounds());
            getTopLeftContentBounds().set(getTopLeftBounds());
            mWinToken1 = task1.token;
            boundsChanged = true;
        }
        if (!mBounds2.equals(mWinBounds2) || !task2.token.equals(mWinToken2)) {
            setTaskBounds(wct, task2, mBounds2);
            mWinBounds2.set(mBounds2);
        if (!getBottomRightBounds().equals(getBottomRightContentBounds())
                || !task2.token.equals(mWinToken2)) {
            setTaskBounds(wct, task2, getBottomRightBounds());
            getBottomRightContentBounds().set(getBottomRightBounds());
            mWinToken2 = task2.token;
            boundsChanged = true;
        }
@@ -1129,22 +1153,22 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
    public void applyLayoutOffsetTarget(WindowContainerTransaction wct, int offsetX, int offsetY,
            ActivityManager.RunningTaskInfo taskInfo1, ActivityManager.RunningTaskInfo taskInfo2) {
        if (offsetX == 0 && offsetY == 0) {
            wct.setBounds(taskInfo1.token, mBounds1);
            wct.setBounds(taskInfo1.token, getTopLeftBounds());
            wct.setScreenSizeDp(taskInfo1.token,
                    SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);

            wct.setBounds(taskInfo2.token, mBounds2);
            wct.setBounds(taskInfo2.token, getBottomRightBounds());
            wct.setScreenSizeDp(taskInfo2.token,
                    SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
        } else {
            getBounds1(mTempRect);
            copyTopLeftBounds(mTempRect);
            mTempRect.offset(offsetX, offsetY);
            wct.setBounds(taskInfo1.token, mTempRect);
            wct.setScreenSizeDp(taskInfo1.token,
                    taskInfo1.configuration.screenWidthDp,
                    taskInfo1.configuration.screenHeightDp);

            getBounds2(mTempRect);
            copyBottomRightBounds(mTempRect);
            mTempRect.offset(offsetX, offsetY);
            wct.setBounds(taskInfo2.token, mTempRect);
            wct.setScreenSizeDp(taskInfo2.token,
@@ -1162,9 +1186,9 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        pw.println(innerPrefix + "mFreezeDividerWindow=" + mFreezeDividerWindow);
        pw.println(innerPrefix + "mDimNonImeSide=" + mDimNonImeSide);
        pw.println(innerPrefix + "mDividerPosition=" + mDividerPosition);
        pw.println(innerPrefix + "bounds1=" + mBounds1.toShortString());
        pw.println(innerPrefix + "bounds1=" + getTopLeftBounds().toShortString());
        pw.println(innerPrefix + "dividerBounds=" + mDividerBounds.toShortString());
        pw.println(innerPrefix + "bounds2=" + mBounds2.toShortString());
        pw.println(innerPrefix + "bounds2=" + getBottomRightBounds().toShortString());
    }

    /** Handles layout change event. */
@@ -1274,15 +1298,16 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
            }

            final boolean topLeftShrink = isLeftRightSplit
                    ? position < mWinBounds1.right : position < mWinBounds1.bottom;
                    ? position < getTopLeftContentBounds().right
                    : position < getTopLeftContentBounds().bottom;
            if (topLeftShrink) {
                mShrinkSide = isLeftRightSplit ? DOCKED_LEFT : DOCKED_TOP;
                mContentBounds.set(mWinBounds1);
                mSurfaceBounds.set(mBounds1);
                mContentBounds.set(getTopLeftContentBounds());
                mSurfaceBounds.set(getTopLeftBounds());
            } else {
                mShrinkSide = isLeftRightSplit ? DOCKED_RIGHT : DOCKED_BOTTOM;
                mContentBounds.set(mWinBounds2);
                mSurfaceBounds.set(mBounds2);
                mContentBounds.set(getBottomRightContentBounds());
                mSurfaceBounds.set(getBottomRightBounds());
            }

            if (mDismissingSide != DOCKED_INVALID) {
@@ -1334,12 +1359,12 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
                    case DOCKED_TOP:
                    case DOCKED_LEFT:
                        targetLeash = leash1;
                        mTempRect.set(mBounds1);
                        mTempRect.set(getTopLeftBounds());
                        break;
                    case DOCKED_BOTTOM:
                    case DOCKED_RIGHT:
                        targetLeash = leash2;
                        mTempRect.set(mBounds2);
                        mTempRect.set(getBottomRightBounds());
                        break;
                }
            } else if (mParallaxType == PARALLAX_ALIGN_CENTER) {
@@ -1347,12 +1372,12 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
                    case DOCKED_TOP:
                    case DOCKED_LEFT:
                        targetLeash = leash1;
                        mTempRect.set(mBounds1);
                        mTempRect.set(getTopLeftBounds());
                        break;
                    case DOCKED_BOTTOM:
                    case DOCKED_RIGHT:
                        targetLeash = leash2;
                        mTempRect.set(mBounds2);
                        mTempRect.set(getBottomRightBounds());
                        break;
                }
            }
@@ -1530,7 +1555,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        private int getTargetYOffset() {
            final int desireOffset = Math.abs(mEndImeTop - mStartImeTop);
            // Make sure to keep at least 30% visible for the top split.
            final int maxOffset = (int) (mBounds1.height() * ADJUSTED_SPLIT_FRACTION_MAX);
            final int maxOffset = (int) (getTopLeftBounds().height() * ADJUSTED_SPLIT_FRACTION_MAX);
            return -Math.min(desireOffset, maxOffset);
        }

@@ -1580,11 +1605,11 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
                    t.setPosition(dividerLeash, mTempRect.left, mTempRect.top);
                }

                getRefBounds1(mTempRect);
                copyTopLeftRefBounds(mTempRect);
                mTempRect.offset(0, mYOffsetForIme);
                t.setPosition(leash1, mTempRect.left, mTempRect.top);

                getRefBounds2(mTempRect);
                copyBottomRightRefBounds(mTempRect);
                mTempRect.offset(0, mYOffsetForIme);
                t.setPosition(leash2, mTempRect.left, mTempRect.top);
                adjusted = true;
+17 −14
Original line number Diff line number Diff line
@@ -1709,8 +1709,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
    }

    void getStageBounds(Rect outTopOrLeftBounds, Rect outBottomOrRightBounds) {
        outTopOrLeftBounds.set(mSplitLayout.getBounds1());
        outBottomOrRightBounds.set(mSplitLayout.getBounds2());
        outTopOrLeftBounds.set(mSplitLayout.getTopLeftBounds());
        outBottomOrRightBounds.set(mSplitLayout.getBottomRightBounds());
    }

    private void runForActiveStages(Consumer<StageTaskListener> consumer) {
@@ -1857,8 +1857,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            return;
        }
        mRecentTasks.ifPresent(recentTasks -> {
            Rect topLeftBounds = mSplitLayout.getBounds1();
            Rect bottomRightBounds = mSplitLayout.getBounds2();
            Rect topLeftBounds = new Rect();
            mSplitLayout.copyTopLeftBounds(topLeftBounds);
            Rect bottomRightBounds = new Rect();
            mSplitLayout.copyBottomRightBounds(bottomRightBounds);

            int sideStageTopTaskId;
            int mainStageTopTaskId;
            if (enableFlexibleSplit()) {
@@ -2392,7 +2395,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        boolean updated = layout.applyTaskChanges(wct, topLeftStage.mRootTaskInfo,
                bottomRightStage.mRootTaskInfo);
        ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "updateWindowBounds: topLeftStage=%s bottomRightStage=%s",
                layout.getBounds1(), layout.getBounds2());
                layout.getTopLeftBounds(), layout.getBottomRightBounds());
        return updated;
    }

@@ -2420,7 +2423,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                applyResizingOffset);
        ProtoLog.d(WM_SHELL_SPLIT_SCREEN,
                "updateSurfaceBounds: topLeftStage=%s bottomRightStage=%s",
                layout.getBounds1(), layout.getBounds2());
                layout.getTopLeftBounds(), layout.getBottomRightBounds());
    }

    @Override
@@ -2541,12 +2544,12 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,

    private Rect getSideStageBounds() {
        return mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
                ? mSplitLayout.getBounds1() : mSplitLayout.getBounds2();
                ? mSplitLayout.getTopLeftBounds() : mSplitLayout.getBottomRightBounds();
    }

    private Rect getMainStageBounds() {
        return mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
                ? mSplitLayout.getBounds2() : mSplitLayout.getBounds1();
                ? mSplitLayout.getBottomRightBounds() : mSplitLayout.getTopLeftBounds();
    }

    /**
@@ -2559,11 +2562,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            // Split Layout doesn't actually keep track of the bounds based on the stage,
            // it only knows that bounds1 is leftTop position and bounds2 is bottomRight position
            // We'll then assume this method is to get bounds of bottomRight stage
            mSplitLayout.getBounds2(rect);
            mSplitLayout.copyBottomRightBounds(rect);
        }  else if (mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT) {
            mSplitLayout.getBounds1(rect);
            mSplitLayout.copyTopLeftBounds(rect);
        } else {
            mSplitLayout.getBounds2(rect);
            mSplitLayout.copyBottomRightBounds(rect);
        }
    }

@@ -2577,12 +2580,12 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            // Split Layout doesn't actually keep track of the bounds based on the stage,
            // it only knows that bounds1 is leftTop position and bounds2 is bottomRight position
            // We'll then assume this method is to get bounds of topLeft stage
            mSplitLayout.getBounds1(rect);
            mSplitLayout.copyTopLeftBounds(rect);
        } else {
            if (mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT) {
                mSplitLayout.getBounds2(rect);
                mSplitLayout.copyBottomRightBounds(rect);
            } else {
                mSplitLayout.getBounds1(rect);
                mSplitLayout.copyTopLeftBounds(rect);
            }
        }
    }
+2 −2
Original line number Diff line number Diff line
@@ -53,8 +53,8 @@ public class SplitTestUtils {
        doReturn(dividerBounds).when(out).getDividerBounds();
        doReturn(dividerBounds).when(out).getRefDividerBounds();
        doReturn(leash).when(out).getDividerLeash();
        doReturn(bounds1).when(out).getBounds1();
        doReturn(bounds2).when(out).getBounds2();
        doReturn(bounds1).when(out).getTopLeftBounds();
        doReturn(bounds2).when(out).getBottomRightBounds();
        return out;
    }

+2 −2
Original line number Diff line number Diff line
@@ -141,8 +141,8 @@ public class StageCoordinatorTests extends ShellTestCase {
                Optional.empty()));
        mDividerLeash = new SurfaceControl.Builder().setName("fakeDivider").build();

        when(mSplitLayout.getBounds1()).thenReturn(mBounds1);
        when(mSplitLayout.getBounds2()).thenReturn(mBounds2);
        when(mSplitLayout.getTopLeftBounds()).thenReturn(mBounds1);
        when(mSplitLayout.getBottomRightBounds()).thenReturn(mBounds2);
        when(mSplitLayout.getRootBounds()).thenReturn(mRootBounds);
        when(mSplitLayout.isLeftRightSplit()).thenReturn(false);
        when(mSplitLayout.applyTaskChanges(any(), any(), any())).thenReturn(true);