diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java index 28d6fbb36a474..6df9f4da7ae8e 100644 --- a/core/java/android/app/ActivityTaskManager.java +++ b/core/java/android/app/ActivityTaskManager.java @@ -400,8 +400,18 @@ public class ActivityTaskManager { */ public List getTasks( int maxNum, boolean filterOnlyVisibleRecents) { + return getTasks(maxNum, filterOnlyVisibleRecents, false /* keepIntentExtra */); + } + + /** + * @return List of running tasks that can be filtered by visibility in recents and keep intent + * extra. + * @hide + */ + public List getTasks( + int maxNum, boolean filterOnlyVisibleRecents, boolean keepIntentExtra) { try { - return getService().getTasks(maxNum, filterOnlyVisibleRecents); + return getService().getTasks(maxNum, filterOnlyVisibleRecents, keepIntentExtra); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl index 2f1f14e186db4..b75e89ce6fdad 100644 --- a/core/java/android/app/IActivityTaskManager.aidl +++ b/core/java/android/app/IActivityTaskManager.aidl @@ -149,7 +149,8 @@ interface IActivityTaskManager { void setFocusedTask(int taskId); boolean removeTask(int taskId); void removeAllVisibleRecentTasks(); - List getTasks(int maxNum, boolean filterOnlyVisibleRecents); + List getTasks(int maxNum, boolean filterOnlyVisibleRecents, + boolean keepIntentExtra); void moveTaskToFront(in IApplicationThread app, in String callingPackage, int task, int flags, in Bundle options); ParceledListSlice getRecentTasks(int maxNum, int flags, diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index ed86710ec2394..e202511976439 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5768,7 +5768,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public List getTasks(int maxNum) { - return mActivityTaskManager.getTasks(maxNum, false /* filterForVisibleRecents */); + return mActivityTaskManager.getTasks(maxNum); } @Override diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 7607285bb468e..8de4ee62561d5 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -2104,8 +2104,16 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } - List getTasks(int maxNum) { - return getTasks(maxNum, false /* filterForVisibleRecents */); + /** + * Gets info of running tasks up to the given number. + * + * @param maxNum the maximum number of task info returned by this method. If the total number of + * running tasks is larger than it then there is no guarantee which task will be + * left out. + * @return a list of {@link ActivityManager.RunningTaskInfo} with up to {@code maxNum} items + */ + public List getTasks(int maxNum) { + return getTasks(maxNum, false /* filterForVisibleRecents */, false /* keepIntentExtra */); } /** @@ -2114,10 +2122,14 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ @Override public List getTasks(int maxNum, - boolean filterOnlyVisibleRecents) { + boolean filterOnlyVisibleRecents, boolean keepIntentExtra) { final int callingUid = Binder.getCallingUid(); final int callingPid = Binder.getCallingPid(); + + int flags = filterOnlyVisibleRecents ? RunningTasks.FLAG_FILTER_ONLY_VISIBLE_RECENTS : 0; + flags |= (keepIntentExtra ? RunningTasks.FLAG_KEEP_INTENT_EXTRA : 0); final boolean crossUser = isCrossUserAllowed(callingPid, callingUid); + flags |= (crossUser ? RunningTasks.FLAG_CROSS_USERS : 0); final int[] profileIds = getUserManager().getProfileIds( UserHandle.getUserId(callingUid), true); ArraySet callingProfileIds = new ArraySet<>(); @@ -2130,8 +2142,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum); final boolean allowed = isGetTasksAllowed("getTasks", callingPid, callingUid); - mRootWindowContainer.getRunningTasks(maxNum, list, filterOnlyVisibleRecents, callingUid, - allowed, crossUser, callingProfileIds); + flags |= (allowed ? RunningTasks.FLAG_ALLOWED : 0); + mRootWindowContainer.getRunningTasks( + maxNum, list, flags, callingUid, callingProfileIds); } 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 2118effe7506d..176e7e9b42318 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -3479,10 +3479,9 @@ class RootWindowContainer extends WindowContainer @VisibleForTesting void getRunningTasks(int maxNum, List list, - boolean filterOnlyVisibleRecents, int callingUid, boolean allowed, boolean crossUser, - ArraySet profileIds) { - mTaskSupervisor.getRunningTasks().getTasks(maxNum, list, filterOnlyVisibleRecents, this, - callingUid, allowed, crossUser, profileIds); + int flags, int callingUid, ArraySet profileIds) { + mTaskSupervisor.getRunningTasks().getTasks(maxNum, list, flags, this, 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 e8c1c8d58cb86..7ba772c184551 100644 --- a/services/core/java/com/android/server/wm/RunningTasks.java +++ b/services/core/java/com/android/server/wm/RunningTasks.java @@ -36,6 +36,11 @@ import java.util.TreeSet; */ class RunningTasks { + static final int FLAG_FILTER_ONLY_VISIBLE_RECENTS = 1; + static final int FLAG_ALLOWED = 1 << 1; + static final int FLAG_CROSS_USERS = 1 << 2; + static final int FLAG_KEEP_INTENT_EXTRA = 1 << 3; + // Comparator to sort by last active time (descending) private static final Comparator LAST_ACTIVE_TIME_COMPARATOR = (o1, o2) -> Long.signum(o2.lastActiveTime - o1.lastActiveTime); @@ -50,10 +55,10 @@ class RunningTasks { private boolean mFilterOnlyVisibleRecents; private Task mTopDisplayFocusRootTask; private RecentTasks mRecentTasks; + private boolean mKeepIntentExtra; - void getTasks(int maxNum, List list, boolean filterOnlyVisibleRecents, - RootWindowContainer root, int callingUid, boolean allowed, boolean crossUser, - ArraySet profileIds) { + void getTasks(int maxNum, List list, int flags, + RootWindowContainer root, int callingUid, ArraySet profileIds) { // Return early if there are no tasks to fetch if (maxNum <= 0) { return; @@ -63,12 +68,14 @@ class RunningTasks { mTmpSortedSet.clear(); mCallingUid = callingUid; mUserId = UserHandle.getUserId(callingUid); - mCrossUser = crossUser; + mCrossUser = (flags & FLAG_CROSS_USERS) == FLAG_CROSS_USERS; mProfileIds = profileIds; - mAllowed = allowed; - mFilterOnlyVisibleRecents = filterOnlyVisibleRecents; + mAllowed = (flags & FLAG_ALLOWED) == FLAG_ALLOWED; + mFilterOnlyVisibleRecents = + (flags & FLAG_FILTER_ONLY_VISIBLE_RECENTS) == FLAG_FILTER_ONLY_VISIBLE_RECENTS; mTopDisplayFocusRootTask = root.getTopDisplayFocusedRootTask(); mRecentTasks = root.mService.getRecentTasks(); + mKeepIntentExtra = (flags & FLAG_KEEP_INTENT_EXTRA) == FLAG_KEEP_INTENT_EXTRA; final PooledConsumer c = PooledLambda.obtainConsumer(RunningTasks::processTask, this, PooledLambda.__(Task.class)); @@ -126,7 +133,8 @@ class RunningTasks { /** Constructs a {@link RunningTaskInfo} from a given {@param task}. */ private RunningTaskInfo createRunningTaskInfo(Task task) { - final RunningTaskInfo rti = task.getTaskInfo(); + final RunningTaskInfo rti = new RunningTaskInfo(); + task.fillTaskInfo(rti, !mKeepIntentExtra); // Fill in some deprecated values rti.id = rti.taskId; return rti; 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 73404eb6f0fd9..95b5afc04573c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java @@ -1418,12 +1418,10 @@ public class RecentTasksTest extends WindowTestsBase { public boolean mLastAllowed; @Override - void getTasks(int maxNum, List list, boolean filterOnlyVisibleRecents, - RootWindowContainer root, int callingUid, boolean allowed, boolean crossUser, - ArraySet profileIds) { - mLastAllowed = allowed; - super.getTasks(maxNum, list, filterOnlyVisibleRecents, root, callingUid, allowed, - crossUser, profileIds); + void getTasks(int maxNum, List list, int flags, + RootWindowContainer root, int callingUid, ArraySet profileIds) { + mLastAllowed = (flags & FLAG_ALLOWED) == FLAG_ALLOWED; + super.getTasks(maxNum, list, flags, 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 e2be39b6eb155..c44c22fefd7aa 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java @@ -16,9 +16,14 @@ package com.android.server.wm; +import static com.android.server.wm.RunningTasks.FLAG_ALLOWED; +import static com.android.server.wm.RunningTasks.FLAG_CROSS_USERS; +import static com.android.server.wm.RunningTasks.FLAG_KEEP_INTENT_EXTRA; + import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import android.app.ActivityManager.RunningTaskInfo; @@ -83,8 +88,8 @@ public class RunningTasksTest extends WindowTestsBase { // collected from all tasks across all the stacks final int numFetchTasks = 5; ArrayList tasks = new ArrayList<>(); - mRunningTasks.getTasks(5, tasks, false /* filterOnlyVisibleRecents */, mRootWindowContainer, - -1 /* callingUid */, true /* allowed */, true /*crossUser */, PROFILE_IDS); + mRunningTasks.getTasks(5, tasks, FLAG_ALLOWED | FLAG_CROSS_USERS, mRootWindowContainer, + -1 /* callingUid */, PROFILE_IDS); assertThat(tasks).hasSize(numFetchTasks); for (int i = 0; i < numFetchTasks; i++) { assertEquals(numTasks - i - 1, tasks.get(i).id); @@ -93,9 +98,8 @@ public class RunningTasksTest extends WindowTestsBase { // Ensure that requesting more than the total number of tasks only returns the subset // and does not crash tasks.clear(); - mRunningTasks.getTasks(100, tasks, false /* filterOnlyVisibleRecents */, - mRootWindowContainer, -1 /* callingUid */, true /* allowed */, true /* crossUser */, - PROFILE_IDS); + mRunningTasks.getTasks(100, tasks, FLAG_ALLOWED | FLAG_CROSS_USERS, + mRootWindowContainer, -1 /* callingUid */, PROFILE_IDS); assertThat(tasks).hasSize(numTasks); for (int i = 0; i < numTasks; i++) { assertEquals(numTasks - i - 1, tasks.get(i).id); @@ -103,7 +107,7 @@ public class RunningTasksTest extends WindowTestsBase { } @Test - public void testTaskInfo_expectNoExtras() { + public void testTaskInfo_expectNoExtrasByDefault() { final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2500).build(); final int numTasks = 10; for (int i = 0; i < numTasks; i++) { @@ -118,9 +122,8 @@ public class RunningTasksTest extends WindowTestsBase { final int numFetchTasks = 5; final ArrayList tasks = new ArrayList<>(); - mRunningTasks.getTasks(numFetchTasks, tasks, false /* filterOnlyVisibleRecents */, - mRootWindowContainer, -1 /* callingUid */, true /* allowed */, true /*crossUser */, - PROFILE_IDS); + mRunningTasks.getTasks(numFetchTasks, tasks, FLAG_ALLOWED | FLAG_CROSS_USERS, + 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(); @@ -128,6 +131,32 @@ public class RunningTasksTest extends WindowTestsBase { } } + @Test + public void testTaskInfo_expectExtrasWithKeepExtraFlag() { + final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2500).build(); + final int numTasks = 10; + for (int i = 0; i < numTasks; i++) { + final Task stack = new TaskBuilder(mSupervisor) + .setDisplay(display) + .setOnTop(true) + .build(); + final Bundle data = new Bundle(); + data.putInt("key", 100); + createTask(stack, ".Task" + i, i, i, data); + } + + final int numFetchTasks = 5; + final ArrayList tasks = new ArrayList<>(); + mRunningTasks.getTasks(numFetchTasks, tasks, + FLAG_ALLOWED | FLAG_CROSS_USERS | FLAG_KEEP_INTENT_EXTRA, 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(); + assertNotNull(extras); + assertEquals(100, extras.getInt("key")); + } + } /** * Create a task with a single activity in it, with the given last active time. @@ -145,6 +174,7 @@ public class RunningTasksTest extends WindowTestsBase { .setComponent(new ComponentName(mContext.getPackageName(), ".TaskActivity")) .setIntentExtras(extras) .build(); + task.intent = activity.intent; return task; } }