From edaa029b4676f1c6e6f3ad7ef403c3fc66c52d0e Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Fri, 23 Jul 2021 01:46:08 +0800 Subject: [PATCH] Fix showing duplicated recent tasks in Recents New task was created while the recent task list frozen. So, a new recent task was added, but the existing task with the same affinity was not removed. Removing the existing task and place the new task to the same index in the list. Bug: 192926123 Test: atest RecentTasksTest Change-Id: I4392c30ab58cfdeebcc2d38c9c986ce531c2f507 --- .../com/android/server/wm/RecentTasks.java | 16 ++++----- .../android/server/wm/RecentTasksTest.java | 34 +++++++++++++++++++ 2 files changed, 41 insertions(+), 9 deletions(-) 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