Loading core/java/android/window/WindowContainerTransaction.java +95 −20 Original line number Diff line number Diff line Loading @@ -486,7 +486,7 @@ public final class WindowContainerTransaction implements Parcelable { } /** * Sets to containers adjacent to each other. Containers below two visible adjacent roots will * Sets two containers adjacent to each other. Containers below two visible adjacent roots will * be made invisible. This currently only applies to TaskFragment containers created by * organizer. * @param root1 the first root. Loading @@ -495,11 +495,66 @@ public final class WindowContainerTransaction implements Parcelable { @NonNull public WindowContainerTransaction setAdjacentRoots( @NonNull WindowContainerToken root1, @NonNull WindowContainerToken root2) { if (!Flags.allowMultipleAdjacentTaskFragments()) { mHierarchyOps.add(HierarchyOp.createForAdjacentRoots( root1.asBinder(), root2.asBinder())); return this; } return setAdjacentRootSet(root1, root2); } /** * Sets multiple containers adjacent to each other. Containers below the visible adjacent roots * will be made invisible. This currently only applies to Task containers created by organizer. * * To remove one container from the adjacent roots, one can call {@link #clearAdjacentRoots} * with the target container. * To remove all containers from the adjacent roots, one much call {@link #clearAdjacentRoots} * on each container if there were more than two containers in the set. * * For non-Task TaskFragment, use {@link #setAdjacentTaskFragments} instead. * * @param roots the Tasks that should be adjacent to each other. * @throws IllegalArgumentException if roots have size < 2. * @hide // TODO(b/373709676) Rename to setAdjacentRoots and update CTS. */ @NonNull public WindowContainerTransaction setAdjacentRootSet( @NonNull WindowContainerToken... roots) { if (!Flags.allowMultipleAdjacentTaskFragments()) { throw new IllegalArgumentException("allowMultipleAdjacentTaskFragments is not enabled." + " Use #setAdjacentRoots instead."); } if (roots.length < 2) { throw new IllegalArgumentException("setAdjacentRootSet must have size >= 2"); } final IBinder[] rootTokens = new IBinder[roots.length]; for (int i = 0; i < roots.length; i++) { rootTokens[i] = roots[i].asBinder(); } mHierarchyOps.add( new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS) .setContainers(rootTokens) .build()); return this; } /** * Clears container adjacent. * If {@link #setAdjacentRootSet} is called with more than 2 roots, calling this will only * remove the given root from the adjacent set. The rest of roots will stay adjacent to each * other. * * @param root the root container to clear the adjacent roots for. * @hide */ @NonNull public WindowContainerTransaction clearAdjacentRoots( @NonNull WindowContainerToken root) { mHierarchyOps.add(HierarchyOp.createForClearAdjacentRoots(root.asBinder())); return this; } /** * Sets the container as launch adjacent flag root. Task starting with Loading Loading @@ -966,18 +1021,6 @@ public final class WindowContainerTransaction implements Parcelable { return this; } /** * Clears container adjacent. * @param root the root container to clear the adjacent roots for. * @hide */ @NonNull public WindowContainerTransaction clearAdjacentRoots( @NonNull WindowContainerToken root) { mHierarchyOps.add(HierarchyOp.createForClearAdjacentRoots(root.asBinder())); return this; } /** * Sets/removes the reparent leaf task flag for this {@code windowContainer}. * When this is set, the server side will try to reparent the leaf task to task display area Loading Loading @@ -1520,6 +1563,9 @@ public final class WindowContainerTransaction implements Parcelable { @Nullable private IBinder mContainer; @Nullable private IBinder[] mContainers; // If this is same as mContainer, then only change position, don't reparent. @Nullable private IBinder mReparent; Loading Loading @@ -1704,6 +1750,7 @@ public final class WindowContainerTransaction implements Parcelable { public HierarchyOp(@NonNull HierarchyOp copy) { mType = copy.mType; mContainer = copy.mContainer; mContainers = copy.mContainers; mBounds = copy.mBounds; mIncludingParents = copy.mIncludingParents; mReparent = copy.mReparent; Loading @@ -1729,6 +1776,7 @@ public final class WindowContainerTransaction implements Parcelable { protected HierarchyOp(Parcel in) { mType = in.readInt(); mContainer = in.readStrongBinder(); mContainers = in.createBinderArray(); mBounds = in.readTypedObject(Rect.CREATOR); mIncludingParents = in.readBoolean(); mReparent = in.readStrongBinder(); Loading Loading @@ -1779,6 +1827,13 @@ public final class WindowContainerTransaction implements Parcelable { return mContainer; } @NonNull public IBinder[] getContainers() { return mContainers; } /** @deprecated b/373709676 replace with {@link #getContainers()}. */ @Deprecated @NonNull public IBinder getAdjacentRoot() { return mReparent; Loading Loading @@ -1869,7 +1924,7 @@ public final class WindowContainerTransaction implements Parcelable { case HIERARCHY_OP_TYPE_REORDER: return "reorder"; case HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT: return "childrenTasksReparent"; case HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT: return "setLaunchRoot"; case HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS: return "setAdjacentRoot"; case HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS: return "setAdjacentRoots"; case HIERARCHY_OP_TYPE_LAUNCH_TASK: return "launchTask"; case HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT: return "setAdjacentFlagRoot"; case HIERARCHY_OP_TYPE_SET_DISABLE_LAUNCH_ADJACENT: Loading @@ -1883,7 +1938,7 @@ public final class WindowContainerTransaction implements Parcelable { case HIERARCHY_OP_TYPE_SET_ALWAYS_ON_TOP: return "setAlwaysOnTop"; case HIERARCHY_OP_TYPE_REMOVE_TASK: return "removeTask"; case HIERARCHY_OP_TYPE_FINISH_ACTIVITY: return "finishActivity"; case HIERARCHY_OP_TYPE_CLEAR_ADJACENT_ROOTS: return "clearAdjacentRoot"; case HIERARCHY_OP_TYPE_CLEAR_ADJACENT_ROOTS: return "clearAdjacentRoots"; case HIERARCHY_OP_TYPE_SET_REPARENT_LEAF_TASK_IF_RELAUNCH: return "setReparentLeafTaskIfRelaunch"; case HIERARCHY_OP_TYPE_ADD_TASK_FRAGMENT_OPERATION: Loading Loading @@ -1923,8 +1978,18 @@ public final class WindowContainerTransaction implements Parcelable { sb.append(mContainer).append(" to ").append(mToTop ? "top" : "bottom"); break; case HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS: if (Flags.allowMultipleAdjacentTaskFragments()) { for (IBinder container : mContainers) { if (container == mContainers[0]) { sb.append("adjacentRoots=").append(container); } else { sb.append(", ").append(container); } } } else { sb.append("container=").append(mContainer) .append(" adjacentRoot=").append(mReparent); } break; case HIERARCHY_OP_TYPE_LAUNCH_TASK: sb.append(mLaunchOptions); Loading Loading @@ -1997,6 +2062,7 @@ public final class WindowContainerTransaction implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mType); dest.writeStrongBinder(mContainer); dest.writeBinderArray(mContainers); dest.writeTypedObject(mBounds, flags); dest.writeBoolean(mIncludingParents); dest.writeStrongBinder(mReparent); Loading Loading @@ -2043,6 +2109,9 @@ public final class WindowContainerTransaction implements Parcelable { @Nullable private IBinder mContainer; @Nullable private IBinder[] mContainers; @Nullable private IBinder mReparent; Loading Loading @@ -2104,6 +2173,11 @@ public final class WindowContainerTransaction implements Parcelable { return this; } Builder setContainers(@Nullable IBinder[] containers) { mContainers = containers; return this; } Builder setReparentContainer(@Nullable IBinder reparentContainer) { mReparent = reparentContainer; return this; Loading Loading @@ -2209,6 +2283,7 @@ public final class WindowContainerTransaction implements Parcelable { HierarchyOp build() { final HierarchyOp hierarchyOp = new HierarchyOp(mType); hierarchyOp.mContainer = mContainer; hierarchyOp.mContainers = mContainers; hierarchyOp.mReparent = mReparent; hierarchyOp.mWindowingModes = mWindowingModes != null ? Arrays.copyOf(mWindowingModes, mWindowingModes.length) Loading services/core/java/com/android/server/wm/WindowOrganizerController.java +50 −21 Original line number Diff line number Diff line Loading @@ -2201,6 +2201,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } private int setAdjacentRootsHierarchyOp(WindowContainerTransaction.HierarchyOp hop) { if (!Flags.allowMultipleAdjacentTaskFragments()) { final WindowContainer wc1 = WindowContainer.fromBinder(hop.getContainer()); if (wc1 == null || !wc1.isAttached()) { Slog.e(TAG, "Attempt to operate on unknown or detached container: " + wc1); Loading @@ -2220,12 +2221,40 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub if (root1.isAdjacentTo(root2)) { return TRANSACT_EFFECTS_NONE; } if (Flags.allowMultipleAdjacentTaskFragments()) { // TODO(b/373709676): allow three roots. root1.setAdjacentTaskFragments(new TaskFragment.AdjacentSet(root1, root2)); } else { root1.setAdjacentTaskFragment(root2); return TRANSACT_EFFECTS_LIFECYCLE; } final IBinder[] containers = hop.getContainers(); final ArraySet<TaskFragment> adjacentRoots = new ArraySet<>(); for (IBinder container : containers) { final WindowContainer wc = WindowContainer.fromBinder(container); if (wc == null || !wc.isAttached()) { Slog.e(TAG, "Attempt to operate on unknown or detached container: " + wc); return TRANSACT_EFFECTS_NONE; } final Task root = wc.asTask(); if (root == null) { // Only support Task. Use WCT#setAdjacentTaskFragments for non-Task TaskFragment. throw new IllegalArgumentException("setAdjacentRootsHierarchyOp: Not called with" + " Task. wc=" + wc); } if (!root.mCreatedByOrganizer) { throw new IllegalArgumentException("setAdjacentRootsHierarchyOp: Not created by" + " organizer root=" + root); } if (adjacentRoots.contains(root)) { throw new IllegalArgumentException("setAdjacentRootsHierarchyOp: called with same" + " root twice=" + root); } adjacentRoots.add(root); } final TaskFragment root0 = adjacentRoots.valueAt(0); final TaskFragment.AdjacentSet adjacentSet = new TaskFragment.AdjacentSet(adjacentRoots); if (adjacentSet.equals(root0.getAdjacentTaskFragments())) { return TRANSACT_EFFECTS_NONE; } root0.setAdjacentTaskFragments(adjacentSet); return TRANSACT_EFFECTS_LIFECYCLE; } Loading services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +43 −0 Original line number Diff line number Diff line Loading @@ -926,6 +926,49 @@ public class WindowOrganizerTests extends WindowTestsBase { assertEquals(dc.getDefaultTaskDisplayArea().mLaunchAdjacentFlagRootTask, null); } @EnableFlags(Flags.FLAG_ALLOW_MULTIPLE_ADJACENT_TASK_FRAGMENTS) @Test public void testSetAdjacentLaunchRootSet() { final DisplayContent dc = mWm.mRoot.getDisplayContent(Display.DEFAULT_DISPLAY); final Task task1 = mWm.mAtmService.mTaskOrganizerController.createRootTask( dc, WINDOWING_MODE_MULTI_WINDOW, null); final RunningTaskInfo info1 = task1.getTaskInfo(); final Task task2 = mWm.mAtmService.mTaskOrganizerController.createRootTask( dc, WINDOWING_MODE_MULTI_WINDOW, null); final RunningTaskInfo info2 = task2.getTaskInfo(); final Task task3 = mWm.mAtmService.mTaskOrganizerController.createRootTask( dc, WINDOWING_MODE_MULTI_WINDOW, null); final RunningTaskInfo info3 = task3.getTaskInfo(); WindowContainerTransaction wct = new WindowContainerTransaction(); wct.setAdjacentRootSet(info1.token, info2.token, info3.token); mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct); assertTrue(task1.hasAdjacentTaskFragment()); assertTrue(task2.hasAdjacentTaskFragment()); assertTrue(task3.hasAdjacentTaskFragment()); assertTrue(task1.isAdjacentTo(task2)); assertTrue(task1.isAdjacentTo(task3)); assertTrue(task2.isAdjacentTo(task3)); wct = new WindowContainerTransaction(); wct.clearAdjacentRoots(info1.token); mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct); assertFalse(task1.hasAdjacentTaskFragment()); assertTrue(task2.hasAdjacentTaskFragment()); assertTrue(task3.hasAdjacentTaskFragment()); assertFalse(task1.isAdjacentTo(task2)); assertFalse(task1.isAdjacentTo(task3)); assertTrue(task2.isAdjacentTo(task3)); wct = new WindowContainerTransaction(); wct.clearAdjacentRoots(info2.token); mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct); assertFalse(task2.hasAdjacentTaskFragment()); assertFalse(task3.hasAdjacentTaskFragment()); assertFalse(task2.isAdjacentTo(task3)); } @Test public void testTileAddRemoveChild() { final StubOrganizer listener = new StubOrganizer(); Loading Loading
core/java/android/window/WindowContainerTransaction.java +95 −20 Original line number Diff line number Diff line Loading @@ -486,7 +486,7 @@ public final class WindowContainerTransaction implements Parcelable { } /** * Sets to containers adjacent to each other. Containers below two visible adjacent roots will * Sets two containers adjacent to each other. Containers below two visible adjacent roots will * be made invisible. This currently only applies to TaskFragment containers created by * organizer. * @param root1 the first root. Loading @@ -495,11 +495,66 @@ public final class WindowContainerTransaction implements Parcelable { @NonNull public WindowContainerTransaction setAdjacentRoots( @NonNull WindowContainerToken root1, @NonNull WindowContainerToken root2) { if (!Flags.allowMultipleAdjacentTaskFragments()) { mHierarchyOps.add(HierarchyOp.createForAdjacentRoots( root1.asBinder(), root2.asBinder())); return this; } return setAdjacentRootSet(root1, root2); } /** * Sets multiple containers adjacent to each other. Containers below the visible adjacent roots * will be made invisible. This currently only applies to Task containers created by organizer. * * To remove one container from the adjacent roots, one can call {@link #clearAdjacentRoots} * with the target container. * To remove all containers from the adjacent roots, one much call {@link #clearAdjacentRoots} * on each container if there were more than two containers in the set. * * For non-Task TaskFragment, use {@link #setAdjacentTaskFragments} instead. * * @param roots the Tasks that should be adjacent to each other. * @throws IllegalArgumentException if roots have size < 2. * @hide // TODO(b/373709676) Rename to setAdjacentRoots and update CTS. */ @NonNull public WindowContainerTransaction setAdjacentRootSet( @NonNull WindowContainerToken... roots) { if (!Flags.allowMultipleAdjacentTaskFragments()) { throw new IllegalArgumentException("allowMultipleAdjacentTaskFragments is not enabled." + " Use #setAdjacentRoots instead."); } if (roots.length < 2) { throw new IllegalArgumentException("setAdjacentRootSet must have size >= 2"); } final IBinder[] rootTokens = new IBinder[roots.length]; for (int i = 0; i < roots.length; i++) { rootTokens[i] = roots[i].asBinder(); } mHierarchyOps.add( new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS) .setContainers(rootTokens) .build()); return this; } /** * Clears container adjacent. * If {@link #setAdjacentRootSet} is called with more than 2 roots, calling this will only * remove the given root from the adjacent set. The rest of roots will stay adjacent to each * other. * * @param root the root container to clear the adjacent roots for. * @hide */ @NonNull public WindowContainerTransaction clearAdjacentRoots( @NonNull WindowContainerToken root) { mHierarchyOps.add(HierarchyOp.createForClearAdjacentRoots(root.asBinder())); return this; } /** * Sets the container as launch adjacent flag root. Task starting with Loading Loading @@ -966,18 +1021,6 @@ public final class WindowContainerTransaction implements Parcelable { return this; } /** * Clears container adjacent. * @param root the root container to clear the adjacent roots for. * @hide */ @NonNull public WindowContainerTransaction clearAdjacentRoots( @NonNull WindowContainerToken root) { mHierarchyOps.add(HierarchyOp.createForClearAdjacentRoots(root.asBinder())); return this; } /** * Sets/removes the reparent leaf task flag for this {@code windowContainer}. * When this is set, the server side will try to reparent the leaf task to task display area Loading Loading @@ -1520,6 +1563,9 @@ public final class WindowContainerTransaction implements Parcelable { @Nullable private IBinder mContainer; @Nullable private IBinder[] mContainers; // If this is same as mContainer, then only change position, don't reparent. @Nullable private IBinder mReparent; Loading Loading @@ -1704,6 +1750,7 @@ public final class WindowContainerTransaction implements Parcelable { public HierarchyOp(@NonNull HierarchyOp copy) { mType = copy.mType; mContainer = copy.mContainer; mContainers = copy.mContainers; mBounds = copy.mBounds; mIncludingParents = copy.mIncludingParents; mReparent = copy.mReparent; Loading @@ -1729,6 +1776,7 @@ public final class WindowContainerTransaction implements Parcelable { protected HierarchyOp(Parcel in) { mType = in.readInt(); mContainer = in.readStrongBinder(); mContainers = in.createBinderArray(); mBounds = in.readTypedObject(Rect.CREATOR); mIncludingParents = in.readBoolean(); mReparent = in.readStrongBinder(); Loading Loading @@ -1779,6 +1827,13 @@ public final class WindowContainerTransaction implements Parcelable { return mContainer; } @NonNull public IBinder[] getContainers() { return mContainers; } /** @deprecated b/373709676 replace with {@link #getContainers()}. */ @Deprecated @NonNull public IBinder getAdjacentRoot() { return mReparent; Loading Loading @@ -1869,7 +1924,7 @@ public final class WindowContainerTransaction implements Parcelable { case HIERARCHY_OP_TYPE_REORDER: return "reorder"; case HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT: return "childrenTasksReparent"; case HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT: return "setLaunchRoot"; case HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS: return "setAdjacentRoot"; case HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS: return "setAdjacentRoots"; case HIERARCHY_OP_TYPE_LAUNCH_TASK: return "launchTask"; case HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT: return "setAdjacentFlagRoot"; case HIERARCHY_OP_TYPE_SET_DISABLE_LAUNCH_ADJACENT: Loading @@ -1883,7 +1938,7 @@ public final class WindowContainerTransaction implements Parcelable { case HIERARCHY_OP_TYPE_SET_ALWAYS_ON_TOP: return "setAlwaysOnTop"; case HIERARCHY_OP_TYPE_REMOVE_TASK: return "removeTask"; case HIERARCHY_OP_TYPE_FINISH_ACTIVITY: return "finishActivity"; case HIERARCHY_OP_TYPE_CLEAR_ADJACENT_ROOTS: return "clearAdjacentRoot"; case HIERARCHY_OP_TYPE_CLEAR_ADJACENT_ROOTS: return "clearAdjacentRoots"; case HIERARCHY_OP_TYPE_SET_REPARENT_LEAF_TASK_IF_RELAUNCH: return "setReparentLeafTaskIfRelaunch"; case HIERARCHY_OP_TYPE_ADD_TASK_FRAGMENT_OPERATION: Loading Loading @@ -1923,8 +1978,18 @@ public final class WindowContainerTransaction implements Parcelable { sb.append(mContainer).append(" to ").append(mToTop ? "top" : "bottom"); break; case HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS: if (Flags.allowMultipleAdjacentTaskFragments()) { for (IBinder container : mContainers) { if (container == mContainers[0]) { sb.append("adjacentRoots=").append(container); } else { sb.append(", ").append(container); } } } else { sb.append("container=").append(mContainer) .append(" adjacentRoot=").append(mReparent); } break; case HIERARCHY_OP_TYPE_LAUNCH_TASK: sb.append(mLaunchOptions); Loading Loading @@ -1997,6 +2062,7 @@ public final class WindowContainerTransaction implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mType); dest.writeStrongBinder(mContainer); dest.writeBinderArray(mContainers); dest.writeTypedObject(mBounds, flags); dest.writeBoolean(mIncludingParents); dest.writeStrongBinder(mReparent); Loading Loading @@ -2043,6 +2109,9 @@ public final class WindowContainerTransaction implements Parcelable { @Nullable private IBinder mContainer; @Nullable private IBinder[] mContainers; @Nullable private IBinder mReparent; Loading Loading @@ -2104,6 +2173,11 @@ public final class WindowContainerTransaction implements Parcelable { return this; } Builder setContainers(@Nullable IBinder[] containers) { mContainers = containers; return this; } Builder setReparentContainer(@Nullable IBinder reparentContainer) { mReparent = reparentContainer; return this; Loading Loading @@ -2209,6 +2283,7 @@ public final class WindowContainerTransaction implements Parcelable { HierarchyOp build() { final HierarchyOp hierarchyOp = new HierarchyOp(mType); hierarchyOp.mContainer = mContainer; hierarchyOp.mContainers = mContainers; hierarchyOp.mReparent = mReparent; hierarchyOp.mWindowingModes = mWindowingModes != null ? Arrays.copyOf(mWindowingModes, mWindowingModes.length) Loading
services/core/java/com/android/server/wm/WindowOrganizerController.java +50 −21 Original line number Diff line number Diff line Loading @@ -2201,6 +2201,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } private int setAdjacentRootsHierarchyOp(WindowContainerTransaction.HierarchyOp hop) { if (!Flags.allowMultipleAdjacentTaskFragments()) { final WindowContainer wc1 = WindowContainer.fromBinder(hop.getContainer()); if (wc1 == null || !wc1.isAttached()) { Slog.e(TAG, "Attempt to operate on unknown or detached container: " + wc1); Loading @@ -2220,12 +2221,40 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub if (root1.isAdjacentTo(root2)) { return TRANSACT_EFFECTS_NONE; } if (Flags.allowMultipleAdjacentTaskFragments()) { // TODO(b/373709676): allow three roots. root1.setAdjacentTaskFragments(new TaskFragment.AdjacentSet(root1, root2)); } else { root1.setAdjacentTaskFragment(root2); return TRANSACT_EFFECTS_LIFECYCLE; } final IBinder[] containers = hop.getContainers(); final ArraySet<TaskFragment> adjacentRoots = new ArraySet<>(); for (IBinder container : containers) { final WindowContainer wc = WindowContainer.fromBinder(container); if (wc == null || !wc.isAttached()) { Slog.e(TAG, "Attempt to operate on unknown or detached container: " + wc); return TRANSACT_EFFECTS_NONE; } final Task root = wc.asTask(); if (root == null) { // Only support Task. Use WCT#setAdjacentTaskFragments for non-Task TaskFragment. throw new IllegalArgumentException("setAdjacentRootsHierarchyOp: Not called with" + " Task. wc=" + wc); } if (!root.mCreatedByOrganizer) { throw new IllegalArgumentException("setAdjacentRootsHierarchyOp: Not created by" + " organizer root=" + root); } if (adjacentRoots.contains(root)) { throw new IllegalArgumentException("setAdjacentRootsHierarchyOp: called with same" + " root twice=" + root); } adjacentRoots.add(root); } final TaskFragment root0 = adjacentRoots.valueAt(0); final TaskFragment.AdjacentSet adjacentSet = new TaskFragment.AdjacentSet(adjacentRoots); if (adjacentSet.equals(root0.getAdjacentTaskFragments())) { return TRANSACT_EFFECTS_NONE; } root0.setAdjacentTaskFragments(adjacentSet); return TRANSACT_EFFECTS_LIFECYCLE; } Loading
services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +43 −0 Original line number Diff line number Diff line Loading @@ -926,6 +926,49 @@ public class WindowOrganizerTests extends WindowTestsBase { assertEquals(dc.getDefaultTaskDisplayArea().mLaunchAdjacentFlagRootTask, null); } @EnableFlags(Flags.FLAG_ALLOW_MULTIPLE_ADJACENT_TASK_FRAGMENTS) @Test public void testSetAdjacentLaunchRootSet() { final DisplayContent dc = mWm.mRoot.getDisplayContent(Display.DEFAULT_DISPLAY); final Task task1 = mWm.mAtmService.mTaskOrganizerController.createRootTask( dc, WINDOWING_MODE_MULTI_WINDOW, null); final RunningTaskInfo info1 = task1.getTaskInfo(); final Task task2 = mWm.mAtmService.mTaskOrganizerController.createRootTask( dc, WINDOWING_MODE_MULTI_WINDOW, null); final RunningTaskInfo info2 = task2.getTaskInfo(); final Task task3 = mWm.mAtmService.mTaskOrganizerController.createRootTask( dc, WINDOWING_MODE_MULTI_WINDOW, null); final RunningTaskInfo info3 = task3.getTaskInfo(); WindowContainerTransaction wct = new WindowContainerTransaction(); wct.setAdjacentRootSet(info1.token, info2.token, info3.token); mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct); assertTrue(task1.hasAdjacentTaskFragment()); assertTrue(task2.hasAdjacentTaskFragment()); assertTrue(task3.hasAdjacentTaskFragment()); assertTrue(task1.isAdjacentTo(task2)); assertTrue(task1.isAdjacentTo(task3)); assertTrue(task2.isAdjacentTo(task3)); wct = new WindowContainerTransaction(); wct.clearAdjacentRoots(info1.token); mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct); assertFalse(task1.hasAdjacentTaskFragment()); assertTrue(task2.hasAdjacentTaskFragment()); assertTrue(task3.hasAdjacentTaskFragment()); assertFalse(task1.isAdjacentTo(task2)); assertFalse(task1.isAdjacentTo(task3)); assertTrue(task2.isAdjacentTo(task3)); wct = new WindowContainerTransaction(); wct.clearAdjacentRoots(info2.token); mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct); assertFalse(task2.hasAdjacentTaskFragment()); assertFalse(task3.hasAdjacentTaskFragment()); assertFalse(task2.isAdjacentTo(task3)); } @Test public void testTileAddRemoveChild() { final StubOrganizer listener = new StubOrganizer(); Loading