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

Commit d425eee2 authored by Jorge Gil's avatar Jorge Gil
Browse files

Clear mPreferredTopFocusableRootTask when root becomes empty

In multi-desks, the focused root task may have its only child desktop
window reparented out into the back of another container, leaving the
empty root incorrectly set as focused. Clear the TDA preferred focusable
root task when this happens so that getFocusedRootTask() doesn't select
the empty task as the focused one.

Flag: com.android.window.flags.enable_multiple_desktops_backend
Bug: 420858253
Test: minimize the last task in a desk, then check dumpsys:
 1) mPreferredTopFocusableRootTask is the DesktopWallpaperActivity task
 2) Desk remains "active" in DesktopRepository and DesksOrganizer
Test: back-nav the last task in a desk (Gmail log in screen to force a
move to back instead a of a close) - verify the same as above

Change-Id: I0e7fb75a62bb8f8d1444e88e95904ba7224cc354
parent 325d92db
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -6293,6 +6293,12 @@ class Task extends TaskFragment {
    void onChildPositionChanged(WindowContainer child) {
        if (!mChildren.contains(child)) {
            dispatchTaskInfoChangedIfNeeded(false /* force */);
            if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue()
                    && mCreatedByOrganizer && mChildren.isEmpty() && getDisplayArea() != null
                    && getDisplayArea().mPreferredTopFocusableRootTask == this) {
                // An empty task cannot be focusable.
                getDisplayArea().clearPreferredTopFocusableRootTask();
            }
            return;
        }
        if (child.asTask() != null) {
+24 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import static com.android.server.wm.ActivityRecord.State.RESUMED;
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;
import static com.android.server.wm.TaskFragment.TASK_FRAGMENT_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
import static com.android.server.wm.WindowContainer.POSITION_TOP;

import static com.google.common.truth.Truth.assertThat;
@@ -185,6 +186,29 @@ public class TaskTests extends WindowTestsBase {
        assertFalse(rootTask.isAttached());
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
    public void testRemoveOnlyChildNestedTask_removesFocusFromRoot() {
        // A created-by-organizer root task at the bottom.
        final Task bottomRootTask = createTask(mDisplayContent);
        bottomRootTask.mCreatedByOrganizer = true;
        // Then a task with an activity on top of it.
        final Task middleTask = createTask(mDisplayContent);
        createActivityRecord(middleTask);
        // And a created-by-organizer root task with a child task with an activity.
        final Task topRootTask = createTask(mDisplayContent);
        topRootTask.mCreatedByOrganizer = true;
        final Task childTask = new TaskBuilder(mSupervisor).setParentTask(topRootTask).build();
        createActivityRecord(childTask);
        assertEquals(topRootTask, mDisplayContent.getFocusedRootTask());

        // Reparent the top leaf task to the bottom root task.
        childTask.reparent(bottomRootTask, POSITION_BOTTOM);

        // Root is now empty, so it can't be focused.
        assertNotEquals(topRootTask, mDisplayContent.getFocusedRootTask());
    }

    @Test
    public void testRemoveContainer_deferRemoval() {
        final Task rootTask = createTask(mDisplayContent);