Allow getTasks to filter tasks by displayId.

Bug: 236099098
Test: atest WmTests:RunningTasksTest WmTests:RecentTasksTest
Change-Id: I4fe5955a075f1482df3acdff8baefc7126ef9bd0
diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java
index 6fc0c26..f17d5b7 100644
--- a/core/java/android/app/ActivityTaskManager.java
+++ b/core/java/android/app/ActivityTaskManager.java
@@ -16,6 +16,8 @@
 
 package android.app;
 
+import static android.view.Display.INVALID_DISPLAY;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
@@ -369,7 +371,8 @@
      * @hide
      */
     public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
-        return getTasks(maxNum, false /* filterForVisibleRecents */);
+        return getTasks(maxNum, false /* filterForVisibleRecents */, false /* keepIntentExtra */,
+                INVALID_DISPLAY);
     }
 
     /**
@@ -378,7 +381,8 @@
      */
     public List<ActivityManager.RunningTaskInfo> getTasks(
             int maxNum, boolean filterOnlyVisibleRecents) {
-        return getTasks(maxNum, filterOnlyVisibleRecents, false /* keepIntentExtra */);
+        return getTasks(maxNum, filterOnlyVisibleRecents, false /* keepIntentExtra */,
+                INVALID_DISPLAY);
     }
 
     /**
@@ -388,8 +392,20 @@
      */
     public List<ActivityManager.RunningTaskInfo> getTasks(
             int maxNum, boolean filterOnlyVisibleRecents, boolean keepIntentExtra) {
+        return getTasks(maxNum, filterOnlyVisibleRecents, keepIntentExtra, INVALID_DISPLAY);
+    }
+
+    /**
+     * @return List of running tasks that can be filtered by visibility and displayId in recents
+     * and keep intent extra.
+     * @param displayId the target display id, or {@link INVALID_DISPLAY} not to filter by displayId
+     * @hide
+     */
+    public List<ActivityManager.RunningTaskInfo> getTasks(
+            int maxNum, boolean filterOnlyVisibleRecents, boolean keepIntentExtra, int displayId) {
         try {
-            return getService().getTasks(maxNum, filterOnlyVisibleRecents, keepIntentExtra);
+            return getService().getTasks(maxNum, filterOnlyVisibleRecents, keepIntentExtra,
+                    displayId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index dc6825c..5f2d518 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -157,7 +157,7 @@
     boolean removeTask(int taskId);
     void removeAllVisibleRecentTasks();
     List<ActivityManager.RunningTaskInfo> getTasks(int maxNum, boolean filterOnlyVisibleRecents,
-            boolean keepIntentExtra);
+            boolean keepIntentExtra, int displayId);
     void moveTaskToFront(in IApplicationThread app, in String callingPackage, int task,
             int flags, in Bundle options);
     ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
diff --git a/services/core/java/com/android/server/app/GameTaskInfoProvider.java b/services/core/java/com/android/server/app/GameTaskInfoProvider.java
index f078d98..25a4f37 100644
--- a/services/core/java/com/android/server/app/GameTaskInfoProvider.java
+++ b/services/core/java/com/android/server/app/GameTaskInfoProvider.java
@@ -16,6 +16,8 @@
 
 package com.android.server.app;
 
+import static android.view.Display.INVALID_DISPLAY;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager.RunningTaskInfo;
@@ -93,7 +95,8 @@
             runningTaskInfos = mActivityTaskManager.getTasks(
                     /* maxNum= */ Integer.MAX_VALUE,
                     /* filterOnlyVisibleRecents= */ false,
-                    /* keepIntentExtra= */ false);
+                    /* keepIntentExtra= */ false,
+                    INVALID_DISPLAY);
         } catch (RemoteException ex) {
             Slog.w(TAG, "Failed to fetch running tasks");
             return null;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 9d8e087..0d5ab10 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -2309,16 +2309,25 @@
      * @return a list of {@link ActivityManager.RunningTaskInfo} with up to {@code maxNum} items
      */
     public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
-        return getTasks(maxNum, false /* filterForVisibleRecents */, false /* keepIntentExtra */);
+        return getTasks(maxNum, false /* filterForVisibleRecents */, false /* keepIntentExtra */,
+                INVALID_DISPLAY);
     }
 
     /**
      * @param filterOnlyVisibleRecents whether to filter the tasks based on whether they would ever
      *                                 be visible in the recent task list in systemui
      */
