Loading services/core/java/com/android/server/wm/RecentTasks.java +50 −49 Original line number Diff line number Diff line Loading @@ -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. */ Loading @@ -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<>(); } Loading @@ -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 Loading @@ -908,17 +913,6 @@ 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. Loading @@ -927,22 +921,26 @@ class RecentTasks { 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); 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 (DEBUG_RECENTS) { Slog.d(TAG_RECENTS, "Skipping, unavail real act: " + 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); if (DEBUG_RECENTS) { Slog.d(TAG_RECENTS, "Skipping, user setup not complete: " + tr); } continue; } Loading @@ -953,7 +951,6 @@ class RecentTasks { res.add(rti); } } return res; } Loading Loading @@ -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); } } Loading Loading @@ -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; Loading Loading @@ -1329,8 +1327,10 @@ 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 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; Loading @@ -1338,6 +1338,7 @@ class RecentTasks { if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\texcludeFromRecents=true"); return numVisibleTasks == 1; } } if (mMinNumVisibleTasks >= 0 && numVisibleTasks <= mMinNumVisibleTasks) { // Always keep up to the min number of recent tasks, after that fall through to the Loading services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +67 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -511,6 +514,52 @@ public class RecentTasksTest extends ActivityTestsBase { assertTrimmed(excludedTask1); } @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(); Loading Loading @@ -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) { Loading @@ -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. Loading Loading @@ -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 Loading Loading
services/core/java/com/android/server/wm/RecentTasks.java +50 −49 Original line number Diff line number Diff line Loading @@ -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. */ Loading @@ -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<>(); } Loading @@ -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 Loading @@ -908,17 +913,6 @@ 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. Loading @@ -927,22 +921,26 @@ class RecentTasks { 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); 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 (DEBUG_RECENTS) { Slog.d(TAG_RECENTS, "Skipping, unavail real act: " + 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); if (DEBUG_RECENTS) { Slog.d(TAG_RECENTS, "Skipping, user setup not complete: " + tr); } continue; } Loading @@ -953,7 +951,6 @@ class RecentTasks { res.add(rti); } } return res; } Loading Loading @@ -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); } } Loading Loading @@ -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; Loading Loading @@ -1329,8 +1327,10 @@ 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 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; Loading @@ -1338,6 +1338,7 @@ class RecentTasks { if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\texcludeFromRecents=true"); return numVisibleTasks == 1; } } if (mMinNumVisibleTasks >= 0 && numVisibleTasks <= mMinNumVisibleTasks) { // Always keep up to the min number of recent tasks, after that fall through to the Loading
services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +67 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -511,6 +514,52 @@ public class RecentTasksTest extends ActivityTestsBase { assertTrimmed(excludedTask1); } @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(); Loading Loading @@ -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) { Loading @@ -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. Loading Loading @@ -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 Loading