Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cab919af authored by Louis Chang's avatar Louis Chang Committed by Android (Google) Code Review
Browse files

Merge "Adding a WCT to make child tasks always inherits the parent bounds" into main

parents 38cd21f2 9304ce90
Loading
Loading
Loading
Loading
+54 −0
Original line number Diff line number Diff line
@@ -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
@@ -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,
@@ -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 {
@@ -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(
@@ -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) {
@@ -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
@@ -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) {
@@ -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 + ")";
            }
        }
@@ -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)
@@ -2587,6 +2631,7 @@ public final class WindowContainerTransaction implements Parcelable {
            dest.writeInt(mForciblyShowingInsetsTypes);
            dest.writeInt(mForciblyHidingInsetsTypes);
            dest.writeTypedObject(mSafeRegionBounds, flags);
            dest.writeBoolean(mDisallowOverrideBoundsForChildren);
        }

        @Override
@@ -2676,6 +2721,8 @@ public final class WindowContainerTransaction implements Parcelable {
            @Nullable
            private Rect mSafeRegionBounds;

            private boolean mDisallowOverrideBoundsForChildren;

            Builder(@HierarchyOpType int type) {
                mType = type;
            }
@@ -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);
@@ -2837,6 +2890,7 @@ public final class WindowContainerTransaction implements Parcelable {
                hierarchyOp.mForciblyShowingInsetsTypes = mForciblyShowingInsetsTypes;
                hierarchyOp.mForciblyHidingInsetsTypes = mForciblyHidingInsetsTypes;
                hierarchyOp.mSafeRegionBounds = mSafeRegionBounds;
                hierarchyOp.mDisallowOverrideBoundsForChildren = mDisallowOverrideBoundsForChildren;
                return hierarchyOp;
            }
        }
+54 −0
Original line number Diff line number Diff line
@@ -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}.
@@ -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();
@@ -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;
@@ -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);
@@ -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) {
+22 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
    }
+26 −0
Original line number Diff line number Diff line
@@ -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)