Loading core/java/android/window/WindowContainerTransaction.java +56 −10 Original line number Diff line number Diff line Loading @@ -295,7 +295,7 @@ public final class WindowContainerTransaction implements Parcelable { } /** * Reparent's all children tasks of {@param currentParent} in the specified * Reparent's all children tasks or the top task of {@param currentParent} in the specified * {@param windowingMode} and {@param activityType} to {@param newParent} in their current * z-order. * Loading @@ -306,20 +306,45 @@ public final class WindowContainerTransaction implements Parcelable { * @param activityTypes of the tasks to reparent. * @param onTop When {@code true}, the child goes to the top of parent; otherwise it goes to * the bottom. * @param reparentTopOnly When {@code true}, only reparent the top task which fit windowingModes * and activityTypes. * @hide */ @NonNull public WindowContainerTransaction reparentTasks(@Nullable WindowContainerToken currentParent, @Nullable WindowContainerToken newParent, @Nullable int[] windowingModes, @Nullable int[] activityTypes, boolean onTop) { @Nullable int[] activityTypes, boolean onTop, boolean reparentTopOnly) { mHierarchyOps.add(HierarchyOp.createForChildrenTasksReparent( currentParent != null ? currentParent.asBinder() : null, newParent != null ? newParent.asBinder() : null, windowingModes, activityTypes, onTop)); onTop, reparentTopOnly)); return this; } /** * Reparent's all children tasks of {@param currentParent} in the specified * {@param windowingMode} and {@param activityType} to {@param newParent} in their current * z-order. * * @param currentParent of the tasks to perform the operation no. * {@code null} will perform the operation on the display. * @param newParent for the tasks. {@code null} will perform the operation on the display. * @param windowingModes of the tasks to reparent. * @param activityTypes of the tasks to reparent. * @param onTop When {@code true}, the child goes to the top of parent; otherwise it goes to * the bottom. */ @NonNull public WindowContainerTransaction reparentTasks(@Nullable WindowContainerToken currentParent, @Nullable WindowContainerToken newParent, @Nullable int[] windowingModes, @Nullable int[] activityTypes, boolean onTop) { return reparentTasks(currentParent, newParent, windowingModes, activityTypes, onTop, false /* reparentTopOnly */); } /** * Sets whether a container should be the launch root for the specified windowing mode and * activity type. This currently only applies to Task containers created by organizer. Loading Loading @@ -948,6 +973,8 @@ public final class WindowContainerTransaction implements Parcelable { // Moves/reparents to top of parent when {@code true}, otherwise moves/reparents to bottom. private boolean mToTop; private boolean mReparentTopOnly; @Nullable private int[] mWindowingModes; Loading Loading @@ -985,13 +1012,15 @@ public final class WindowContainerTransaction implements Parcelable { } public static HierarchyOp createForChildrenTasksReparent(IBinder currentParent, IBinder newParent, int[] windowingModes, int[] activityTypes, boolean onTop) { IBinder newParent, int[] windowingModes, int[] activityTypes, boolean onTop, boolean reparentTopOnly) { return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT) .setContainer(currentParent) .setReparentContainer(newParent) .setWindowingModes(windowingModes) .setActivityTypes(activityTypes) .setToTop(onTop) .setReparentTopOnly(reparentTopOnly) .build(); } Loading Loading @@ -1040,6 +1069,7 @@ public final class WindowContainerTransaction implements Parcelable { mContainer = copy.mContainer; mReparent = copy.mReparent; mToTop = copy.mToTop; mReparentTopOnly = copy.mReparentTopOnly; mWindowingModes = copy.mWindowingModes; mActivityTypes = copy.mActivityTypes; mLaunchOptions = copy.mLaunchOptions; Loading @@ -1053,6 +1083,7 @@ public final class WindowContainerTransaction implements Parcelable { mContainer = in.readStrongBinder(); mReparent = in.readStrongBinder(); mToTop = in.readBoolean(); mReparentTopOnly = in.readBoolean(); mWindowingModes = in.createIntArray(); mActivityTypes = in.createIntArray(); mLaunchOptions = in.readBundle(); Loading Loading @@ -1093,6 +1124,10 @@ public final class WindowContainerTransaction implements Parcelable { return mToTop; } public boolean getReparentTopOnly() { return mReparentTopOnly; } public int[] getWindowingModes() { return mWindowingModes; } Loading Loading @@ -1126,12 +1161,13 @@ public final class WindowContainerTransaction implements Parcelable { switch (mType) { case HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT: return "{ChildrenTasksReparent: from=" + mContainer + " to=" + mReparent + " mToTop=" + mToTop + " mWindowingMode=" + mWindowingModes + " mActivityType=" + mActivityTypes + "}"; + " mToTop=" + mToTop + " mReparentTopOnly=" + mReparentTopOnly + " mWindowingMode=" + Arrays.toString(mWindowingModes) + " mActivityType=" + Arrays.toString(mActivityTypes) + "}"; case HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT: return "{SetLaunchRoot: container=" + mContainer + " mWindowingMode=" + mWindowingModes + " mActivityType=" + mActivityTypes + "}"; + " mWindowingMode=" + Arrays.toString(mWindowingModes) + " mActivityType=" + Arrays.toString(mActivityTypes) + "}"; case HIERARCHY_OP_TYPE_REPARENT: return "{reparent: " + mContainer + " to " + (mToTop ? "top of " : "bottom of ") + mReparent + "}"; Loading Loading @@ -1163,8 +1199,9 @@ public final class WindowContainerTransaction implements Parcelable { + " adjacentContainer=" + mReparent + "}"; default: return "{mType=" + mType + " container=" + mContainer + " reparent=" + mReparent + " mToTop=" + mToTop + " mWindowingMode=" + mWindowingModes + " mActivityType=" + mActivityTypes + "}"; + " mToTop=" + mToTop + " mWindowingMode=" + Arrays.toString(mWindowingModes) + " mActivityType=" + Arrays.toString(mActivityTypes) + "}"; } } Loading @@ -1174,6 +1211,7 @@ public final class WindowContainerTransaction implements Parcelable { dest.writeStrongBinder(mContainer); dest.writeStrongBinder(mReparent); dest.writeBoolean(mToTop); dest.writeBoolean(mReparentTopOnly); dest.writeIntArray(mWindowingModes); dest.writeIntArray(mActivityTypes); dest.writeBundle(mLaunchOptions); Loading Loading @@ -1211,6 +1249,8 @@ public final class WindowContainerTransaction implements Parcelable { private boolean mToTop; private boolean mReparentTopOnly; @Nullable private int[] mWindowingModes; Loading Loading @@ -1248,6 +1288,11 @@ public final class WindowContainerTransaction implements Parcelable { return this; } Builder setReparentTopOnly(boolean reparentTopOnly) { mReparentTopOnly = reparentTopOnly; return this; } Builder setWindowingModes(@Nullable int[] windowingModes) { mWindowingModes = windowingModes; return this; Loading Loading @@ -1290,6 +1335,7 @@ public final class WindowContainerTransaction implements Parcelable { ? Arrays.copyOf(mActivityTypes, mActivityTypes.length) : null; hierarchyOp.mToTop = mToTop; hierarchyOp.mReparentTopOnly = mReparentTopOnly; hierarchyOp.mLaunchOptions = mLaunchOptions; hierarchyOp.mActivityIntent = mActivityIntent; hierarchyOp.mPendingIntent = mPendingIntent; Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java +10 −11 Original line number Diff line number Diff line Loading @@ -49,25 +49,24 @@ class MainStage extends StageTaskListener { return mIsActive; } void activate(Rect rootBounds, WindowContainerTransaction wct) { void activate(Rect rootBounds, WindowContainerTransaction wct, boolean includingTopTask) { if (mIsActive) return; final WindowContainerToken rootToken = mRootTaskInfo.token; wct.setBounds(rootToken, rootBounds) .setWindowingMode(rootToken, WINDOWING_MODE_MULTI_WINDOW) .setLaunchRoot( rootToken, CONTROLLED_WINDOWING_MODES, CONTROLLED_ACTIVITY_TYPES) .reparentTasks( // Moving the root task to top after the child tasks were re-parented , or the root // task cannot be visible and focused. .reorder(rootToken, true /* onTop */); if (includingTopTask) { wct.reparentTasks( null /* currentParent */, rootToken, CONTROLLED_WINDOWING_MODES, CONTROLLED_ACTIVITY_TYPES, true /* onTop */) // Moving the root task to top after the child tasks were re-parented , or the root // task cannot be visible and focused. .reorder(rootToken, true /* onTop */); true /* onTop */, true /* reparentTopOnly */); } mIsActive = true; } Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +4 −4 Original line number Diff line number Diff line Loading @@ -263,7 +263,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, @SplitPosition int sideStagePosition) { final WindowContainerTransaction wct = new WindowContainerTransaction(); setSideStagePosition(sideStagePosition, wct); mMainStage.activate(getMainStageBounds(), wct); mMainStage.activate(getMainStageBounds(), wct, true /* reparent */); mSideStage.addTask(task, getSideStageBounds(), wct); mSyncQueue.queue(wct); mSyncQueue.runInSync(t -> updateSurfaceBounds(null /* layout */, t)); Loading Loading @@ -299,7 +299,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, // Build a request WCT that will launch both apps such that task 0 is on the main stage // while task 1 is on the side stage. mMainStage.activate(getMainStageBounds(), wct); mMainStage.activate(getMainStageBounds(), wct, false /* reparent */); mSideStage.setBounds(getSideStageBounds(), wct); // Make sure the launch options will put tasks in the corresponding split roots Loading Loading @@ -368,7 +368,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, // Build a request WCT that will launch both apps such that task 0 is on the main stage // while task 1 is on the side stage. mMainStage.activate(getMainStageBounds(), wct); mMainStage.activate(getMainStageBounds(), wct, false /* reparent */); mSideStage.setBounds(getSideStageBounds(), wct); // Make sure the launch options will put tasks in the corresponding split roots Loading Loading @@ -756,7 +756,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, } else if (isSideStage) { final WindowContainerTransaction wct = new WindowContainerTransaction(); // Make sure the main stage is active. mMainStage.activate(getMainStageBounds(), wct); mMainStage.activate(getMainStageBounds(), wct, true /* reparent */); mSideStage.setBounds(getSideStageBounds(), wct); mTaskOrganizer.applyTransaction(wct); } Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/MainStageTests.java +2 −1 Original line number Diff line number Diff line Loading @@ -62,7 +62,8 @@ public class MainStageTests { @Test public void testActiveDeactivate() { mMainStage.activate(mRootTaskInfo.configuration.windowConfiguration.getBounds(), mWct); mMainStage.activate(mRootTaskInfo.configuration.windowConfiguration.getBounds(), mWct, true /* reparent */); assertThat(mMainStage.isActive()).isTrue(); mMainStage.deactivate(mWct); Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java +2 −1 Original line number Diff line number Diff line Loading @@ -316,7 +316,8 @@ public class SplitTransitionTests extends ShellTestCase { mock(SurfaceControl.Transaction.class), mock(SurfaceControl.Transaction.class), mock(Transitions.TransitionFinishCallback.class)); mMainStage.activate(new Rect(0, 0, 100, 100), new WindowContainerTransaction()); mMainStage.activate(new Rect(0, 0, 100, 100), new WindowContainerTransaction(), true /* includingTopTask */); } private boolean containsSplitExit(@NonNull WindowContainerTransaction wct) { Loading Loading
core/java/android/window/WindowContainerTransaction.java +56 −10 Original line number Diff line number Diff line Loading @@ -295,7 +295,7 @@ public final class WindowContainerTransaction implements Parcelable { } /** * Reparent's all children tasks of {@param currentParent} in the specified * Reparent's all children tasks or the top task of {@param currentParent} in the specified * {@param windowingMode} and {@param activityType} to {@param newParent} in their current * z-order. * Loading @@ -306,20 +306,45 @@ public final class WindowContainerTransaction implements Parcelable { * @param activityTypes of the tasks to reparent. * @param onTop When {@code true}, the child goes to the top of parent; otherwise it goes to * the bottom. * @param reparentTopOnly When {@code true}, only reparent the top task which fit windowingModes * and activityTypes. * @hide */ @NonNull public WindowContainerTransaction reparentTasks(@Nullable WindowContainerToken currentParent, @Nullable WindowContainerToken newParent, @Nullable int[] windowingModes, @Nullable int[] activityTypes, boolean onTop) { @Nullable int[] activityTypes, boolean onTop, boolean reparentTopOnly) { mHierarchyOps.add(HierarchyOp.createForChildrenTasksReparent( currentParent != null ? currentParent.asBinder() : null, newParent != null ? newParent.asBinder() : null, windowingModes, activityTypes, onTop)); onTop, reparentTopOnly)); return this; } /** * Reparent's all children tasks of {@param currentParent} in the specified * {@param windowingMode} and {@param activityType} to {@param newParent} in their current * z-order. * * @param currentParent of the tasks to perform the operation no. * {@code null} will perform the operation on the display. * @param newParent for the tasks. {@code null} will perform the operation on the display. * @param windowingModes of the tasks to reparent. * @param activityTypes of the tasks to reparent. * @param onTop When {@code true}, the child goes to the top of parent; otherwise it goes to * the bottom. */ @NonNull public WindowContainerTransaction reparentTasks(@Nullable WindowContainerToken currentParent, @Nullable WindowContainerToken newParent, @Nullable int[] windowingModes, @Nullable int[] activityTypes, boolean onTop) { return reparentTasks(currentParent, newParent, windowingModes, activityTypes, onTop, false /* reparentTopOnly */); } /** * Sets whether a container should be the launch root for the specified windowing mode and * activity type. This currently only applies to Task containers created by organizer. Loading Loading @@ -948,6 +973,8 @@ public final class WindowContainerTransaction implements Parcelable { // Moves/reparents to top of parent when {@code true}, otherwise moves/reparents to bottom. private boolean mToTop; private boolean mReparentTopOnly; @Nullable private int[] mWindowingModes; Loading Loading @@ -985,13 +1012,15 @@ public final class WindowContainerTransaction implements Parcelable { } public static HierarchyOp createForChildrenTasksReparent(IBinder currentParent, IBinder newParent, int[] windowingModes, int[] activityTypes, boolean onTop) { IBinder newParent, int[] windowingModes, int[] activityTypes, boolean onTop, boolean reparentTopOnly) { return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT) .setContainer(currentParent) .setReparentContainer(newParent) .setWindowingModes(windowingModes) .setActivityTypes(activityTypes) .setToTop(onTop) .setReparentTopOnly(reparentTopOnly) .build(); } Loading Loading @@ -1040,6 +1069,7 @@ public final class WindowContainerTransaction implements Parcelable { mContainer = copy.mContainer; mReparent = copy.mReparent; mToTop = copy.mToTop; mReparentTopOnly = copy.mReparentTopOnly; mWindowingModes = copy.mWindowingModes; mActivityTypes = copy.mActivityTypes; mLaunchOptions = copy.mLaunchOptions; Loading @@ -1053,6 +1083,7 @@ public final class WindowContainerTransaction implements Parcelable { mContainer = in.readStrongBinder(); mReparent = in.readStrongBinder(); mToTop = in.readBoolean(); mReparentTopOnly = in.readBoolean(); mWindowingModes = in.createIntArray(); mActivityTypes = in.createIntArray(); mLaunchOptions = in.readBundle(); Loading Loading @@ -1093,6 +1124,10 @@ public final class WindowContainerTransaction implements Parcelable { return mToTop; } public boolean getReparentTopOnly() { return mReparentTopOnly; } public int[] getWindowingModes() { return mWindowingModes; } Loading Loading @@ -1126,12 +1161,13 @@ public final class WindowContainerTransaction implements Parcelable { switch (mType) { case HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT: return "{ChildrenTasksReparent: from=" + mContainer + " to=" + mReparent + " mToTop=" + mToTop + " mWindowingMode=" + mWindowingModes + " mActivityType=" + mActivityTypes + "}"; + " mToTop=" + mToTop + " mReparentTopOnly=" + mReparentTopOnly + " mWindowingMode=" + Arrays.toString(mWindowingModes) + " mActivityType=" + Arrays.toString(mActivityTypes) + "}"; case HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT: return "{SetLaunchRoot: container=" + mContainer + " mWindowingMode=" + mWindowingModes + " mActivityType=" + mActivityTypes + "}"; + " mWindowingMode=" + Arrays.toString(mWindowingModes) + " mActivityType=" + Arrays.toString(mActivityTypes) + "}"; case HIERARCHY_OP_TYPE_REPARENT: return "{reparent: " + mContainer + " to " + (mToTop ? "top of " : "bottom of ") + mReparent + "}"; Loading Loading @@ -1163,8 +1199,9 @@ public final class WindowContainerTransaction implements Parcelable { + " adjacentContainer=" + mReparent + "}"; default: return "{mType=" + mType + " container=" + mContainer + " reparent=" + mReparent + " mToTop=" + mToTop + " mWindowingMode=" + mWindowingModes + " mActivityType=" + mActivityTypes + "}"; + " mToTop=" + mToTop + " mWindowingMode=" + Arrays.toString(mWindowingModes) + " mActivityType=" + Arrays.toString(mActivityTypes) + "}"; } } Loading @@ -1174,6 +1211,7 @@ public final class WindowContainerTransaction implements Parcelable { dest.writeStrongBinder(mContainer); dest.writeStrongBinder(mReparent); dest.writeBoolean(mToTop); dest.writeBoolean(mReparentTopOnly); dest.writeIntArray(mWindowingModes); dest.writeIntArray(mActivityTypes); dest.writeBundle(mLaunchOptions); Loading Loading @@ -1211,6 +1249,8 @@ public final class WindowContainerTransaction implements Parcelable { private boolean mToTop; private boolean mReparentTopOnly; @Nullable private int[] mWindowingModes; Loading Loading @@ -1248,6 +1288,11 @@ public final class WindowContainerTransaction implements Parcelable { return this; } Builder setReparentTopOnly(boolean reparentTopOnly) { mReparentTopOnly = reparentTopOnly; return this; } Builder setWindowingModes(@Nullable int[] windowingModes) { mWindowingModes = windowingModes; return this; Loading Loading @@ -1290,6 +1335,7 @@ public final class WindowContainerTransaction implements Parcelable { ? Arrays.copyOf(mActivityTypes, mActivityTypes.length) : null; hierarchyOp.mToTop = mToTop; hierarchyOp.mReparentTopOnly = mReparentTopOnly; hierarchyOp.mLaunchOptions = mLaunchOptions; hierarchyOp.mActivityIntent = mActivityIntent; hierarchyOp.mPendingIntent = mPendingIntent; Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java +10 −11 Original line number Diff line number Diff line Loading @@ -49,25 +49,24 @@ class MainStage extends StageTaskListener { return mIsActive; } void activate(Rect rootBounds, WindowContainerTransaction wct) { void activate(Rect rootBounds, WindowContainerTransaction wct, boolean includingTopTask) { if (mIsActive) return; final WindowContainerToken rootToken = mRootTaskInfo.token; wct.setBounds(rootToken, rootBounds) .setWindowingMode(rootToken, WINDOWING_MODE_MULTI_WINDOW) .setLaunchRoot( rootToken, CONTROLLED_WINDOWING_MODES, CONTROLLED_ACTIVITY_TYPES) .reparentTasks( // Moving the root task to top after the child tasks were re-parented , or the root // task cannot be visible and focused. .reorder(rootToken, true /* onTop */); if (includingTopTask) { wct.reparentTasks( null /* currentParent */, rootToken, CONTROLLED_WINDOWING_MODES, CONTROLLED_ACTIVITY_TYPES, true /* onTop */) // Moving the root task to top after the child tasks were re-parented , or the root // task cannot be visible and focused. .reorder(rootToken, true /* onTop */); true /* onTop */, true /* reparentTopOnly */); } mIsActive = true; } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +4 −4 Original line number Diff line number Diff line Loading @@ -263,7 +263,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, @SplitPosition int sideStagePosition) { final WindowContainerTransaction wct = new WindowContainerTransaction(); setSideStagePosition(sideStagePosition, wct); mMainStage.activate(getMainStageBounds(), wct); mMainStage.activate(getMainStageBounds(), wct, true /* reparent */); mSideStage.addTask(task, getSideStageBounds(), wct); mSyncQueue.queue(wct); mSyncQueue.runInSync(t -> updateSurfaceBounds(null /* layout */, t)); Loading Loading @@ -299,7 +299,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, // Build a request WCT that will launch both apps such that task 0 is on the main stage // while task 1 is on the side stage. mMainStage.activate(getMainStageBounds(), wct); mMainStage.activate(getMainStageBounds(), wct, false /* reparent */); mSideStage.setBounds(getSideStageBounds(), wct); // Make sure the launch options will put tasks in the corresponding split roots Loading Loading @@ -368,7 +368,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, // Build a request WCT that will launch both apps such that task 0 is on the main stage // while task 1 is on the side stage. mMainStage.activate(getMainStageBounds(), wct); mMainStage.activate(getMainStageBounds(), wct, false /* reparent */); mSideStage.setBounds(getSideStageBounds(), wct); // Make sure the launch options will put tasks in the corresponding split roots Loading Loading @@ -756,7 +756,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, } else if (isSideStage) { final WindowContainerTransaction wct = new WindowContainerTransaction(); // Make sure the main stage is active. mMainStage.activate(getMainStageBounds(), wct); mMainStage.activate(getMainStageBounds(), wct, true /* reparent */); mSideStage.setBounds(getSideStageBounds(), wct); mTaskOrganizer.applyTransaction(wct); } Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/MainStageTests.java +2 −1 Original line number Diff line number Diff line Loading @@ -62,7 +62,8 @@ public class MainStageTests { @Test public void testActiveDeactivate() { mMainStage.activate(mRootTaskInfo.configuration.windowConfiguration.getBounds(), mWct); mMainStage.activate(mRootTaskInfo.configuration.windowConfiguration.getBounds(), mWct, true /* reparent */); assertThat(mMainStage.isActive()).isTrue(); mMainStage.deactivate(mWct); Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java +2 −1 Original line number Diff line number Diff line Loading @@ -316,7 +316,8 @@ public class SplitTransitionTests extends ShellTestCase { mock(SurfaceControl.Transaction.class), mock(SurfaceControl.Transaction.class), mock(Transitions.TransitionFinishCallback.class)); mMainStage.activate(new Rect(0, 0, 100, 100), new WindowContainerTransaction()); mMainStage.activate(new Rect(0, 0, 100, 100), new WindowContainerTransaction(), true /* includingTopTask */); } private boolean containsSplitExit(@NonNull WindowContainerTransaction wct) { Loading