diff options
| author | 2024-11-19 01:25:24 +0000 | |
|---|---|---|
| committer | 2024-11-19 01:25:24 +0000 | |
| commit | 025f8b58a19ed417351a2fdf01ec8f0e57e90ac8 (patch) | |
| tree | 9144f734931df9af6e39e2e0cb377ef3d7e5ab3e | |
| parent | a9812d3c0f9bf026509631dc3ab6b391b2a697ff (diff) | |
| parent | fd128546245e79fd07b077e630c6a8c367c19a8c (diff) | |
Merge "Flexible split: mBounds1 and mBounds2" into main
4 files changed, 117 insertions, 89 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java index dab30b0f0b96..0f21756bb863 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java @@ -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; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index f07ae4465341..45ecfa95b494 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -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); } } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java index 66dcef6f14cc..d13a8888edc7 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java @@ -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; } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java index 2d102fb27c66..4f6f3c69aa3a 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java @@ -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); |