-    @Override
     public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum,
             boolean filterOnlyVisibleRecents, boolean keepIntentExtra) {
+        return getTasks(maxNum, filterOnlyVisibleRecents, keepIntentExtra, INVALID_DISPLAY);
+    }
+
+    /**
+     * @param displayId the target display id, or {@link INVALID_DISPLAY} not to filter by displayId
+     */
+    @Override
+    public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum,
+            boolean filterOnlyVisibleRecents, boolean keepIntentExtra, int displayId) {
         final int callingUid = Binder.getCallingUid();
         final int callingPid = Binder.getCallingPid();
 
@@ -2340,7 +2349,7 @@
             final boolean allowed = isGetTasksAllowed("getTasks", callingPid, callingUid);
             flags |= (allowed ? RunningTasks.FLAG_ALLOWED : 0);
             mRootWindowContainer.getRunningTasks(
-                    maxNum, list, flags, callingUid, callingProfileIds);
+                    maxNum, list, flags, callingUid, callingProfileIds, displayId);
         }
 
         return list;
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index dfce40b..afa81fd 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -3343,9 +3343,16 @@
 
     @VisibleForTesting
     void getRunningTasks(int maxNum, List<ActivityManager.RunningTaskInfo> list,
-            int flags, int callingUid, ArraySet<Integer> profileIds) {
-        mTaskSupervisor.getRunningTasks().getTasks(maxNum, list, flags, this, callingUid,
-                profileIds);
+            int flags, int callingUid, ArraySet<Integer> profileIds, int displayId) {
+        WindowContainer root = this;
+        if (displayId != INVALID_DISPLAY) {
+            root = getDisplayContent(displayId);
+            if (root == null) {
+                return;
+            }
+        }
+        mTaskSupervisor.getRunningTasks().getTasks(maxNum, list, flags, mService.getRecentTasks(),
+                root, callingUid, profileIds);
     }
 
     void startPowerModeLaunchIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java
index 1ec191e..120fec0 100644
--- a/services/core/java/com/android/server/wm/RunningTasks.java
+++ b/services/core/java/com/android/server/wm/RunningTasks.java
@@ -60,8 +60,8 @@
     private RecentTasks mRecentTasks;
     private boolean mKeepIntentExtra;
 
