Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +96 −71 Original line number Diff line number Diff line Loading @@ -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; /** Loading Loading @@ -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; Loading Loading @@ -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; } Loading @@ -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. */ Loading Loading @@ -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() { Loading Loading @@ -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. */ Loading Loading @@ -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(); } /** Loading Loading @@ -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(); Loading @@ -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 */); Loading Loading @@ -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()); Loading @@ -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; } Loading Loading @@ -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, Loading @@ -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. */ Loading Loading @@ -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) { Loading Loading @@ -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) { Loading @@ -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; } } Loading Loading @@ -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); } Loading Loading @@ -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; Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +17 −14 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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()) { Loading Loading @@ -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; } Loading Loading @@ -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 Loading Loading @@ -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(); } /** Loading @@ -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); } } Loading @@ -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); } } } Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java +2 −2 Original line number Diff line number Diff line Loading @@ -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; } Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java +2 −2 Original line number Diff line number Diff line Loading @@ -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); Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +96 −71 Original line number Diff line number Diff line Loading @@ -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; /** Loading Loading @@ -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; Loading Loading @@ -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; } Loading @@ -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. */ Loading Loading @@ -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() { Loading Loading @@ -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. */ Loading Loading @@ -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(); } /** Loading Loading @@ -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(); Loading @@ -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 */); Loading Loading @@ -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()); Loading @@ -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; } Loading Loading @@ -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, Loading @@ -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. */ Loading Loading @@ -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) { Loading Loading @@ -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) { Loading @@ -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; } } Loading Loading @@ -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); } Loading Loading @@ -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; Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +17 −14 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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()) { Loading Loading @@ -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; } Loading Loading @@ -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 Loading Loading @@ -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(); } /** Loading @@ -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); } } Loading @@ -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); } } } Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java +2 −2 Original line number Diff line number Diff line Loading @@ -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; } Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java +2 −2 Original line number Diff line number Diff line Loading @@ -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); Loading