Loading core/java/android/window/WindowContainerTransaction.java +54 −0 Original line number Diff line number Diff line Loading @@ -301,6 +301,33 @@ public final class WindowContainerTransaction implements Parcelable { return this; } /** * Sets whether to allow the child tasks to have override bounds. * * <p>When {@code true}, the system will ensure the child tasks of the given root task * will have no override bounds. That is, the override bounds of the existing child tasks * will be cleared, and the override bounds of any newly added child tasks afterward will * also be cleared. This mechanism is specifically designed to be applied to a root task * created by an organizer only. * * @param rootTaskContainer The window container of the task that created by organizer. * @param disallowOverrideBoundsForChildren {@code true} to avoid the child tasks to have * override bounds, {@code false} otherwise. * @hide */ @NonNull public WindowContainerTransaction setDisallowOverrideBoundsForChildren( @NonNull WindowContainerToken rootTaskContainer, boolean disallowOverrideBoundsForChildren) { final HierarchyOp hierarchyOp = new HierarchyOp.Builder( HierarchyOp.HIERARCHY_OP_TYPE_DISALLOW_OVERRIDE_BOUNDS_FOR_CHILDREN) .setContainer(rootTaskContainer.asBinder()) .setDisallowOverrideBoundsForChildren(disallowOverrideBoundsForChildren) .build(); mHierarchyOps.add(hierarchyOp); return this; } /** * Sets whether a container or its children should be hidden. When {@code false}, the existing * visibility of the container applies, but when {@code true} the container will be forced Loading Loading @@ -1932,6 +1959,7 @@ public final class WindowContainerTransaction implements Parcelable { public static final int HIERARCHY_OP_TYPE_APP_COMPAT_REACHABILITY = 24; public static final int HIERARCHY_OP_TYPE_SET_SAFE_REGION_BOUNDS = 25; public static final int HIERARCHY_OP_TYPE_SET_SYSTEM_BAR_VISIBILITY_OVERRIDE = 26; public static final int HIERARCHY_OP_TYPE_DISALLOW_OVERRIDE_BOUNDS_FOR_CHILDREN = 27; @IntDef(prefix = {"HIERARCHY_OP_TYPE_"}, value = { HIERARCHY_OP_TYPE_REPARENT, Loading Loading @@ -1961,6 +1989,7 @@ public final class WindowContainerTransaction implements Parcelable { HIERARCHY_OP_TYPE_APP_COMPAT_REACHABILITY, HIERARCHY_OP_TYPE_SET_SAFE_REGION_BOUNDS, HIERARCHY_OP_TYPE_SET_SYSTEM_BAR_VISIBILITY_OVERRIDE, HIERARCHY_OP_TYPE_DISALLOW_OVERRIDE_BOUNDS_FOR_CHILDREN, }) @Retention(RetentionPolicy.SOURCE) public @interface HierarchyOpType { Loading Loading @@ -2050,6 +2079,8 @@ public final class WindowContainerTransaction implements Parcelable { @Nullable private Rect mSafeRegionBounds; private boolean mDisallowOverrideBoundsForChildren; /** Creates a hierarchy operation for reparenting a container within the hierarchy. */ @NonNull public static HierarchyOp createForReparent( Loading Loading @@ -2246,6 +2277,7 @@ public final class WindowContainerTransaction implements Parcelable { mForciblyShowingInsetsTypes = copy.mForciblyShowingInsetsTypes; mForciblyHidingInsetsTypes = copy.mForciblyHidingInsetsTypes; mSafeRegionBounds = copy.mSafeRegionBounds; mDisallowOverrideBoundsForChildren = copy.mDisallowOverrideBoundsForChildren; } private HierarchyOp(@NonNull Parcel in) { Loading Loading @@ -2275,6 +2307,7 @@ public final class WindowContainerTransaction implements Parcelable { mForciblyShowingInsetsTypes = in.readInt(); mForciblyHidingInsetsTypes = in.readInt(); mSafeRegionBounds = in.readTypedObject(Rect.CREATOR); mDisallowOverrideBoundsForChildren = in.readBoolean(); } @HierarchyOpType Loading Loading @@ -2405,6 +2438,10 @@ public final class WindowContainerTransaction implements Parcelable { return mSafeRegionBounds; } public boolean getDisallowOverrideBoundsForChildren() { return mDisallowOverrideBoundsForChildren; } /** Gets a string representation of a hierarchy-op type. */ public static String hopToString(@HierarchyOpType int type) { switch (type) { Loading Loading @@ -2439,6 +2476,8 @@ public final class WindowContainerTransaction implements Parcelable { case HIERARCHY_OP_TYPE_SET_SAFE_REGION_BOUNDS: return "setSafeRegionBounds"; case HIERARCHY_OP_TYPE_SET_SYSTEM_BAR_VISIBILITY_OVERRIDE: return "setSystemBarVisibilityOverride"; case HIERARCHY_OP_TYPE_DISALLOW_OVERRIDE_BOUNDS_FOR_CHILDREN: return "disallowOverrideBoundsForChildren"; default: return "HOP(" + type + ")"; } } Loading Loading @@ -2549,6 +2588,11 @@ public final class WindowContainerTransaction implements Parcelable { .append(" mForciblyHidingInsetsTypes=") .append(WindowInsets.Type.toString(mForciblyHidingInsetsTypes)); break; case HIERARCHY_OP_TYPE_DISALLOW_OVERRIDE_BOUNDS_FOR_CHILDREN: sb.append(" container=").append(mContainer) .append(" mDisallowOverrideBoundsForChildren=") .append(mDisallowOverrideBoundsForChildren); break; default: sb.append("container=").append(mContainer) .append(" reparent=").append(mReparent) Loading Loading @@ -2587,6 +2631,7 @@ public final class WindowContainerTransaction implements Parcelable { dest.writeInt(mForciblyShowingInsetsTypes); dest.writeInt(mForciblyHidingInsetsTypes); dest.writeTypedObject(mSafeRegionBounds, flags); dest.writeBoolean(mDisallowOverrideBoundsForChildren); } @Override Loading Loading @@ -2676,6 +2721,8 @@ public final class WindowContainerTransaction implements Parcelable { @Nullable private Rect mSafeRegionBounds; private boolean mDisallowOverrideBoundsForChildren; Builder(@HierarchyOpType int type) { mType = type; } Loading Loading @@ -2805,6 +2852,12 @@ public final class WindowContainerTransaction implements Parcelable { return this; } Builder setDisallowOverrideBoundsForChildren( boolean disallowOverrideBoundsForChildren) { mDisallowOverrideBoundsForChildren = disallowOverrideBoundsForChildren; return this; } @NonNull HierarchyOp build() { final HierarchyOp hierarchyOp = new HierarchyOp(mType); Loading Loading @@ -2837,6 +2890,7 @@ public final class WindowContainerTransaction implements Parcelable { hierarchyOp.mForciblyShowingInsetsTypes = mForciblyShowingInsetsTypes; hierarchyOp.mForciblyHidingInsetsTypes = mForciblyHidingInsetsTypes; hierarchyOp.mSafeRegionBounds = mSafeRegionBounds; hierarchyOp.mDisallowOverrideBoundsForChildren = mDisallowOverrideBoundsForChildren; return hierarchyOp; } } Loading services/core/java/com/android/server/wm/Task.java +54 −0 Original line number Diff line number Diff line Loading @@ -530,6 +530,11 @@ class Task extends TaskFragment { */ private boolean mForceNonResizeOverride; /** * Whether the child tasks can have override bounds. */ private boolean mDisallowOverrideBoundsForChildren; /** * If the window is allowed to be repositioned by {@link * android.app.ActivityManager.AppTask#moveTaskTo}. Loading Loading @@ -1235,9 +1240,25 @@ class Task extends TaskFragment { setInitialBoundsIfNeeded(); } // Clear the override bounds if any ancestor requested to. if (!isOverrideBoundsAllowed()) { setBounds(null); } mRootWindowContainer.updateUIDsPresentOnDisplay(); } private boolean isOverrideBoundsAllowed() { Task parentTask = getParent() != null ? getParent().asTask() : null; while (parentTask != null) { if (parentTask.mDisallowOverrideBoundsForChildren) { return false; } parentTask = parentTask.getParent().asTask(); } return true; } @Override void onResize() { super.onResize(); Loading Loading @@ -2896,6 +2917,11 @@ class Task extends TaskFragment { return setBounds(getRequestedOverrideBounds(), bounds); } if (!isOverrideBoundsAllowed() && bounds != null && !bounds.isEmpty()) { Slog.w(TAG, "Not allowed to set override bounds " + bounds + " for " + this); return BOUNDS_CHANGE_NONE; } final int boundsChange = super.setBounds(bounds); updateSurfacePositionNonOrganized(); return boundsChange; Loading Loading @@ -6060,6 +6086,9 @@ class Task extends TaskFragment { if (mDisablePip) { pw.println(prefix + " mDisablePip=true"); } if (mDisallowOverrideBoundsForChildren) { pw.println(prefix + " mDisallowOverrideBoundsForChildren=true"); } if (mLastNonFullscreenBounds != null) { pw.print(prefix); pw.print(" mLastNonFullscreenBounds="); pw.println(mLastNonFullscreenBounds); Loading Loading @@ -6466,6 +6495,31 @@ class Task extends TaskFragment { return mSelfMovable; } /** * Sets whether the child tasks can have override bounds. * * @param disallowOverrideBoundsForChildren whether to disallow the override bounds * @return a bitmask representing the types of bounds changes made to the child tasks. */ int setDisallowOverrideBoundsForChildren(boolean disallowOverrideBoundsForChildren) { if (!mCreatedByOrganizer) { Slog.w(TAG, "Can only disable child bounds override on tasks created by organizer"); return BOUNDS_CHANGE_NONE; } mDisallowOverrideBoundsForChildren = disallowOverrideBoundsForChildren; final int[] boundsChange = new int[1]; if (disallowOverrideBoundsForChildren) { forAllTasks(task -> { if (task == this) { return; } boundsChange[0] |= task.setBounds(null); }); } return boundsChange[0]; } @Override public void dumpDebug(ProtoOutputStream proto, long fieldId, @WindowTracingLogLevel int logLevel) { Loading services/core/java/com/android/server/wm/WindowOrganizerController.java +22 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_APP_COMPAT_REACHABILITY; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CLEAR_ADJACENT_ROOTS; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_DISALLOW_OVERRIDE_BOUNDS_FOR_CHILDREN; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_FINISH_ACTIVITY; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_LAUNCH_TASK; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_MOVE_PIP_ACTIVITY_TO_PINNED_TASK; Loading Loading @@ -93,6 +94,7 @@ import static com.android.server.wm.ActivityTaskManagerService.enforceTaskPermis import static com.android.server.wm.ActivityTaskManagerService.isPip2ExperimentEnabled; import static com.android.server.wm.ActivityTaskSupervisor.REMOVE_FROM_RECENTS; import static com.android.server.wm.AppCompatReachabilityPolicy.REACHABILITY_SOURCE_SHELL; import static com.android.server.wm.ConfigurationContainer.BOUNDS_CHANGE_NONE; import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK; import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG; import static com.android.server.wm.TaskFragment.EMBEDDED_DIM_AREA_PARENT_TASK; Loading Loading @@ -1644,6 +1646,26 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } break; } case HIERARCHY_OP_TYPE_DISALLOW_OVERRIDE_BOUNDS_FOR_CHILDREN: { final WindowContainer<?> container = WindowContainer.fromBinder(hop.getContainer()); if (container == null || !container.isAttached()) { Slog.e(TAG, "Attempt to operate on unknown or detached container: " + container); break; } final Task task = container.asTask(); if (task == null) { Slog.e(TAG, "Cannot disallow override bounds for children on a non-task: " + container); break; } if (task.setDisallowOverrideBoundsForChildren( hop.getDisallowOverrideBoundsForChildren()) != BOUNDS_CHANGE_NONE) { effects |= TRANSACT_EFFECTS_LIFECYCLE; } break; } } return effects; } Loading services/tests/wmtests/src/com/android/server/wm/WindowContainerTransactionTests.java +26 −0 Original line number Diff line number Diff line Loading @@ -542,6 +542,32 @@ public class WindowContainerTransactionTests extends WindowTestsBase { assertFalse(task.getIsTaskMoveAllowed()); } @Test public void testSetDisallowOverrideBoundsForChildren() { final Rect overrideBounds = new Rect(10, 10, 100, 100); final Rect emptyBounds = new Rect(); final Task parentTask = createTask(mDisplayContent); final Task childTask = new TaskBuilder(mSupervisor) .setTaskDisplayArea(parentTask.getTaskDisplayArea()) .setParentTask(parentTask) .build(); parentTask.mCreatedByOrganizer = true; // Verifies the override bounds once set. childTask.setBounds(overrideBounds); assertEquals(overrideBounds, childTask.getRequestedOverrideBounds()); // Verifies the override bounds are cleared if the ancestor disallowed. WindowContainerTransaction wct = new WindowContainerTransaction(); wct.setDisallowOverrideBoundsForChildren(parentTask.getTaskInfo().token, true); applyTransaction(wct); assertEquals(emptyBounds, childTask.getRequestedOverrideBounds()); // Verifies the override bounds cannot be set if the ancestor disallowed. childTask.setBounds(overrideBounds); assertEquals(emptyBounds, childTask.getRequestedOverrideBounds()); } private Task createTask(int taskId) { return new Task.Builder(mAtm) .setTaskId(taskId) Loading Loading
core/java/android/window/WindowContainerTransaction.java +54 −0 Original line number Diff line number Diff line Loading @@ -301,6 +301,33 @@ public final class WindowContainerTransaction implements Parcelable { return this; } /** * Sets whether to allow the child tasks to have override bounds. * * <p>When {@code true}, the system will ensure the child tasks of the given root task * will have no override bounds. That is, the override bounds of the existing child tasks * will be cleared, and the override bounds of any newly added child tasks afterward will * also be cleared. This mechanism is specifically designed to be applied to a root task * created by an organizer only. * * @param rootTaskContainer The window container of the task that created by organizer. * @param disallowOverrideBoundsForChildren {@code true} to avoid the child tasks to have * override bounds, {@code false} otherwise. * @hide */ @NonNull public WindowContainerTransaction setDisallowOverrideBoundsForChildren( @NonNull WindowContainerToken rootTaskContainer, boolean disallowOverrideBoundsForChildren) { final HierarchyOp hierarchyOp = new HierarchyOp.Builder( HierarchyOp.HIERARCHY_OP_TYPE_DISALLOW_OVERRIDE_BOUNDS_FOR_CHILDREN) .setContainer(rootTaskContainer.asBinder()) .setDisallowOverrideBoundsForChildren(disallowOverrideBoundsForChildren) .build(); mHierarchyOps.add(hierarchyOp); return this; } /** * Sets whether a container or its children should be hidden. When {@code false}, the existing * visibility of the container applies, but when {@code true} the container will be forced Loading Loading @@ -1932,6 +1959,7 @@ public final class WindowContainerTransaction implements Parcelable { public static final int HIERARCHY_OP_TYPE_APP_COMPAT_REACHABILITY = 24; public static final int HIERARCHY_OP_TYPE_SET_SAFE_REGION_BOUNDS = 25; public static final int HIERARCHY_OP_TYPE_SET_SYSTEM_BAR_VISIBILITY_OVERRIDE = 26; public static final int HIERARCHY_OP_TYPE_DISALLOW_OVERRIDE_BOUNDS_FOR_CHILDREN = 27; @IntDef(prefix = {"HIERARCHY_OP_TYPE_"}, value = { HIERARCHY_OP_TYPE_REPARENT, Loading Loading @@ -1961,6 +1989,7 @@ public final class WindowContainerTransaction implements Parcelable { HIERARCHY_OP_TYPE_APP_COMPAT_REACHABILITY, HIERARCHY_OP_TYPE_SET_SAFE_REGION_BOUNDS, HIERARCHY_OP_TYPE_SET_SYSTEM_BAR_VISIBILITY_OVERRIDE, HIERARCHY_OP_TYPE_DISALLOW_OVERRIDE_BOUNDS_FOR_CHILDREN, }) @Retention(RetentionPolicy.SOURCE) public @interface HierarchyOpType { Loading Loading @@ -2050,6 +2079,8 @@ public final class WindowContainerTransaction implements Parcelable { @Nullable private Rect mSafeRegionBounds; private boolean mDisallowOverrideBoundsForChildren; /** Creates a hierarchy operation for reparenting a container within the hierarchy. */ @NonNull public static HierarchyOp createForReparent( Loading Loading @@ -2246,6 +2277,7 @@ public final class WindowContainerTransaction implements Parcelable { mForciblyShowingInsetsTypes = copy.mForciblyShowingInsetsTypes; mForciblyHidingInsetsTypes = copy.mForciblyHidingInsetsTypes; mSafeRegionBounds = copy.mSafeRegionBounds; mDisallowOverrideBoundsForChildren = copy.mDisallowOverrideBoundsForChildren; } private HierarchyOp(@NonNull Parcel in) { Loading Loading @@ -2275,6 +2307,7 @@ public final class WindowContainerTransaction implements Parcelable { mForciblyShowingInsetsTypes = in.readInt(); mForciblyHidingInsetsTypes = in.readInt(); mSafeRegionBounds = in.readTypedObject(Rect.CREATOR); mDisallowOverrideBoundsForChildren = in.readBoolean(); } @HierarchyOpType Loading Loading @@ -2405,6 +2438,10 @@ public final class WindowContainerTransaction implements Parcelable { return mSafeRegionBounds; } public boolean getDisallowOverrideBoundsForChildren() { return mDisallowOverrideBoundsForChildren; } /** Gets a string representation of a hierarchy-op type. */ public static String hopToString(@HierarchyOpType int type) { switch (type) { Loading Loading @@ -2439,6 +2476,8 @@ public final class WindowContainerTransaction implements Parcelable { case HIERARCHY_OP_TYPE_SET_SAFE_REGION_BOUNDS: return "setSafeRegionBounds"; case HIERARCHY_OP_TYPE_SET_SYSTEM_BAR_VISIBILITY_OVERRIDE: return "setSystemBarVisibilityOverride"; case HIERARCHY_OP_TYPE_DISALLOW_OVERRIDE_BOUNDS_FOR_CHILDREN: return "disallowOverrideBoundsForChildren"; default: return "HOP(" + type + ")"; } } Loading Loading @@ -2549,6 +2588,11 @@ public final class WindowContainerTransaction implements Parcelable { .append(" mForciblyHidingInsetsTypes=") .append(WindowInsets.Type.toString(mForciblyHidingInsetsTypes)); break; case HIERARCHY_OP_TYPE_DISALLOW_OVERRIDE_BOUNDS_FOR_CHILDREN: sb.append(" container=").append(mContainer) .append(" mDisallowOverrideBoundsForChildren=") .append(mDisallowOverrideBoundsForChildren); break; default: sb.append("container=").append(mContainer) .append(" reparent=").append(mReparent) Loading Loading @@ -2587,6 +2631,7 @@ public final class WindowContainerTransaction implements Parcelable { dest.writeInt(mForciblyShowingInsetsTypes); dest.writeInt(mForciblyHidingInsetsTypes); dest.writeTypedObject(mSafeRegionBounds, flags); dest.writeBoolean(mDisallowOverrideBoundsForChildren); } @Override Loading Loading @@ -2676,6 +2721,8 @@ public final class WindowContainerTransaction implements Parcelable { @Nullable private Rect mSafeRegionBounds; private boolean mDisallowOverrideBoundsForChildren; Builder(@HierarchyOpType int type) { mType = type; } Loading Loading @@ -2805,6 +2852,12 @@ public final class WindowContainerTransaction implements Parcelable { return this; } Builder setDisallowOverrideBoundsForChildren( boolean disallowOverrideBoundsForChildren) { mDisallowOverrideBoundsForChildren = disallowOverrideBoundsForChildren; return this; } @NonNull HierarchyOp build() { final HierarchyOp hierarchyOp = new HierarchyOp(mType); Loading Loading @@ -2837,6 +2890,7 @@ public final class WindowContainerTransaction implements Parcelable { hierarchyOp.mForciblyShowingInsetsTypes = mForciblyShowingInsetsTypes; hierarchyOp.mForciblyHidingInsetsTypes = mForciblyHidingInsetsTypes; hierarchyOp.mSafeRegionBounds = mSafeRegionBounds; hierarchyOp.mDisallowOverrideBoundsForChildren = mDisallowOverrideBoundsForChildren; return hierarchyOp; } } Loading
services/core/java/com/android/server/wm/Task.java +54 −0 Original line number Diff line number Diff line Loading @@ -530,6 +530,11 @@ class Task extends TaskFragment { */ private boolean mForceNonResizeOverride; /** * Whether the child tasks can have override bounds. */ private boolean mDisallowOverrideBoundsForChildren; /** * If the window is allowed to be repositioned by {@link * android.app.ActivityManager.AppTask#moveTaskTo}. Loading Loading @@ -1235,9 +1240,25 @@ class Task extends TaskFragment { setInitialBoundsIfNeeded(); } // Clear the override bounds if any ancestor requested to. if (!isOverrideBoundsAllowed()) { setBounds(null); } mRootWindowContainer.updateUIDsPresentOnDisplay(); } private boolean isOverrideBoundsAllowed() { Task parentTask = getParent() != null ? getParent().asTask() : null; while (parentTask != null) { if (parentTask.mDisallowOverrideBoundsForChildren) { return false; } parentTask = parentTask.getParent().asTask(); } return true; } @Override void onResize() { super.onResize(); Loading Loading @@ -2896,6 +2917,11 @@ class Task extends TaskFragment { return setBounds(getRequestedOverrideBounds(), bounds); } if (!isOverrideBoundsAllowed() && bounds != null && !bounds.isEmpty()) { Slog.w(TAG, "Not allowed to set override bounds " + bounds + " for " + this); return BOUNDS_CHANGE_NONE; } final int boundsChange = super.setBounds(bounds); updateSurfacePositionNonOrganized(); return boundsChange; Loading Loading @@ -6060,6 +6086,9 @@ class Task extends TaskFragment { if (mDisablePip) { pw.println(prefix + " mDisablePip=true"); } if (mDisallowOverrideBoundsForChildren) { pw.println(prefix + " mDisallowOverrideBoundsForChildren=true"); } if (mLastNonFullscreenBounds != null) { pw.print(prefix); pw.print(" mLastNonFullscreenBounds="); pw.println(mLastNonFullscreenBounds); Loading Loading @@ -6466,6 +6495,31 @@ class Task extends TaskFragment { return mSelfMovable; } /** * Sets whether the child tasks can have override bounds. * * @param disallowOverrideBoundsForChildren whether to disallow the override bounds * @return a bitmask representing the types of bounds changes made to the child tasks. */ int setDisallowOverrideBoundsForChildren(boolean disallowOverrideBoundsForChildren) { if (!mCreatedByOrganizer) { Slog.w(TAG, "Can only disable child bounds override on tasks created by organizer"); return BOUNDS_CHANGE_NONE; } mDisallowOverrideBoundsForChildren = disallowOverrideBoundsForChildren; final int[] boundsChange = new int[1]; if (disallowOverrideBoundsForChildren) { forAllTasks(task -> { if (task == this) { return; } boundsChange[0] |= task.setBounds(null); }); } return boundsChange[0]; } @Override public void dumpDebug(ProtoOutputStream proto, long fieldId, @WindowTracingLogLevel int logLevel) { Loading
services/core/java/com/android/server/wm/WindowOrganizerController.java +22 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_APP_COMPAT_REACHABILITY; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CLEAR_ADJACENT_ROOTS; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_DISALLOW_OVERRIDE_BOUNDS_FOR_CHILDREN; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_FINISH_ACTIVITY; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_LAUNCH_TASK; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_MOVE_PIP_ACTIVITY_TO_PINNED_TASK; Loading Loading @@ -93,6 +94,7 @@ import static com.android.server.wm.ActivityTaskManagerService.enforceTaskPermis import static com.android.server.wm.ActivityTaskManagerService.isPip2ExperimentEnabled; import static com.android.server.wm.ActivityTaskSupervisor.REMOVE_FROM_RECENTS; import static com.android.server.wm.AppCompatReachabilityPolicy.REACHABILITY_SOURCE_SHELL; import static com.android.server.wm.ConfigurationContainer.BOUNDS_CHANGE_NONE; import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK; import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG; import static com.android.server.wm.TaskFragment.EMBEDDED_DIM_AREA_PARENT_TASK; Loading Loading @@ -1644,6 +1646,26 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } break; } case HIERARCHY_OP_TYPE_DISALLOW_OVERRIDE_BOUNDS_FOR_CHILDREN: { final WindowContainer<?> container = WindowContainer.fromBinder(hop.getContainer()); if (container == null || !container.isAttached()) { Slog.e(TAG, "Attempt to operate on unknown or detached container: " + container); break; } final Task task = container.asTask(); if (task == null) { Slog.e(TAG, "Cannot disallow override bounds for children on a non-task: " + container); break; } if (task.setDisallowOverrideBoundsForChildren( hop.getDisallowOverrideBoundsForChildren()) != BOUNDS_CHANGE_NONE) { effects |= TRANSACT_EFFECTS_LIFECYCLE; } break; } } return effects; } Loading
services/tests/wmtests/src/com/android/server/wm/WindowContainerTransactionTests.java +26 −0 Original line number Diff line number Diff line Loading @@ -542,6 +542,32 @@ public class WindowContainerTransactionTests extends WindowTestsBase { assertFalse(task.getIsTaskMoveAllowed()); } @Test public void testSetDisallowOverrideBoundsForChildren() { final Rect overrideBounds = new Rect(10, 10, 100, 100); final Rect emptyBounds = new Rect(); final Task parentTask = createTask(mDisplayContent); final Task childTask = new TaskBuilder(mSupervisor) .setTaskDisplayArea(parentTask.getTaskDisplayArea()) .setParentTask(parentTask) .build(); parentTask.mCreatedByOrganizer = true; // Verifies the override bounds once set. childTask.setBounds(overrideBounds); assertEquals(overrideBounds, childTask.getRequestedOverrideBounds()); // Verifies the override bounds are cleared if the ancestor disallowed. WindowContainerTransaction wct = new WindowContainerTransaction(); wct.setDisallowOverrideBoundsForChildren(parentTask.getTaskInfo().token, true); applyTransaction(wct); assertEquals(emptyBounds, childTask.getRequestedOverrideBounds()); // Verifies the override bounds cannot be set if the ancestor disallowed. childTask.setBounds(overrideBounds); assertEquals(emptyBounds, childTask.getRequestedOverrideBounds()); } private Task createTask(int taskId) { return new Task.Builder(mAtm) .setTaskId(taskId) Loading