-    void getTasks(int maxNum, List<RunningTaskInfo> list, int flags,
-            RootWindowContainer root, int callingUid, ArraySet<Integer> profileIds) {
+    void getTasks(int maxNum, List<RunningTaskInfo> list, int flags, RecentTasks recentTasks,
+            WindowContainer root, int callingUid, ArraySet<Integer> profileIds) {
         // Return early if there are no tasks to fetch
         if (maxNum <= 0) {
             return;
@@ -76,7 +76,7 @@
         mAllowed = (flags & FLAG_ALLOWED) == FLAG_ALLOWED;
         mFilterOnlyVisibleRecents =
                 (flags & FLAG_FILTER_ONLY_VISIBLE_RECENTS) == FLAG_FILTER_ONLY_VISIBLE_RECENTS;
-        mRecentTasks = root.mService.getRecentTasks();
+        mRecentTasks = recentTasks;
         mKeepIntentExtra = (flags & FLAG_KEEP_INTENT_EXTRA) == FLAG_KEEP_INTENT_EXTRA;
 
         final PooledConsumer c = PooledLambda.obtainConsumer(RunningTasks::processTask, this,
diff --git a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
index a8b340c..e4f9eaf 100644
--- a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
@@ -218,8 +218,8 @@
         }).when(mMockWindowManagerInternal).unregisterTaskSystemBarsListener(any());
 
         mRunningTaskInfos = new ArrayList<>();
-        when(mMockActivityTaskManager.getTasks(anyInt(), anyBoolean(), anyBoolean())).thenReturn(
-                mRunningTaskInfos);
+        when(mMockActivityTaskManager.getTasks(anyInt(), anyBoolean(), anyBoolean(), anyInt()))
+                .thenReturn(mRunningTaskInfos);
 
 
         final UserHandle userHandle = new UserHandle(USER_ID);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 83f375f..adf694c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -1531,10 +1531,10 @@
         public boolean mLastAllowed;
 
         @Override
-        void getTasks(int maxNum, List<RunningTaskInfo> list, int flags,
-                RootWindowContainer root, int callingUid, ArraySet<Integer> profileIds) {
+        void getTasks(int maxNum, List<RunningTaskInfo> list, int flags, RecentTasks recentTasks,
+                WindowContainer root, int callingUid, ArraySet<Integer> profileIds) {
             mLastAllowed = (flags & FLAG_ALLOWED) == FLAG_ALLOWED;
-            super.getTasks(maxNum, list, flags, root, callingUid, profileIds);
+            super.getTasks(maxNum, list, flags, recentTasks, root, callingUid, profileIds);
         }
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
index 33b2366..b1acae2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
@@ -35,6 +35,8 @@
 
 import androidx.test.filters.MediumTest;
 
+import com.google.common.truth.Correspondence;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -52,6 +54,9 @@
 public class RunningTasksTest extends WindowTestsBase {
 
     private static final ArraySet<Integer> PROFILE_IDS = new ArraySet<>();
+    private static final Correspondence<RunningTaskInfo, Integer> TASKINFO_HAS_ID =
+            Correspondence.transforming((RunningTaskInfo t) -> t.taskId, "has id");
+
 
     private RunningTasks mRunningTasks;
 
@@ -91,8 +96,8 @@
         // collected from all tasks across all the stacks
         final int numFetchTasks = 5;
         ArrayList<RunningTaskInfo> tasks = new ArrayList<>();
-        mRunningTasks.getTasks(5, tasks, FLAG_ALLOWED | FLAG_CROSS_USERS, mRootWindowContainer,
-                -1 /* callingUid */, PROFILE_IDS);
+        mRunningTasks.getTasks(5, tasks, FLAG_ALLOWED | FLAG_CROSS_USERS,
+                mAtm.getRecentTasks(), mRootWindowContainer, -1 /* callingUid */, PROFILE_IDS);
         assertThat(tasks).hasSize(numFetchTasks);
         for (int i = 0; i < numFetchTasks; i++) {
             assertEquals(numTasks - i - 1, tasks.get(i).id);
@@ -102,7 +107,7 @@
         // and does not crash
         tasks.clear();
         mRunningTasks.getTasks(100, tasks, FLAG_ALLOWED | FLAG_CROSS_USERS,
-                mRootWindowContainer, -1 /* callingUid */, PROFILE_IDS);
+                mAtm.getRecentTasks(), mRootWindowContainer, -1 /* callingUid */, PROFILE_IDS);
         assertThat(tasks).hasSize(numTasks);
         for (int i = 0; i < numTasks; i++) {
             assertEquals(numTasks - i - 1, tasks.get(i).id);
@@ -126,7 +131,7 @@
         final int numFetchTasks = 5;
         final ArrayList<RunningTaskInfo> tasks = new ArrayList<>();
         mRunningTasks.getTasks(numFetchTasks, tasks, FLAG_ALLOWED | FLAG_CROSS_USERS,
-                mRootWindowContainer, -1 /* callingUid */, PROFILE_IDS);
+                mAtm.getRecentTasks(), mRootWindowContainer, -1 /* callingUid */, PROFILE_IDS);
         assertThat(tasks).hasSize(numFetchTasks);
         for (int i = 0; i < tasks.size(); i++) {
             final Bundle extras = tasks.get(i).baseIntent.getExtras();
@@ -151,8 +156,8 @@
         final int numFetchTasks = 5;
         final ArrayList<RunningTaskInfo> tasks = new ArrayList<>();
         mRunningTasks.getTasks(numFetchTasks, tasks,
-                FLAG_ALLOWED | FLAG_CROSS_USERS | FLAG_KEEP_INTENT_EXTRA, mRootWindowContainer,
-                -1 /* callingUid */, PROFILE_IDS);
+                FLAG_ALLOWED | FLAG_CROSS_USERS | FLAG_KEEP_INTENT_EXTRA,
+                mAtm.getRecentTasks(), mRootWindowContainer, -1 /* callingUid */, PROFILE_IDS);
         assertThat(tasks).hasSize(numFetchTasks);
         for (int i = 0; i < tasks.size(); i++) {
             final Bundle extras = tasks.get(i).baseIntent.getExtras();
@@ -184,8 +189,8 @@
         final int numFetchTasks = 5;
         final ArrayList<RunningTaskInfo> fetchTasks = new ArrayList<>();
         mRunningTasks.getTasks(numFetchTasks, fetchTasks,
-                FLAG_ALLOWED | FLAG_CROSS_USERS | FLAG_KEEP_INTENT_EXTRA, mRootWindowContainer,
-                -1 /* callingUid */, PROFILE_IDS);
+                FLAG_ALLOWED | FLAG_CROSS_USERS | FLAG_KEEP_INTENT_EXTRA,
+                mAtm.getRecentTasks(), mRootWindowContainer, -1 /* callingUid */, PROFILE_IDS);
         assertThat(fetchTasks).hasSize(numFetchTasks);
         assertEquals(fetchTasks.get(0).id, focusedTask.mTaskId);
         assertEquals(fetchTasks.get(1).id, visibleTask.mTaskId);
@@ -210,4 +215,46 @@
         task.intent = activity.intent;
         return task;
     }
+
+    @Test
+    public void testMultipleDisplays() {
+        final DisplayContent display0 = new TestDisplayContent.Builder(mAtm, 1000, 2500).build();
+        final DisplayContent display1 = new TestDisplayContent.Builder(mAtm, 1000, 2500).build();
+        final int numTasks = 10;
+        final ArrayList<Task> tasks = new ArrayList<>();
+        for (int i = 0; i < numTasks; i++) {
+            final Task stack = new TaskBuilder(mSupervisor)
+                    .setDisplay(i % 2 == 0 ? display0 : display1)
+                    .setOnTop(true)
+                    .build();
+            final Task task = createTask(stack, ".Task" + i, i, i, null);
+            tasks.add(task);
+        }
+
+        final int numFetchTasks = numTasks;
+        final ArrayList<RunningTaskInfo> fetchTasks = new ArrayList<>();
+
+        mRunningTasks.getTasks(numFetchTasks, fetchTasks,
+                FLAG_ALLOWED | FLAG_CROSS_USERS,
+                mAtm.getRecentTasks(), display0, -1 /* callingUid */, PROFILE_IDS);
+        assertThat(fetchTasks).hasSize(numTasks / 2);
+        assertThat(fetchTasks).comparingElementsUsing(TASKINFO_HAS_ID)
+                .containsExactly(0, 2, 4, 6, 8);
+
+        fetchTasks.clear();
+        mRunningTasks.getTasks(numFetchTasks, fetchTasks,
+                FLAG_ALLOWED | FLAG_CROSS_USERS,
+                mAtm.getRecentTasks(), display1, -1 /* callingUid */, PROFILE_IDS);
+        assertThat(fetchTasks).hasSize(numTasks / 2);
+        assertThat(fetchTasks).comparingElementsUsing(TASKINFO_HAS_ID)
+                .containsExactly(1, 3, 5, 7, 9);
+
+        fetchTasks.clear();
+        mRunningTasks.getTasks(numFetchTasks, fetchTasks,
+                FLAG_ALLOWED | FLAG_CROSS_USERS,
+                mAtm.getRecentTasks(), mRootWindowContainer, -1 /* callingUid */, PROFILE_IDS);
+        assertThat(fetchTasks).hasSize(numTasks);
+        assertThat(fetchTasks).comparingElementsUsing(TASKINFO_HAS_ID)
+                .containsExactly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+    }
 }