diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java index 455f568d75235..ede4c2ef78350 100644 --- a/services/core/java/com/android/server/wm/RecentTasks.java +++ b/services/core/java/com/android/server/wm/RecentTasks.java @@ -1108,13 +1108,15 @@ class RecentTasks { } if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: trimming tasks for " + task); - removeForAddTask(task); + final int removedIndex = removeForAddTask(task); task.inRecents = true; if (!isAffiliated || needAffiliationFix) { // If this is a simple non-affiliated task, or we had some failure trying to // handle it as part of an affilated task, then just place it at the top. - mTasks.add(0, task); + // But if the list is frozen, adding the task to the removed index to keep the order. + int indexToAdd = mFreezeTaskListReordering && removedIndex != -1 ? removedIndex : 0; + mTasks.add(indexToAdd, task); notifyTaskAdded(task); if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: adding " + task); } else if (isAffiliated) { @@ -1482,14 +1484,14 @@ class RecentTasks { * If needed, remove oldest existing entries in recents that are for the same kind * of task as the given one. */ - private void removeForAddTask(Task task) { + private int removeForAddTask(Task task) { // The adding task will be in recents so it is not hidden. mHiddenTasks.remove(task); final int removeIndex = findRemoveIndexForAddTask(task); if (removeIndex == -1) { // Nothing to trim - return; + return removeIndex; } // There is a similar task that will be removed for the addition of {@param task}, but it @@ -1511,6 +1513,7 @@ class RecentTasks { } } notifyTaskPersisterLocked(removedTask, false /* flush */); + return removeIndex; } /** @@ -1518,11 +1521,6 @@ class RecentTasks { * list (if any). */ private int findRemoveIndexForAddTask(Task task) { - if (mFreezeTaskListReordering) { - // Defer removing tasks due to the addition of new tasks until the task list is unfrozen - return -1; - } - final int recentsCount = mTasks.size(); final Intent intent = task.intent; final boolean document = intent != null && intent.isDocument(); 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 5af68021b2019..e3c38b06ec887 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java @@ -858,6 +858,40 @@ public class RecentTasksTest extends WindowTestsBase { assertThat(mCallbacksRecorder.mRemoved).contains(mTasks.get(1)); } + @Test + public void testFreezeTaskListOrder_replaceTask() { + // Create two tasks with the same affinity + Task affinityTask1 = createTaskBuilder(".AffinityTask1") + .setFlags(FLAG_ACTIVITY_NEW_TASK) + .build(); + Task affinityTask2 = createTaskBuilder(".AffinityTask2") + .setFlags(FLAG_ACTIVITY_NEW_TASK) + .build(); + affinityTask2.affinity = affinityTask1.affinity = "affinity"; + + // Add some tasks + mRecentTasks.add(mTasks.get(0)); + mRecentTasks.add(affinityTask1); + mRecentTasks.add(mTasks.get(1)); + mCallbacksRecorder.clear(); + + // Freeze the list + mRecentTasks.setFreezeTaskListReordering(); + assertTrue(mRecentTasks.isFreezeTaskListReorderingSet()); + + // Add the affinity task + mRecentTasks.add(affinityTask2); + + assertRecentTasksOrder(mTasks.get(1), + affinityTask2, + mTasks.get(0)); + + assertThat(mCallbacksRecorder.mAdded).hasSize(1); + assertThat(mCallbacksRecorder.mAdded).contains(affinityTask2); + assertThat(mCallbacksRecorder.mRemoved).hasSize(1); + assertThat(mCallbacksRecorder.mRemoved).contains(affinityTask1); + } + @Test public void testFreezeTaskListOrder_timeout() { // Add some tasks