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

Commit 60f66360 authored by Jorge Gil's avatar Jorge Gil Committed by Android (Google) Code Review
Browse files

Merge "[4/N] Desks: Add WCT#removeRootTask()" into main

parents 5ea9b08e 968154b0
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -39,7 +39,12 @@ interface ITaskOrganizerController {
     */
    void unregisterTaskOrganizer(ITaskOrganizer organizer);

    /** Creates a persistent root task in WM for a particular windowing-mode. */
    /**
    * Creates a persistent root task in WM for a particular windowing-mode.
    *
    * It may be removed using {@link #deleteRootTask} or through
    * {@link WindowContainerTransaction#removeRootTask}.
    */
    void createRootTask(int displayId, int windowingMode, IBinder launchCookie,
            boolean removeWithTaskOrganizer);

+36 −1
Original line number Diff line number Diff line
@@ -614,6 +614,10 @@ public final class WindowContainerTransaction implements Parcelable {
    /**
     * Finds and removes a task and its children using its container token. The task is removed
     * from recents.
     *
     * If the task is a root task, its leaves are removed but the root task is not. Use
     * {@link #removeRootTask(WindowContainerToken)} to remove the root task.
     *
     * @param containerToken ContainerToken of Task to be removed
     */
    @NonNull
@@ -622,6 +626,19 @@ public final class WindowContainerTransaction implements Parcelable {
        return this;
    }

    /**
     * Finds and removes a root task created by an organizer and its leaves using its container
     * token.
     *
     * @param containerToken ContainerToken of the root task to be removed
     * @hide
     */
    @NonNull
    public WindowContainerTransaction removeRootTask(@NonNull WindowContainerToken containerToken) {
        mHierarchyOps.add(HierarchyOp.createForRemoveRootTask(containerToken.asBinder()));
        return this;
    }

    /**
     * Sets whether a container is being drag-resized.
     * When {@code true}, the client will reuse a single (larger) surface size to avoid
@@ -1573,6 +1590,7 @@ public final class WindowContainerTransaction implements Parcelable {
        public static final int HIERARCHY_OP_TYPE_SET_EXCLUDE_INSETS_TYPES = 21;
        public static final int HIERARCHY_OP_TYPE_SET_KEYGUARD_STATE = 22;
        public static final int HIERARCHY_OP_TYPE_SET_DISABLE_LAUNCH_ADJACENT = 23;
        public static final int HIERARCHY_OP_TYPE_REMOVE_ROOT_TASK = 24;

        @IntDef(prefix = {"HIERARCHY_OP_TYPE_"}, value = {
                HIERARCHY_OP_TYPE_REPARENT,
@@ -1598,7 +1616,8 @@ public final class WindowContainerTransaction implements Parcelable {
                HIERARCHY_OP_TYPE_RESTORE_BACK_NAVIGATION,
                HIERARCHY_OP_TYPE_SET_EXCLUDE_INSETS_TYPES,
                HIERARCHY_OP_TYPE_SET_KEYGUARD_STATE,
                HIERARCHY_OP_TYPE_SET_DISABLE_LAUNCH_ADJACENT
                HIERARCHY_OP_TYPE_SET_DISABLE_LAUNCH_ADJACENT,
                HIERARCHY_OP_TYPE_REMOVE_ROOT_TASK,
        })
        @Retention(RetentionPolicy.SOURCE)
        public @interface HierarchyOpType {
@@ -1795,6 +1814,18 @@ public final class WindowContainerTransaction implements Parcelable {
                    .build();
        }

        /**
         * Creates a hierarchy op for deleting a root task
         *
         * @hide
         **/
        @NonNull
        public static HierarchyOp createForRemoveRootTask(@NonNull IBinder container) {
            return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_REMOVE_ROOT_TASK)
                    .setContainer(container)
                    .build();
        }

        /** Creates a hierarchy op for clearing adjacent root tasks. */
        @NonNull
        public static HierarchyOp createForClearAdjacentRoots(@NonNull IBinder root) {
@@ -2012,6 +2043,7 @@ public final class WindowContainerTransaction implements Parcelable {
                    return "removeInsetsFrameProvider";
                case HIERARCHY_OP_TYPE_SET_ALWAYS_ON_TOP: return "setAlwaysOnTop";
                case HIERARCHY_OP_TYPE_REMOVE_TASK: return "removeTask";
                case HIERARCHY_OP_TYPE_REMOVE_ROOT_TASK: return "removeRootTask";
                case HIERARCHY_OP_TYPE_FINISH_ACTIVITY: return "finishActivity";
                case HIERARCHY_OP_TYPE_CLEAR_ADJACENT_ROOTS: return "clearAdjacentRoots";
                case HIERARCHY_OP_TYPE_SET_REPARENT_LEAF_TASK_IF_RELAUNCH:
@@ -2096,6 +2128,9 @@ public final class WindowContainerTransaction implements Parcelable {
                case HIERARCHY_OP_TYPE_REMOVE_TASK:
                    sb.append("task=").append(mContainer);
                    break;
                case HIERARCHY_OP_TYPE_REMOVE_ROOT_TASK:
                    sb.append("rootTask=").append(mContainer);
                    break;
                case HIERARCHY_OP_TYPE_FINISH_ACTIVITY:
                    sb.append("activity=").append(mContainer);
                    break;
+18 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import static android.window.WindowContainerTransaction.Change.CHANGE_FOCUSABLE;
import static android.window.WindowContainerTransaction.Change.CHANGE_FORCE_TRANSLUCENT;
import static android.window.WindowContainerTransaction.Change.CHANGE_HIDDEN;
import static android.window.WindowContainerTransaction.Change.CHANGE_RELATIVE_BOUNDS;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REMOVE_ROOT_TASK;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_KEYGUARD_STATE;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_ADD_INSETS_FRAME_PROVIDER;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_ADD_TASK_FRAGMENT_OPERATION;
@@ -1131,6 +1132,23 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                }
                break;
            }
            case HIERARCHY_OP_TYPE_REMOVE_ROOT_TASK: {
                final WindowContainer wc = WindowContainer.fromBinder(hop.getContainer());
                if (wc == null || wc.asTask() == null || !wc.isAttached()
                        || !wc.asTask().isRootTask() || !wc.asTask().mCreatedByOrganizer) {
                    Slog.e(TAG, "Attempt to remove invalid task: " + wc);
                    break;
                }
                final Task task = wc.asTask();
                if (task.isVisibleRequested() || task.isVisible()) {
                    effects |= TRANSACT_EFFECTS_LIFECYCLE;
                }
                // Removes its leaves, but not itself.
                mService.mTaskSupervisor.removeRootTask(task);
                // Now that the root has no leaves, remove it too. .
                task.remove(true /* withTransition */, "remove-root-task-through-hierarchyOp");
                break;
            }
            case HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT: {
                final WindowContainer wc = WindowContainer.fromBinder(hop.getContainer());
                if (wc == null || !wc.isAttached()) {
+28 −0
Original line number Diff line number Diff line
@@ -78,6 +78,34 @@ public class WindowContainerTransactionTests extends WindowTestsBase {
        verify(mAtm.getLockTaskController(), atLeast(1)).clearLockedTask(rootTask);
    }

    @Test
    public void testRemoveRootTask() {
        final Task rootTask = createTask(mDisplayContent);
        final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
        final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
        final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();

        WindowContainerTransaction wct = new WindowContainerTransaction();
        WindowContainerToken token = rootTask.getTaskInfo().token;
        wct.removeTask(token);
        applyTransaction(wct);

        // There is still an activity to be destroyed, so the task is not removed immediately.
        assertNotNull(task.getParent());
        assertTrue(rootTask.hasChild());
        assertTrue(task.hasChild());
        assertTrue(activity.finishing);

        activity.destroyed("testRemoveRootTask");
        // Assert that the container was removed after the activity is destroyed.
        assertNull(task.getParent());
        assertEquals(0, task.getChildCount());
        assertNull(activity.getParent());
        assertNull(taskDisplayArea.getTask(task1 -> task1.mTaskId == rootTask.mTaskId));
        verify(mAtm.getLockTaskController(), atLeast(1)).clearLockedTask(task);
        verify(mAtm.getLockTaskController(), atLeast(1)).clearLockedTask(rootTask);
    }

    @Test
    public void testDesktopMode_tasksAreBroughtToFront() {
        final TestDesktopOrganizer desktopOrganizer = new TestDesktopOrganizer(mAtm);