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

Commit 3e822d83 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Shell: Make `RecentTasksController.getRecentTasks()` multi-desks aware" into main

parents 71c67e9f 5c90f115
Loading
Loading
Loading
Loading
+43 −19
Original line number Diff line number Diff line
@@ -47,20 +47,26 @@ public class GroupedTaskInfo implements Parcelable {

    public static final int TYPE_FULLSCREEN = 1;
    public static final int TYPE_SPLIT = 2;
    public static final int TYPE_FREEFORM = 3;
    public static final int TYPE_DESK = 3;
    public static final int TYPE_MIXED = 4;

    @IntDef(prefix = {"TYPE_"}, value = {
            TYPE_FULLSCREEN,
            TYPE_SPLIT,
            TYPE_FREEFORM,
            TYPE_DESK,
            TYPE_MIXED
    })
    public @interface GroupType {}

    /**
     * The ID of the desk that this `GroupedTaskInfo` represents (when the type is `TYPE_DESK`). The
     * value is -1 if this is not a desk.
     */
    private final int mDeskId;

    /**
     * The type of this particular task info, can be one of TYPE_FULLSCREEN, TYPE_SPLIT or
     * TYPE_FREEFORM.
     * TYPE_DESK.
     */
    @GroupType
    protected final int mType;
@@ -69,7 +75,7 @@ public class GroupedTaskInfo implements Parcelable {
     * The list of tasks associated with this single recent task info.
     * TYPE_FULLSCREEN: Contains the stack of tasks associated with a single "task" in overview
     * TYPE_SPLIT: Contains the two split roots of each side
     * TYPE_FREEFORM: Contains the set of tasks currently in freeform mode
     * TYPE_DESK: Contains the set of tasks currently in freeform mode contained in desk.
     */
    @Nullable
    protected final List<TaskInfo> mTasks;
@@ -83,7 +89,7 @@ public class GroupedTaskInfo implements Parcelable {
    protected final SplitBounds mSplitBounds;

    /**
     * Only set for TYPE_FREEFORM.
     * Only set for TYPE_DESK.
     *
     * TODO(b/348332802): move isMinimized inside each Task object instead once we have a
     *  replacement for RecentTaskInfo
@@ -103,8 +109,8 @@ public class GroupedTaskInfo implements Parcelable {
     * Create new for a stack of fullscreen tasks
     */
    public static GroupedTaskInfo forFullscreenTasks(@NonNull TaskInfo task) {
        return new GroupedTaskInfo(List.of(task), null, TYPE_FULLSCREEN,
                null /* minimizedFreeformTasks */);
        return new GroupedTaskInfo(/* deskId = */ -1, List.of(task), null, TYPE_FULLSCREEN,
                /* minimizedFreeformTaskIds = */ null);
    }

    /**
@@ -112,18 +118,19 @@ public class GroupedTaskInfo implements Parcelable {
     */
    public static GroupedTaskInfo forSplitTasks(@NonNull TaskInfo task1,
                    @NonNull TaskInfo task2, @NonNull SplitBounds splitBounds) {
        return new GroupedTaskInfo(List.of(task1, task2), splitBounds, TYPE_SPLIT,
                null /* minimizedFreeformTasks */);
        return new GroupedTaskInfo(/* deskId = */ -1, List.of(task1, task2), splitBounds,
                TYPE_SPLIT, /* minimizedFreeformTaskIds = */ null);
    }

    /**
     * Create new for a group of freeform tasks
     * Create new for a group of freeform tasks that belong to a single desk.
     */
    public static GroupedTaskInfo forFreeformTasks(
    public static GroupedTaskInfo forDeskTasks(
            int deskId,
            @NonNull List<TaskInfo> tasks,
                    @NonNull Set<Integer> minimizedFreeformTasks) {
        return new GroupedTaskInfo(tasks, null /* splitBounds */, TYPE_FREEFORM,
                minimizedFreeformTasks.stream().mapToInt(i -> i).toArray());
            @NonNull Set<Integer> minimizedFreeformTaskIds) {
        return new GroupedTaskInfo(deskId, tasks, /* splitBounds = */ null, TYPE_DESK,
                minimizedFreeformTaskIds.stream().mapToInt(i -> i).toArray());
    }

    /**
@@ -141,10 +148,12 @@ public class GroupedTaskInfo implements Parcelable {
    }

    private GroupedTaskInfo(
            int deskId,
            @NonNull List<TaskInfo> tasks,
            @Nullable SplitBounds splitBounds,
            @GroupType int type,
            @Nullable int[] minimizedFreeformTaskIds) {
        mDeskId = deskId;
        mTasks = tasks;
        mGroupedTasks = null;
        mSplitBounds = splitBounds;
@@ -154,6 +163,7 @@ public class GroupedTaskInfo implements Parcelable {
    }

    private GroupedTaskInfo(@NonNull List<GroupedTaskInfo> groupedTasks) {
        mDeskId = -1;
        mTasks = null;
        mGroupedTasks = groupedTasks;
        mSplitBounds = null;
@@ -174,6 +184,7 @@ public class GroupedTaskInfo implements Parcelable {
    }

    protected GroupedTaskInfo(@NonNull Parcel parcel) {
        mDeskId = parcel.readInt();
        mTasks = new ArrayList();
        final int numTasks = parcel.readInt();
        for (int i = 0; i < numTasks; i++) {
@@ -273,6 +284,16 @@ public class GroupedTaskInfo implements Parcelable {
        return mSplitBounds;
    }

    /**
     * Returns the ID of the desk represented by `this` if the type is `TYPE_DESK`, or -1 otherwise.
     */
    public int getDeskId() {
        if (mType == TYPE_MIXED) {
            throw new IllegalStateException("No desk ID for a mixed task");
        }
        return mDeskId;
    }

    /**
     * Get type of this recents entry. One of {@link GroupType}.
     * Note: This is deprecated, callers should use `isBaseType()` and not make assumptions about
@@ -285,7 +306,7 @@ public class GroupedTaskInfo implements Parcelable {
    }

    /**
     * Returns the set of minimized task ids, only valid for TYPE_FREEFORM.
     * Returns the set of minimized task ids, only valid for TYPE_DESK.
     */
    @Nullable
    public int[] getMinimizedTaskIds() {
@@ -301,7 +322,8 @@ public class GroupedTaskInfo implements Parcelable {
            return false;
        }
        GroupedTaskInfo other = (GroupedTaskInfo) obj;
        return mType == other.mType
        return mDeskId == other.mDeskId
                && mType == other.mType
                && Objects.equals(mTasks, other.mTasks)
                && Objects.equals(mGroupedTasks, other.mGroupedTasks)
                && Objects.equals(mSplitBounds, other.mSplitBounds)
@@ -310,7 +332,7 @@ public class GroupedTaskInfo implements Parcelable {

    @Override
    public int hashCode() {
        return Objects.hash(mType, mTasks, mGroupedTasks, mSplitBounds,
        return Objects.hash(mDeskId, mType, mTasks, mGroupedTasks, mSplitBounds,
                Arrays.hashCode(mMinimizedTaskIds));
    }

@@ -322,6 +344,7 @@ public class GroupedTaskInfo implements Parcelable {
                    .map(GroupedTaskInfo::toString)
                    .collect(Collectors.joining(",\n\t", "[\n\t", "\n]")));
        } else {
            taskString.append("Desk ID= ").append(mDeskId).append(", ");
            taskString.append("Tasks=" + mTasks.stream()
                    .map(taskInfo -> getTaskInfoDumpString(taskInfo))
                    .collect(Collectors.joining(", ", "[", "]")));
@@ -353,6 +376,7 @@ public class GroupedTaskInfo implements Parcelable {

    @Override
    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeInt(mDeskId);
        // We don't use the parcel list methods because we want to only write the TaskInfo state
        // and not the subclasses (Recents/RunningTaskInfo) whose fields are all deprecated
        final int tasksSize = mTasks != null ? mTasks.size() : 0;
@@ -375,7 +399,7 @@ public class GroupedTaskInfo implements Parcelable {
        return switch (type) {
            case TYPE_FULLSCREEN -> "FULLSCREEN";
            case TYPE_SPLIT -> "SPLIT";
            case TYPE_FREEFORM -> "FREEFORM";
            case TYPE_DESK -> "DESK";
            case TYPE_MIXED -> "MIXED";
            default -> "UNKNOWN";
        };
+3 −0
Original line number Diff line number Diff line
@@ -217,6 +217,9 @@ class DesktopRepository(
    fun getDeskIds(displayId: Int): Set<Int> =
        desktopData.desksSequence(displayId).map { desk -> desk.deskId }.toSet()

    /** Returns all the ids of all desks in all displays. */
    fun getAllDeskIds(): Set<Int> = desktopData.desksSequence().map { desk -> desk.deskId }.toSet()

    /** Returns the id of the default desk in the given display. */
    fun getDefaultDeskId(displayId: Int): Int? = getDefaultDesk(displayId)?.deskId

+109 −19
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import android.os.Bundle;
import android.os.RemoteException;
import android.util.Slog;
import android.util.SparseIntArray;
import android.window.DesktopExperienceFlags;
import android.window.DesktopModeFlags;
import android.window.WindowContainerToken;

@@ -92,6 +93,11 @@ public class RecentTasksController implements TaskStackListenerCallback,
        TaskStackTransitionObserver.TaskStackTransitionObserverListener, UserChangeListener {
    private static final String TAG = RecentTasksController.class.getSimpleName();

    // When the multiple desktops feature is disabled, all freeform tasks are lumped together into
    // a single `GroupedTaskInfo` whose type is `TYPE_DESK`, and its `mDeskId` doesn't matter, so
    // we pick the below arbitrary value.
    private static final int INVALID_DESK_ID = -1;

    private final Context mContext;
    private final ShellController mShellController;
    private final ShellCommandHandler mShellCommandHandler;
@@ -128,6 +134,7 @@ public class RecentTasksController implements TaskStackListenerCallback,

    // Temporary vars used in `generateList()`
    private final Map<Integer, TaskInfo> mTmpRemaining = new HashMap<>();
    private final Map<Integer, Desk> mTmpDesks = new HashMap<>();

    /**
     * Creates {@link RecentTasksController}, returns {@code null} if the feature is not
@@ -528,6 +535,78 @@ public class RecentTasksController implements TaskStackListenerCallback,
        return false;
    }

    /**
     * Represents a desk whose ID is `mDeskId` and contains the tasks in `mDeskTasks`. Some of these
     * tasks are minimized and their IDs are contained in the `mMinimizedDeskTasks` set.
     */
    private static class Desk {
        final int mDeskId;
        boolean mHasVisibleTasks = false;
        final ArrayList<TaskInfo> mDeskTasks = new ArrayList<>();
        final Set<Integer> mMinimizedDeskTasks = new HashSet<>();

        Desk(int deskId) {
            mDeskId = deskId;
        }

        void addTask(TaskInfo taskInfo, boolean isMinimized, boolean isVisible) {
            mDeskTasks.add(taskInfo);
            if (isMinimized) {
                mMinimizedDeskTasks.add(taskInfo.taskId);
            }
            mHasVisibleTasks |= isVisible;
        }

        boolean hasTasks() {
            return !mDeskTasks.isEmpty();
        }

        GroupedTaskInfo createDeskTaskInfo() {
            return GroupedTaskInfo.forDeskTasks(mDeskId, mDeskTasks, mMinimizedDeskTasks);
        }
    }

    /**
     * Clears the `mTmpDesks` map, and re-initializes it with the current state of desks from all
     * displays, without adding any desk tasks. This is a preparation step so that tasks can be
     * added to these desks in `generateList()`.
     *
     * This is needed since with the `ENABLE_MULTIPLE_DESKTOPS_BACKEND` flag, we want to include
     * desk even if they're empty (i.e. have no tasks).
     *
     * @param multipleDesktopsEnabled whether the multiple desktops backend feature is enabled.
     */
    private void initializeDesksMap(boolean multipleDesktopsEnabled) {
        mTmpDesks.clear();

        if (DesktopModeStatus.canEnterDesktopMode(mContext)
                && mDesktopUserRepositories.isPresent()) {
            if (multipleDesktopsEnabled) {
                for (var deskId : mDesktopUserRepositories.get().getCurrent().getAllDeskIds()) {
                    getOrCreateDesk(deskId);
                }
            } else {
                // When the multiple desks feature is disabled, we lump all freeform windows in a
                // single `GroupedTaskInfo` regardless of their display. The `deskId` in this case
                // doesn't matter and can be any arbitrary value.
                getOrCreateDesk(/* deskId = */ INVALID_DESK_ID);
            }
        }
    }

    /**
     * Returns the `Desk` whose ID is `deskId` from the `mTmpDesks` map if it exists, or it creates
     * one and adds it to the map and then returns it.
     */
    private Desk getOrCreateDesk(int deskId) {
        var desk = mTmpDesks.get(deskId);
        if (desk == null) {
            desk = new Desk(deskId);
            mTmpDesks.put(deskId, desk);
        }
        return desk;
    }

    /**
     * Generates a list of GroupedTaskInfos for the given raw list of tasks (either recents or
     * running tasks).
@@ -555,6 +634,14 @@ public class RecentTasksController implements TaskStackListenerCallback,
            ProtoLog.v(WM_SHELL_TASK_OBSERVER, "RecentTasksController.generateList(%s)", reason);
        }

        final boolean multipleDesktopsEnabled =
                DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue();
        initializeDesksMap(multipleDesktopsEnabled);

        // When the multiple desktops feature is enabled, we include all desks even if they're
        // empty.
        final boolean shouldIncludeEmptyDesktops = multipleDesktopsEnabled;

        // Make a mapping of task id -> task info for the remaining tasks to be processed, this
        // mapping is used to keep track of split tasks that may exist later in the task list that
        // should be ignored because they've already been grouped
@@ -566,11 +653,7 @@ public class RecentTasksController implements TaskStackListenerCallback,
        ArrayList<GroupedTaskInfo> groupedTasks = new ArrayList<>(tasks.size());
        ArrayList<GroupedTaskInfo> visibleGroupedTasks = new ArrayList<>();

        // Phase 1: Extract the desktop and visible fullscreen/split tasks. We make new collections
        // here as the GroupedTaskInfo can store them without copying
        ArrayList<TaskInfo> desktopTasks = new ArrayList<>();
        Set<Integer> minimizedDesktopTasks = new HashSet<>();
        boolean desktopTasksVisible = false;
        // Phase 1: Extract the desktops and visible fullscreen/split tasks.
        for (int i = 0; i < tasks.size(); i++) {
            final TaskInfo taskInfo = tasks.get(i);
            final int taskId = taskInfo.taskId;
@@ -600,11 +683,15 @@ public class RecentTasksController implements TaskStackListenerCallback,
                    taskInfo.positionInParent = new Point(taskInfo.lastNonFullscreenBounds.left,
                            taskInfo.lastNonFullscreenBounds.top);
                }
                desktopTasks.add(taskInfo);
                if (mDesktopUserRepositories.get().getCurrent().isMinimizedTask(taskId)) {
                    minimizedDesktopTasks.add(taskId);
                }
                desktopTasksVisible |= mVisibleTasksMap.containsKey(taskId);
                // Lump all freeform tasks together as if they were all in a single desk whose ID is
                // `INVALID_DESK_ID` when the multiple desktops feature is disabled.
                final int deskId = multipleDesktopsEnabled
                        ? mDesktopUserRepositories.get().getCurrent().getDeskIdForTask(taskId)
                        : INVALID_DESK_ID;
                final Desk desk = getOrCreateDesk(deskId);
                desk.addTask(taskInfo,
                        mDesktopUserRepositories.get().getCurrent().isMinimizedTask(taskId),
                        mVisibleTasksMap.containsKey(taskId));
                mTmpRemaining.remove(taskId);
                continue;
            }
@@ -636,9 +723,10 @@ public class RecentTasksController implements TaskStackListenerCallback,
        if (enableShellTopTaskTracking()) {
            // Phase 2: If there were desktop tasks and they are visible, add them to the visible
            //          list as well (the actual order doesn't matter for Overview)
            if (!desktopTasks.isEmpty() && desktopTasksVisible) {
                visibleGroupedTasks.add(
                        GroupedTaskInfo.forFreeformTasks(desktopTasks, minimizedDesktopTasks));
            for (var desk : mTmpDesks.values()) {
                if (desk.mHasVisibleTasks) {
                    visibleGroupedTasks.add(desk.createDeskTaskInfo());
                }
            }

            if (!visibleGroupedTasks.isEmpty()) {
@@ -674,16 +762,18 @@ public class RecentTasksController implements TaskStackListenerCallback,
            // Phase 5: If there were desktop tasks and they are not visible (ie. weren't added
            //          above), add them to the end of the final list (the actual order doesn't
            //          matter for Overview)
            if (!desktopTasks.isEmpty() && !desktopTasksVisible) {
                groupedTasks.add(
                        GroupedTaskInfo.forFreeformTasks(desktopTasks, minimizedDesktopTasks));
            for (var desk : mTmpDesks.values()) {
                if (!desk.mHasVisibleTasks && (desk.hasTasks() || shouldIncludeEmptyDesktops)) {
                    groupedTasks.add(desk.createDeskTaskInfo());
                }
            }
            dumpGroupedTasks(groupedTasks, "Phase 5");
        } else {
            // Add the desktop tasks at the end of the list
            if (!desktopTasks.isEmpty()) {
                groupedTasks.add(
                        GroupedTaskInfo.forFreeformTasks(desktopTasks, minimizedDesktopTasks));
            for (var desk : mTmpDesks.values()) {
                if (desk.hasTasks() || shouldIncludeEmptyDesktops) {
                    groupedTasks.add(desk.createDeskTaskInfo());
                }
            }
        }

+28 −23
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ import android.window.WindowContainerToken
import androidx.test.filters.SmallTest
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.shared.GroupedTaskInfo
import com.android.wm.shell.shared.GroupedTaskInfo.TYPE_FREEFORM
import com.android.wm.shell.shared.GroupedTaskInfo.TYPE_DESK
import com.android.wm.shell.shared.GroupedTaskInfo.TYPE_FULLSCREEN
import com.android.wm.shell.shared.GroupedTaskInfo.TYPE_SPLIT
import com.android.wm.shell.shared.split.SplitBounds
@@ -87,14 +87,14 @@ class GroupedTaskInfoTest : ShellTestCase() {
    }

    @Test
    fun testFreeformTasks_hasCorrectType() {
        assertThat(freeformTasksGroupInfo(freeformTaskIds = arrayOf(1)).isBaseType(TYPE_FREEFORM))
    fun testDeskTasks_hasCorrectType() {
        assertThat(deskTasksGroupInfo(deskId = 0, freeformTaskIds = arrayOf(1)).isBaseType(TYPE_DESK))
            .isTrue()
    }

    @Test
    fun testCreateFreeformTasks_hasCorrectNumberOfTasks() {
        val list = freeformTasksGroupInfo(freeformTaskIds = arrayOf(1, 2, 3)).taskInfoList
    fun testCreateDeskTasks_hasCorrectNumberOfTasks() {
        val list = deskTasksGroupInfo(deskId = 0, freeformTaskIds = arrayOf(1, 2, 3)).taskInfoList
        assertThat(list).hasSize(3)
        assertThat(list[0].taskId).isEqualTo(1)
        assertThat(list[1].taskId).isEqualTo(2)
@@ -102,9 +102,9 @@ class GroupedTaskInfoTest : ShellTestCase() {
    }

    @Test
    fun testCreateFreeformTasks_nonExistentMinimizedTaskId_throwsException() {
    fun testCreateDeskTasks_nonExistentMinimizedTaskId_throwsException() {
        assertThrows(IllegalArgumentException::class.java) {
            freeformTasksGroupInfo(
            deskTasksGroupInfo(deskId = 0,
                freeformTaskIds = arrayOf(1, 2, 3),
                minimizedTaskIds = arrayOf(1, 4)
            )
@@ -122,8 +122,8 @@ class GroupedTaskInfoTest : ShellTestCase() {
    }

    @Test
    fun testMixedWithFreeformBase_hasCorrectType() {
        assertThat(mixedTaskGroupInfoWithFreeformBase().isBaseType(TYPE_FREEFORM)).isTrue()
    fun testMixedWithDeskBase_hasCorrectType() {
        assertThat(mixedTaskGroupInfoWithDeskBase().isBaseType(TYPE_DESK)).isTrue()
    }

    @Test
@@ -190,15 +190,16 @@ class GroupedTaskInfoTest : ShellTestCase() {
    }

    @Test
    fun testParcelling_freeformTasks() {
        val taskInfo = freeformTasksGroupInfo(freeformTaskIds = arrayOf(1, 2, 3))
    fun testParcelling_DeskTasks() {
        val taskInfo = deskTasksGroupInfo(deskId = 50, freeformTaskIds = arrayOf(1, 2, 3))
        val parcel = Parcel.obtain()
        taskInfo.writeToParcel(parcel, 0)
        parcel.setDataPosition(0)
        // Read the object back from the parcel
        val taskInfoFromParcel: GroupedTaskInfo =
            GroupedTaskInfo.CREATOR.createFromParcel(parcel)
        assertThat(taskInfoFromParcel.isBaseType(TYPE_FREEFORM)).isTrue()
        assertThat(taskInfoFromParcel.deskId).isEqualTo(taskInfo.deskId)
        assertThat(taskInfoFromParcel.isBaseType(TYPE_DESK)).isTrue()
        assertThat(taskInfoFromParcel.taskInfoList).hasSize(3)
        // Only compare task ids
        val taskIdComparator = Correspondence.transforming<TaskInfo, Int>(
@@ -209,8 +210,8 @@ class GroupedTaskInfoTest : ShellTestCase() {
    }

    @Test
    fun testParcelling_freeformTasks_minimizedTasks() {
        val taskInfo = freeformTasksGroupInfo(
    fun testParcelling_DeskTasks_minimizedTasks() {
        val taskInfo = deskTasksGroupInfo(deskId = 0,
            freeformTaskIds = arrayOf(1, 2, 3), minimizedTaskIds = arrayOf(2))

        val parcel = Parcel.obtain()
@@ -220,14 +221,14 @@ class GroupedTaskInfoTest : ShellTestCase() {
        // Read the object back from the parcel
        val taskInfoFromParcel: GroupedTaskInfo =
            GroupedTaskInfo.CREATOR.createFromParcel(parcel)
        assertThat(taskInfoFromParcel.isBaseType(TYPE_FREEFORM)).isTrue()
        assertThat(taskInfoFromParcel.isBaseType(TYPE_DESK)).isTrue()
        assertThat(taskInfoFromParcel.minimizedTaskIds).isEqualTo(arrayOf(2).toIntArray())
    }

    @Test
    fun testParcelling_mixedTasks() {
        val taskInfo = GroupedTaskInfo.forMixed(listOf(
                freeformTasksGroupInfo(freeformTaskIds = arrayOf(4, 5, 6),
                deskTasksGroupInfo(deskId = 0, freeformTaskIds = arrayOf(4, 5, 6),
                    minimizedTaskIds = arrayOf(5)),
                splitTasksGroupInfo(firstId = 2, secondId = 3),
                singleTaskGroupInfo(id = 1)))
@@ -239,7 +240,7 @@ class GroupedTaskInfoTest : ShellTestCase() {
        // Read the object back from the parcel
        val taskInfoFromParcel: GroupedTaskInfo =
            GroupedTaskInfo.CREATOR.createFromParcel(parcel)
        assertThat(taskInfoFromParcel.isBaseType(TYPE_FREEFORM)).isTrue()
        assertThat(taskInfoFromParcel.isBaseType(TYPE_DESK)).isTrue()
        assertThat(taskInfoFromParcel.baseGroupedTask.minimizedTaskIds).isEqualTo(
            arrayOf(5).toIntArray())
        for (i in 1..6) {
@@ -275,12 +276,14 @@ class GroupedTaskInfoTest : ShellTestCase() {
    }

    @Test
    fun testTaskProperties_freeformTasks() {
    fun testTaskProperties_DeskTasks() {
        val task1 = createTaskInfo(id = 1)
        val task2 = createTaskInfo(id = 2)

        val taskInfo = GroupedTaskInfo.forFreeformTasks(listOf(task1, task2), setOf())
        val taskInfo = GroupedTaskInfo.forDeskTasks(
            /* deskId = */ 500, listOf(task1, task2), setOf())

        assertThat(taskInfo.deskId).isEqualTo(500)
        assertThat(taskInfo.getTaskById(1)).isEqualTo(task1)
        assertThat(taskInfo.getTaskById(2)).isEqualTo(task2)
        assertThat(taskInfo.containsTask(1)).isTrue()
@@ -325,11 +328,13 @@ class GroupedTaskInfoTest : ShellTestCase() {
        return GroupedTaskInfo.forSplitTasks(task1, task2, splitBounds)
    }

    private fun freeformTasksGroupInfo(
    private fun deskTasksGroupInfo(
        deskId: Int,
        freeformTaskIds: Array<Int>,
        minimizedTaskIds: Array<Int> = emptyArray()
    ): GroupedTaskInfo {
        return GroupedTaskInfo.forFreeformTasks(
        return GroupedTaskInfo.forDeskTasks(
            deskId,
            freeformTaskIds.map { createTaskInfo(it) }.toList(),
            minimizedTaskIds.toSet())
    }
@@ -346,9 +351,9 @@ class GroupedTaskInfoTest : ShellTestCase() {
            singleTaskGroupInfo(id = 1)))
    }

    private fun mixedTaskGroupInfoWithFreeformBase(): GroupedTaskInfo {
    private fun mixedTaskGroupInfoWithDeskBase(): GroupedTaskInfo {
        return GroupedTaskInfo.forMixed(listOf(
            freeformTasksGroupInfo(freeformTaskIds = arrayOf(2, 3, 4)),
            deskTasksGroupInfo(deskId = 0, freeformTaskIds = arrayOf(2, 3, 4)),
            singleTaskGroupInfo(id = 1)))
    }
}
+4 −4
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE;
import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_FREEFORM;
import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_DESK;
import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_FULLSCREEN;
import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_SPLIT;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_50_50;
@@ -349,7 +349,7 @@ public class RecentTasksControllerTest extends ShellTestCase {
        GroupedTaskInfo freeformGroup = recentTasks.get(2);

        // Check that groups have expected types
        assertTrue(freeformGroup.isBaseType(TYPE_FREEFORM));
        assertTrue(freeformGroup.isBaseType(TYPE_DESK));
        assertTrue(singleGroup1.isBaseType(TYPE_FULLSCREEN));
        assertTrue(singleGroup2.isBaseType(TYPE_FULLSCREEN));

@@ -389,7 +389,7 @@ public class RecentTasksControllerTest extends ShellTestCase {

        // Check that groups have expected types
        assertTrue(splitGroup.isBaseType(TYPE_SPLIT));
        assertTrue(freeformGroup.isBaseType(TYPE_FREEFORM));
        assertTrue(freeformGroup.isBaseType(TYPE_DESK));
        assertTrue(singleGroup.isBaseType(TYPE_FULLSCREEN));

        // Check freeform group entries
@@ -460,7 +460,7 @@ public class RecentTasksControllerTest extends ShellTestCase {
        GroupedTaskInfo freeformGroup = recentTasks.get(2);

        // Check that groups have expected types
        assertTrue(freeformGroup.isBaseType(TYPE_FREEFORM));
        assertTrue(freeformGroup.isBaseType(TYPE_DESK));
        assertTrue(singleGroup1.isBaseType(TYPE_FULLSCREEN));
        assertTrue(singleGroup2.isBaseType(TYPE_FULLSCREEN));