summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/RecentTasks.java99
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java69
2 files changed, 117 insertions, 51 deletions
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index d69ae3d5c3c0..24b02133ff3c 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -845,6 +845,11 @@ class RecentTasks {
return mService.mAmInternal.getCurrentProfileIds();
}
+ @VisibleForTesting
+ boolean isUserRunning(int userId, int flags) {
+ return mService.mAmInternal.isUserRunning(userId, flags);
+ }
+
/**
* @return the list of recent tasks for presentation.
*/
@@ -861,7 +866,7 @@ class RecentTasks {
boolean getTasksAllowed, boolean getDetailedTasks, int userId, int callingUid) {
final boolean withExcluded = (flags & RECENT_WITH_EXCLUDED) != 0;
- if (!mService.mAmInternal.isUserRunning(userId, FLAG_AND_UNLOCKED)) {
+ if (!isUserRunning(userId, FLAG_AND_UNLOCKED)) {
Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
return new ArrayList<>();
}
@@ -881,7 +886,7 @@ class RecentTasks {
if (isVisibleRecentTask(tr)) {
numVisibleTasks++;
- if (isInVisibleRange(tr, numVisibleTasks)) {
+ if (isInVisibleRange(tr, numVisibleTasks, withExcluded)) {
// Fall through
} else {
// Not in visible range
@@ -908,51 +913,43 @@ class RecentTasks {
continue;
}
- // Return the entry if desired by the caller. We always return
- // the first entry, because callers always expect this to be the
- // foreground app. We may filter others if the caller has
- // not supplied RECENT_WITH_EXCLUDED and there is some reason
- // we should exclude the entry.
-
- if (i == 0
- || withExcluded
- || (tr.intent == null)
- || ((tr.intent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
- == 0)) {
- if (!getTasksAllowed) {
- // If the caller doesn't have the GET_TASKS permission, then only
- // allow them to see a small subset of tasks -- their own and home.
- if (!tr.isActivityTypeHome() && tr.effectiveUid != callingUid) {
- if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
- continue;
- }
- }
- if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
- // Don't include auto remove tasks that are finished or finishing.
- if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
- "Skipping, auto-remove without activity: " + tr);
- continue;
- }
- if ((flags & RECENT_IGNORE_UNAVAILABLE) != 0 && !tr.isAvailable) {
- if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
- "Skipping, unavail real act: " + tr);
+ if (!getTasksAllowed) {
+ // If the caller doesn't have the GET_TASKS permission, then only
+ // allow them to see a small subset of tasks -- their own and home.
+ if (!tr.isActivityTypeHome() && tr.effectiveUid != callingUid) {
+ if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
continue;
}
+ }
- if (!tr.mUserSetupComplete) {
- // Don't include task launched while user is not done setting-up.
- if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
- "Skipping, user setup not complete: " + tr);
- continue;
+ if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
+ // Don't include auto remove tasks that are finished or finishing.
+ if (DEBUG_RECENTS) {
+ Slog.d(TAG_RECENTS, "Skipping, auto-remove without activity: " + tr);
+ }
+ continue;
+ }
+ if ((flags & RECENT_IGNORE_UNAVAILABLE) != 0 && !tr.isAvailable) {
+ if (DEBUG_RECENTS) {
+ Slog.d(TAG_RECENTS, "Skipping, unavail real act: " + tr);
}
+ continue;
+ }
- final ActivityManager.RecentTaskInfo rti = createRecentTaskInfo(tr);
- if (!getDetailedTasks) {
- rti.baseIntent.replaceExtras((Bundle)null);
+ if (!tr.mUserSetupComplete) {
+ // Don't include task launched while user is not done setting-up.
+ if (DEBUG_RECENTS) {
+ Slog.d(TAG_RECENTS, "Skipping, user setup not complete: " + tr);
}
+ continue;
+ }
- res.add(rti);
+ final ActivityManager.RecentTaskInfo rti = createRecentTaskInfo(tr);
+ if (!getDetailedTasks) {
+ rti.baseIntent.replaceExtras((Bundle) null);
}
+
+ res.add(rti);
}
return res;
}
@@ -994,7 +991,7 @@ class RecentTasks {
final TaskRecord tr = mTasks.get(i);
if (isVisibleRecentTask(tr)) {
numVisibleTasks++;
- if (isInVisibleRange(tr, numVisibleTasks)) {
+ if (isInVisibleRange(tr, numVisibleTasks, false /* skipExcludedCheck */)) {
res.put(tr.taskId, true);
}
}
@@ -1215,7 +1212,8 @@ class RecentTasks {
continue;
} else {
numVisibleTasks++;
- if (isInVisibleRange(task, numVisibleTasks) || !isTrimmable(task)) {
+ if (isInVisibleRange(task, numVisibleTasks, false /* skipExcludedCheck */)
+ || !isTrimmable(task)) {
// Keep visible tasks in range
i++;
continue;
@@ -1329,14 +1327,17 @@ class RecentTasks {
/**
* @return whether the given visible task is within the policy range.
*/
- private boolean isInVisibleRange(TaskRecord task, int numVisibleTasks) {
- // Keep the last most task even if it is excluded from recents
- final boolean isExcludeFromRecents =
- (task.getBaseIntent().getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
- == FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
- if (isExcludeFromRecents) {
- if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\texcludeFromRecents=true");
- return numVisibleTasks == 1;
+ private boolean isInVisibleRange(TaskRecord task, int numVisibleTasks,
+ boolean skipExcludedCheck) {
+ if (!skipExcludedCheck) {
+ // Keep the most recent task even if it is excluded from recents
+ final boolean isExcludeFromRecents =
+ (task.getBaseIntent().getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+ == FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
+ if (isExcludeFromRecents) {
+ if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\texcludeFromRecents=true");
+ return numVisibleTasks == 1;
+ }
}
if (mMinNumVisibleTasks >= 0 && numVisibleTasks <= mMinNumVisibleTasks) {
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 68e7470b8763..08e6ce4287a5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.app.ActivityManager.RECENT_WITH_EXCLUDED;
import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
@@ -29,7 +30,9 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.view.Display.DEFAULT_DISPLAY;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -512,6 +515,52 @@ public class RecentTasksTest extends ActivityTestsBase {
}
@Test
+ public void testVisibleTasks_excludedFromRecents_firstTaskNotVisible() {
+ // Create some set of tasks, some of which are visible and some are not
+ TaskRecord homeTask = setTaskActivityType(
+ createTaskBuilder("com.android.pkg1", ".HomeTask").build(),
+ ACTIVITY_TYPE_HOME);
+ homeTask.mUserSetupComplete = true;
+ mRecentTasks.add(homeTask);
+ TaskRecord excludedTask1 = createTaskBuilder(".ExcludedTask1")
+ .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+ .build();
+ excludedTask1.mUserSetupComplete = true;
+ mRecentTasks.add(excludedTask1);
+
+ // Expect that the first visible excluded-from-recents task is visible
+ assertGetRecentTasksOrder(0 /* flags */, excludedTask1);
+ }
+
+ @Test
+ public void testVisibleTasks_excludedFromRecents_withExcluded() {
+ // Create some set of tasks, some of which are visible and some are not
+ TaskRecord t1 = createTaskBuilder("com.android.pkg1", ".Task1").build();
+ t1.mUserSetupComplete = true;
+ mRecentTasks.add(t1);
+ TaskRecord homeTask = setTaskActivityType(
+ createTaskBuilder("com.android.pkg1", ".HomeTask").build(),
+ ACTIVITY_TYPE_HOME);
+ homeTask.mUserSetupComplete = true;
+ mRecentTasks.add(homeTask);
+ TaskRecord excludedTask1 = createTaskBuilder(".ExcludedTask1")
+ .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+ .build();
+ excludedTask1.mUserSetupComplete = true;
+ mRecentTasks.add(excludedTask1);
+ TaskRecord excludedTask2 = createTaskBuilder(".ExcludedTask2")
+ .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+ .build();
+ excludedTask2.mUserSetupComplete = true;
+ mRecentTasks.add(excludedTask2);
+ TaskRecord t2 = createTaskBuilder("com.android.pkg2", ".Task1").build();
+ t2.mUserSetupComplete = true;
+ mRecentTasks.add(t2);
+
+ assertGetRecentTasksOrder(RECENT_WITH_EXCLUDED, t2, excludedTask2, excludedTask1, t1);
+ }
+
+ @Test
public void testVisibleTasks_minNum() {
mRecentTasks.setOnlyTestVisibleRange();
mRecentTasks.setParameters(5 /* min */, -1 /* max */, 25 /* ms */);
@@ -830,7 +879,7 @@ public class RecentTasksTest extends ActivityTestsBase {
}
/**
- * Ensures that the recent tasks list is in the provided order. Note that the expected tasks
+ * Ensures that the raw recent tasks list is in the provided order. Note that the expected tasks
* should be ordered from least to most recent.
*/
private void assertRecentTasksOrder(TaskRecord... expectedTasks) {
@@ -841,6 +890,22 @@ public class RecentTasksTest extends ActivityTestsBase {
}
}
+ /**
+ * Ensures that the recent tasks list is in the provided order. Note that the expected tasks
+ * should be ordered from least to most recent.
+ */
+ private void assertGetRecentTasksOrder(int getRecentTaskFlags, TaskRecord... expectedTasks) {
+ doNothing().when(mRecentTasks).loadUserRecentsLocked(anyInt());
+ doReturn(true).when(mRecentTasks).isUserRunning(anyInt(), anyInt());
+ List<RecentTaskInfo> infos = mRecentTasks.getRecentTasks(MAX_VALUE, getRecentTaskFlags,
+ true /* getTasksAllowed */, false /* getDetailedTasks */,
+ TEST_USER_0_ID, 0).getList();
+ assertTrue(expectedTasks.length == infos.size());
+ for (int i = 0; i < infos.size(); i++) {
+ assertTrue(expectedTasks[i].taskId == infos.get(i).taskId);
+ }
+ }
+
private void assertNotRestoreTask(Runnable action) {
// Verify stack count doesn't change because task with fullscreen mode and standard type
// would have its own stack.
@@ -1018,7 +1083,7 @@ public class RecentTasksTest extends ActivityTestsBase {
@Override
protected RecentTasks createRecentTasks() {
- return new TestRecentTasks(this, mTaskPersister);
+ return spy(new TestRecentTasks(this, mTaskPersister));
}
@Override