From d8ddd4c02334101ec62956eb632933b568dbd50e Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Mon, 9 Sep 2024 21:33:53 +0000 Subject: [PATCH] 2b/ Update launcher to use GroupedTaskInfos Bug: 346588978 Flag: EXEMPT adding new flag enable_shell_top_task_tracking Test: Build SystemUI & Launcher Test: atest WMShellUnitTests Change-Id: I1e41712d9f94649f4381d4235d8f2925df71e2b2 --- .../android/quickstep/RecentTasksList.java | 58 +++++++++---------- .../com/android/quickstep/SystemUiProxy.java | 10 ++-- .../com/android/quickstep/TopTaskTracker.java | 25 ++++---- .../quickstep/RecentTasksListTest.java | 32 +++++----- 4 files changed, 65 insertions(+), 60 deletions(-) diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java index a5cc32a1b1..714838a468 100644 --- a/quickstep/src/com/android/quickstep/RecentTasksList.java +++ b/quickstep/src/com/android/quickstep/RecentTasksList.java @@ -20,9 +20,9 @@ import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.quickstep.util.SplitScreenUtils.convertShellSplitBoundsToLauncher; -import static com.android.wm.shell.shared.GroupedRecentTaskInfo.TYPE_FREEFORM; +import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_FREEFORM; -import android.app.ActivityManager; +import android.app.ActivityManager.RunningTaskInfo; import android.app.KeyguardManager; import android.app.TaskInfo; import android.content.ComponentName; @@ -40,7 +40,7 @@ import com.android.quickstep.util.DesktopTask; import com.android.quickstep.util.GroupTask; import com.android.systemui.shared.recents.model.Task; import com.android.wm.shell.recents.IRecentTasksListener; -import com.android.wm.shell.shared.GroupedRecentTaskInfo; +import com.android.wm.shell.shared.GroupedTaskInfo; import com.android.wm.shell.shared.desktopmode.DesktopModeStatus; import java.io.PrintWriter; @@ -76,7 +76,7 @@ public class RecentTasksList { private @Nullable RecentsModel.RunningTasksListener mRunningTasksListener; private @Nullable RecentsModel.RecentTasksChangedListener mRecentTasksChangedListener; // Tasks are stored in order of least recently launched to most recently launched. - private ArrayList mRunningTasks; + private ArrayList mRunningTasks; public RecentTasksList(Context context, LooperExecutor mainThreadExecutor, KeyguardManager keyguardManager, SystemUiProxy sysUiProxy, @@ -93,35 +93,38 @@ public class RecentTasksList { } @Override - public void onRunningTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) { + public void onRunningTaskAppeared(RunningTaskInfo taskInfo) { mMainThreadExecutor.execute(() -> { RecentTasksList.this.onRunningTaskAppeared(taskInfo); }); } @Override - public void onRunningTaskVanished(ActivityManager.RunningTaskInfo taskInfo) { + public void onRunningTaskVanished(RunningTaskInfo taskInfo) { mMainThreadExecutor.execute(() -> { RecentTasksList.this.onRunningTaskVanished(taskInfo); }); } @Override - public void onRunningTaskChanged(ActivityManager.RunningTaskInfo taskInfo) { + public void onRunningTaskChanged(RunningTaskInfo taskInfo) { mMainThreadExecutor.execute(() -> { RecentTasksList.this.onRunningTaskChanged(taskInfo); }); } @Override - public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) { + public void onTaskMovedToFront(GroupedTaskInfo[] visibleTasks) { mMainThreadExecutor.execute(() -> { - topTaskTracker.onTaskMovedToFront(taskInfo); + // TODO(b/346588978): We currently are only sending a single task, but this will + // be updated once we send the full set of visible tasks + final TaskInfo info = visibleTasks[0].getTaskInfo1(); + topTaskTracker.handleTaskMovedToFront(info); }); } @Override - public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) { + public void onTaskInfoChanged(RunningTaskInfo taskInfo) { mMainThreadExecutor.execute(() -> topTaskTracker.onTaskChanged(taskInfo)); } }); @@ -250,7 +253,7 @@ public class RecentTasksList { mRecentTasksChangedListener = null; } - private void initRunningTasks(ArrayList runningTasks) { + private void initRunningTasks(ArrayList runningTasks) { // Tasks are retrieved in order of most recently launched/used to least recently launched. mRunningTasks = new ArrayList<>(runningTasks); Collections.reverse(mRunningTasks); @@ -259,13 +262,13 @@ public class RecentTasksList { /** * Gets the set of running tasks. */ - public ArrayList getRunningTasks() { + public ArrayList getRunningTasks() { return mRunningTasks; } - private void onRunningTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) { + private void onRunningTaskAppeared(RunningTaskInfo taskInfo) { // Make sure this task is not already in the list - for (ActivityManager.RunningTaskInfo existingTask : mRunningTasks) { + for (RunningTaskInfo existingTask : mRunningTasks) { if (taskInfo.taskId == existingTask.taskId) { return; } @@ -276,9 +279,9 @@ public class RecentTasksList { } } - private void onRunningTaskVanished(ActivityManager.RunningTaskInfo taskInfo) { + private void onRunningTaskVanished(RunningTaskInfo taskInfo) { // Find the task from the list of running tasks, if it exists - for (ActivityManager.RunningTaskInfo existingTask : mRunningTasks) { + for (RunningTaskInfo existingTask : mRunningTasks) { if (existingTask.taskId != taskInfo.taskId) continue; mRunningTasks.remove(existingTask); @@ -289,9 +292,9 @@ public class RecentTasksList { } } - private void onRunningTaskChanged(ActivityManager.RunningTaskInfo taskInfo) { + private void onRunningTaskChanged(RunningTaskInfo taskInfo) { // Find the task from the list of running tasks, if it exists - for (ActivityManager.RunningTaskInfo existingTask : mRunningTasks) { + for (RunningTaskInfo existingTask : mRunningTasks) { if (existingTask.taskId != taskInfo.taskId) continue; mRunningTasks.remove(existingTask); @@ -309,7 +312,7 @@ public class RecentTasksList { @VisibleForTesting TaskLoadResult loadTasksInBackground(int numTasks, int requestId, boolean loadKeysOnly) { int currentUserId = Process.myUserHandle().getIdentifier(); - ArrayList rawTasks; + ArrayList rawTasks; try { rawTasks = mSysUiProxy.getRecentTasks(numTasks, currentUserId); } catch (SystemUiProxy.GetRecentTasksException e) { @@ -332,7 +335,7 @@ public class RecentTasksList { TaskLoadResult allTasks = new TaskLoadResult(requestId, loadKeysOnly, rawTasks.size()); int numVisibleTasks = 0; - for (GroupedRecentTaskInfo rawTask : rawTasks) { + for (GroupedTaskInfo rawTask : rawTasks) { if (rawTask.getType() == TYPE_FREEFORM) { // TYPE_FREEFORM tasks is only created when desktop mode can be entered, // leftover TYPE_FREEFORM tasks created when flag was on should be ignored. @@ -344,14 +347,13 @@ public class RecentTasksList { } continue; } - ActivityManager.RecentTaskInfo taskInfo1 = rawTask.getTaskInfo1(); - ActivityManager.RecentTaskInfo taskInfo2 = rawTask.getTaskInfo2(); + TaskInfo taskInfo1 = rawTask.getTaskInfo1(); + TaskInfo taskInfo2 = rawTask.getTaskInfo2(); Task.TaskKey task1Key = new Task.TaskKey(taskInfo1); Task task1 = loadKeysOnly ? new Task(task1Key) : Task.from(task1Key, taskInfo1, tmpLockedUsers.get(task1Key.userId) /* isLocked */); - task1.setLastSnapshotData(taskInfo1); Task task2 = null; if (taskInfo2 != null) { // Is split task @@ -360,7 +362,6 @@ public class RecentTasksList { ? new Task(task2Key) : Task.from(task2Key, taskInfo2, tmpLockedUsers.get(task2Key.userId) /* isLocked */); - task2.setLastSnapshotData(taskInfo2); } else { // Is fullscreen task if (numVisibleTasks > 0) { @@ -384,17 +385,16 @@ public class RecentTasksList { return allTasks; } - private @Nullable DesktopTask createDesktopTask(GroupedRecentTaskInfo recentTaskInfo) { + private @Nullable DesktopTask createDesktopTask(GroupedTaskInfo recentTaskInfo) { ArrayList tasks = new ArrayList<>(recentTaskInfo.getTaskInfoList().size()); int[] minimizedTaskIds = recentTaskInfo.getMinimizedTaskIds(); if (minimizedTaskIds.length == recentTaskInfo.getTaskInfoList().size()) { // All Tasks are minimized -> don't create a DesktopTask return null; } - for (ActivityManager.RecentTaskInfo taskInfo : recentTaskInfo.getTaskInfoList()) { + for (TaskInfo taskInfo : recentTaskInfo.getTaskInfoList()) { Task.TaskKey key = new Task.TaskKey(taskInfo); Task task = Task.from(key, taskInfo, false); - task.setLastSnapshotData(taskInfo); task.positionInParent = taskInfo.positionInParent; task.appBounds = taskInfo.configuration.windowConfiguration.getAppBounds(); task.isVisible = taskInfo.isVisible; @@ -429,14 +429,14 @@ public class RecentTasksList { } writer.println(prefix + " ]"); int currentUserId = Process.myUserHandle().getIdentifier(); - ArrayList rawTasks; + ArrayList rawTasks; try { rawTasks = mSysUiProxy.getRecentTasks(Integer.MAX_VALUE, currentUserId); } catch (SystemUiProxy.GetRecentTasksException e) { rawTasks = new ArrayList<>(); } writer.println(prefix + " rawTasks=["); - for (GroupedRecentTaskInfo task : rawTasks) { + for (GroupedTaskInfo task : rawTasks) { TaskInfo taskInfo1 = task.getTaskInfo1(); TaskInfo taskInfo2 = task.getTaskInfo2(); ComponentName cn1 = taskInfo1.topActivity; diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index cd39c09fee..73e22bb1c6 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -91,7 +91,7 @@ import com.android.wm.shell.recents.IRecentTasks; import com.android.wm.shell.recents.IRecentTasksListener; import com.android.wm.shell.recents.IRecentsAnimationController; import com.android.wm.shell.recents.IRecentsAnimationRunner; -import com.android.wm.shell.shared.GroupedRecentTaskInfo; +import com.android.wm.shell.shared.GroupedTaskInfo; import com.android.wm.shell.shared.IShellTransitions; import com.android.wm.shell.shared.bubbles.BubbleBarLocation; import com.android.wm.shell.shared.desktopmode.DesktopModeStatus; @@ -1358,15 +1358,15 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle { * @throws GetRecentTasksException if IRecentTasks is not initialized, or when we get * RemoteException from server side */ - public ArrayList getRecentTasks(int numTasks, int userId) - throws GetRecentTasksException { + public ArrayList getRecentTasks(int numTasks, + int userId) throws GetRecentTasksException { if (mRecentTasks == null) { Log.e(TAG, "getRecentTasks() failed due to null mRecentTasks"); throw new GetRecentTasksException("null mRecentTasks"); } try { - final GroupedRecentTaskInfo[] rawTasks = mRecentTasks.getRecentTasks(numTasks, - RECENT_IGNORE_UNAVAILABLE, userId); + final GroupedTaskInfo[] rawTasks = + mRecentTasks.getRecentTasks(numTasks, RECENT_IGNORE_UNAVAILABLE, userId); if (rawTasks == null) { return new ArrayList<>(); } diff --git a/quickstep/src/com/android/quickstep/TopTaskTracker.java b/quickstep/src/com/android/quickstep/TopTaskTracker.java index 71b657348e..c9dfe6d19d 100644 --- a/quickstep/src/com/android/quickstep/TopTaskTracker.java +++ b/quickstep/src/com/android/quickstep/TopTaskTracker.java @@ -27,6 +27,7 @@ import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITIO import android.annotation.UserIdInt; import android.app.ActivityManager.RunningTaskInfo; +import android.app.TaskInfo; import android.content.Context; import androidx.annotation.NonNull; @@ -67,7 +68,7 @@ public class TopTaskTracker extends ISplitScreenListener.Stub private static final int HISTORY_SIZE = 5; // Ordered list with first item being the most recent task. - private final LinkedList mOrderedTaskList = new LinkedList<>(); + private final LinkedList mOrderedTaskList = new LinkedList<>(); private final Context mContext; private final SplitStageInfo mMainStagePosition = new SplitStageInfo(); @@ -96,6 +97,10 @@ public class TopTaskTracker extends ISplitScreenListener.Stub @Override public void onTaskMovedToFront(RunningTaskInfo taskInfo) { + handleTaskMovedToFront(taskInfo); + } + + public void handleTaskMovedToFront(TaskInfo taskInfo) { mOrderedTaskList.removeIf(rto -> rto.taskId == taskInfo.taskId); mOrderedTaskList.addFirst(taskInfo); @@ -103,7 +108,7 @@ public class TopTaskTracker extends ISplitScreenListener.Stub // display's task to the list, to avoid showing non-home display's task upon going to // Recents animation. if (taskInfo.displayId != DEFAULT_DISPLAY) { - final RunningTaskInfo topTaskOnHomeDisplay = mOrderedTaskList.stream() + final TaskInfo topTaskOnHomeDisplay = mOrderedTaskList.stream() .filter(rto -> rto.displayId == DEFAULT_DISPLAY).findFirst().orElse(null); if (topTaskOnHomeDisplay != null) { mOrderedTaskList.removeIf(rto -> rto.taskId == topTaskOnHomeDisplay.taskId); @@ -113,9 +118,9 @@ public class TopTaskTracker extends ISplitScreenListener.Stub if (mOrderedTaskList.size() >= HISTORY_SIZE) { // If we grow in size, remove the last taskInfo which is not part of the split task. - Iterator itr = mOrderedTaskList.descendingIterator(); + Iterator itr = mOrderedTaskList.descendingIterator(); while (itr.hasNext()) { - RunningTaskInfo info = itr.next(); + TaskInfo info = itr.next(); if (info.taskId != taskInfo.taskId && info.taskId != mMainStagePosition.taskId && info.taskId != mSideStagePosition.taskId) { @@ -215,13 +220,13 @@ public class TopTaskTracker extends ISplitScreenListener.Stub Collections.addAll(mOrderedTaskList, tasks); } - ArrayList tasks = new ArrayList<>(mOrderedTaskList); + ArrayList tasks = new ArrayList<>(mOrderedTaskList); // Strip the pinned task and recents task tasks.removeIf(t -> t.taskId == mPinnedTaskId || isRecentsTask(t)); return new CachedTaskInfo(tasks); } - private static boolean isRecentsTask(RunningTaskInfo task) { + private static boolean isRecentsTask(TaskInfo task) { return task != null && task.configuration.windowConfiguration .getActivityType() == ACTIVITY_TYPE_RECENTS; } @@ -233,10 +238,10 @@ public class TopTaskTracker extends ISplitScreenListener.Stub public static class CachedTaskInfo { @Nullable - private final RunningTaskInfo mTopTask; - public final List mAllCachedTasks; + private final TaskInfo mTopTask; + public final List mAllCachedTasks; - CachedTaskInfo(List allCachedTasks) { + CachedTaskInfo(List allCachedTasks) { mAllCachedTasks = allCachedTasks; mTopTask = allCachedTasks.isEmpty() ? null : allCachedTasks.get(0); } @@ -262,7 +267,7 @@ public class TopTaskTracker extends ISplitScreenListener.Stub // Not an excluded task. return null; } - List visibleNonExcludedTasks = mAllCachedTasks.stream() + List visibleNonExcludedTasks = mAllCachedTasks.stream() .filter(t -> t.isVisible && (t.baseIntent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0 && t.getActivityType() != ACTIVITY_TYPE_HOME diff --git a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java index 244b897de7..b3c486c9b1 100644 --- a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java +++ b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java @@ -28,7 +28,9 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.ActivityManager; +import android.app.ActivityManager.RecentTaskInfo; import android.app.KeyguardManager; +import android.app.TaskInfo; import android.content.Context; import android.content.res.Resources; @@ -39,7 +41,7 @@ import com.android.launcher3.util.LooperExecutor; import com.android.quickstep.util.GroupTask; import com.android.quickstep.views.TaskViewType; import com.android.systemui.shared.recents.model.Task; -import com.android.wm.shell.shared.GroupedRecentTaskInfo; +import com.android.wm.shell.shared.GroupedTaskInfo; import org.junit.Before; import org.junit.Test; @@ -91,8 +93,8 @@ public class RecentTasksListTest { @Test public void loadTasksInBackground_onlyKeys_noValidTaskDescription() throws Exception { - GroupedRecentTaskInfo recentTaskInfos = GroupedRecentTaskInfo.forSplitTasks( - new ActivityManager.RecentTaskInfo(), new ActivityManager.RecentTaskInfo(), null); + GroupedTaskInfo recentTaskInfos = GroupedTaskInfo.forSplitTasks( + new RecentTaskInfo(), new RecentTaskInfo(), null); when(mSystemUiProxy.getRecentTasks(anyInt(), anyInt())) .thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos))); @@ -119,12 +121,11 @@ public class RecentTasksListTest { @Test public void loadTasksInBackground_moreThanKeys_hasValidTaskDescription() throws Exception { String taskDescription = "Wheeee!"; - ActivityManager.RecentTaskInfo task1 = new ActivityManager.RecentTaskInfo(); + RecentTaskInfo task1 = new RecentTaskInfo(); task1.taskDescription = new ActivityManager.TaskDescription(taskDescription); - ActivityManager.RecentTaskInfo task2 = new ActivityManager.RecentTaskInfo(); + RecentTaskInfo task2 = new RecentTaskInfo(); task2.taskDescription = new ActivityManager.TaskDescription(); - GroupedRecentTaskInfo recentTaskInfos = GroupedRecentTaskInfo.forSplitTasks(task1, task2, - null); + GroupedTaskInfo recentTaskInfos = GroupedTaskInfo.forSplitTasks(task1, task2, null); when(mSystemUiProxy.getRecentTasks(anyInt(), anyInt())) .thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos))); @@ -138,11 +139,11 @@ public class RecentTasksListTest { @Test public void loadTasksInBackground_freeformTask_createsDesktopTask() throws Exception { - ActivityManager.RecentTaskInfo[] tasks = { + List tasks = Arrays.asList( createRecentTaskInfo(1 /* taskId */), createRecentTaskInfo(4 /* taskId */), - createRecentTaskInfo(5 /* taskId */)}; - GroupedRecentTaskInfo recentTaskInfos = GroupedRecentTaskInfo.forFreeformTasks( + createRecentTaskInfo(5 /* taskId */)); + GroupedTaskInfo recentTaskInfos = GroupedTaskInfo.forFreeformTasks( tasks, Collections.emptySet() /* minimizedTaskIds */); when(mSystemUiProxy.getRecentTasks(anyInt(), anyInt())) .thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos))); @@ -162,14 +163,13 @@ public class RecentTasksListTest { @Test public void loadTasksInBackground_freeformTask_onlyMinimizedTasks_doesNotCreateDesktopTask() throws Exception { - ActivityManager.RecentTaskInfo[] tasks = { + List tasks = Arrays.asList( createRecentTaskInfo(1 /* taskId */), createRecentTaskInfo(4 /* taskId */), - createRecentTaskInfo(5 /* taskId */)}; + createRecentTaskInfo(5 /* taskId */)); Set minimizedTaskIds = Arrays.stream(new Integer[]{1, 4, 5}).collect(Collectors.toSet()); - GroupedRecentTaskInfo recentTaskInfos = - GroupedRecentTaskInfo.forFreeformTasks(tasks, minimizedTaskIds); + GroupedTaskInfo recentTaskInfos = GroupedTaskInfo.forFreeformTasks(tasks, minimizedTaskIds); when(mSystemUiProxy.getRecentTasks(anyInt(), anyInt())) .thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos))); @@ -179,8 +179,8 @@ public class RecentTasksListTest { assertEquals(0, taskList.size()); } - private ActivityManager.RecentTaskInfo createRecentTaskInfo(int taskId) { - ActivityManager.RecentTaskInfo recentTaskInfo = new ActivityManager.RecentTaskInfo(); + private TaskInfo createRecentTaskInfo(int taskId) { + RecentTaskInfo recentTaskInfo = new RecentTaskInfo(); recentTaskInfo.taskId = taskId; return recentTaskInfo; }