diff options
| -rw-r--r-- | services/core/java/com/android/server/wm/RecentTasks.java | 99 | ||||
| -rw-r--r-- | services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java | 69 |
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 |