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

Commit f4d6da9c authored by Gaurav Bhola's avatar Gaurav Bhola Committed by Android (Google) Code Review
Browse files

Merge "Support DisplayArea reordering via WindowContainerTransaction" into main

parents 4fa24d0b f622bbe9
Loading
Loading
Loading
Loading
+22 −6
Original line number Diff line number Diff line
@@ -1194,7 +1194,13 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                        }
                    }
                }
                effects |= sanitizeAndApplyHierarchyOp(wc, hop);
                if (wc.asTask() != null) {
                    effects |= sanitizeAndApplyHierarchyOpForTask(wc.asTask(), hop);
                } else if (wc.asDisplayArea() != null) {
                    effects |= sanitizeAndApplyHierarchyOpForDisplayArea(wc.asDisplayArea(), hop);
                } else {
                    throw new IllegalArgumentException("Invalid container in hierarchy op");
                }
                break;
            }
            case HIERARCHY_OP_TYPE_ADD_TASK_FRAGMENT_OPERATION: {
@@ -1850,12 +1856,22 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
        return starterResult[0];
    }

    private int sanitizeAndApplyHierarchyOp(WindowContainer container,
            WindowContainerTransaction.HierarchyOp hop) {
        final Task task = container.asTask();
        if (task == null) {
            throw new IllegalArgumentException("Invalid container in hierarchy op");
    private int sanitizeAndApplyHierarchyOpForDisplayArea(@NonNull DisplayArea displayArea,
            @NonNull WindowContainerTransaction.HierarchyOp hop) {
        if (hop.getType() != HIERARCHY_OP_TYPE_REORDER) {
            throw new UnsupportedOperationException("DisplayArea only supports reordering");
        }
        if (displayArea.getParent() == null) {
            return TRANSACT_EFFECTS_NONE;
        }
        displayArea.getParent().positionChildAt(
                hop.getToTop() ? POSITION_TOP : POSITION_BOTTOM,
                displayArea, hop.includingParents());
        return TRANSACT_EFFECTS_LIFECYCLE;
    }

    private int sanitizeAndApplyHierarchyOpForTask(@NonNull Task task,
            @NonNull WindowContainerTransaction.HierarchyOp hop) {
        final DisplayContent dc = task.getDisplayContent();
        if (dc == null) {
            Slog.w(TAG, "Container is no longer attached: " + task);
+67 −7
Original line number Diff line number Diff line
@@ -1488,7 +1488,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
    @Test
    public void testReorderWithParents() {
        /*
                  root
                  default TDA
               ____|______
               |         |
           firstTda    secondTda
@@ -1496,10 +1496,12 @@ public class WindowOrganizerTests extends WindowTestsBase {
         firstRootTask    secondRootTask

         */
        final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
        final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
                mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
        final TaskDisplayArea firstTaskDisplayArea = createTaskDisplayArea(
                mDisplayContent, mRootWindowContainer.mWmService, "FirstTaskDisplayArea",
                FEATURE_VENDOR_FIRST);
        final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
                mDisplayContent, mRootWindowContainer.mWmService, "SecondTaskDisplayArea",
                FEATURE_VENDOR_FIRST + 1);
        final Task firstRootTask = firstTaskDisplayArea.createRootTask(
                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
        final Task secondRootTask = secondTaskDisplayArea.createRootTask(
@@ -1508,9 +1510,6 @@ public class WindowOrganizerTests extends WindowTestsBase {
                .setTask(firstRootTask).build();
        final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
                .setTask(secondRootTask).build();
        // This assertion is just a defense to ensure that firstRootTask is not the top most
        // by default
        assertThat(mDisplayContent.getTopRootTask()).isEqualTo(secondRootTask);
        WindowContainerTransaction wct = new WindowContainerTransaction();

        // Reorder to top
@@ -1532,6 +1531,67 @@ public class WindowOrganizerTests extends WindowTestsBase {
        assertThat(mDisplayContent.getBottomMostTask()).isEqualTo(firstRootTask);
    }

    @Test
    public void testReorderDisplayArea() {
        /*
                  defaultTda
               ____|______
               |         |
           firstTda    secondTda
               |             |
         firstRootTask    secondRootTask

         */
        final TaskDisplayArea firstTaskDisplayArea = createTaskDisplayArea(
                mDisplayContent, mRootWindowContainer.mWmService, "FirstTaskDisplayArea",
                FEATURE_VENDOR_FIRST);
        final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
                mDisplayContent, mRootWindowContainer.mWmService, "SecondTaskDisplayArea",
                FEATURE_VENDOR_FIRST + 1);
        final Task firstRootTask = firstTaskDisplayArea.createRootTask(
                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
        final Task secondRootTask = secondTaskDisplayArea.createRootTask(
                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
        final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
                .setTask(firstRootTask).build();
        final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
                .setTask(secondRootTask).build();

        WindowContainerTransaction wct = new WindowContainerTransaction();

        // Reorder to top
        wct.reorder(firstTaskDisplayArea.mRemoteToken.toWindowContainerToken(), true /* onTop */,
                true /* includingParents */);
        mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
        assertThat(mDisplayContent.getTopRootTask()).isEqualTo(firstRootTask);

        // Reorder to bottom
        wct.reorder(firstTaskDisplayArea.mRemoteToken.toWindowContainerToken(), false /* onTop */,
                true /* includingParents */);
        mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
        assertThat(mDisplayContent.getBottomMostTask()).isEqualTo(firstRootTask);
    }

    @Test
    public void testReparentDisplayAreaUnsupported() {
        final TaskDisplayArea firstTaskDisplayArea = createTaskDisplayArea(
                mDisplayContent, mRootWindowContainer.mWmService, "FirstTaskDisplayArea",
                FEATURE_VENDOR_FIRST);
        final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
                mDisplayContent, mRootWindowContainer.mWmService, "SecondTaskDisplayArea",
                FEATURE_VENDOR_FIRST + 1);

        WindowContainerTransaction wct = new WindowContainerTransaction();
        wct.reparent(firstTaskDisplayArea.mRemoteToken.toWindowContainerToken(),
                secondTaskDisplayArea.mRemoteToken.toWindowContainerToken(),
                true /* onTop */
        );

        assertThrows(UnsupportedOperationException.class, () ->
                mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct)
        );
    }

    @Test
    public void testAppearDeferThenVanish() {
        final ITaskOrganizer organizer = registerMockOrganizer();