From a9391ebe84bf74ef184dd2cdf1e1f22d118551bb Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Mon, 29 Jun 2020 17:02:57 +0800 Subject: [PATCH] Do not put in-recent task in hidden task list Tasks that cannot be accessed recently are hidden tasks, and the tasks will be removed when going to home to avoid leakage. But the task may be added to recent task again according to back stack, then it should not be hidden anymore, otherwise it may be removed unexpectedly. Also guard the case when performing the removal of hidden tasks. Fixes: 149538962 Test: RecentTasksTest#testAddTasksHomeClearUntrackedTasks_expectFinish Change-Id: I3de151aaeaad311f863c3867102a916779370407 --- .../core/java/com/android/server/wm/RecentTasks.java | 9 +++++---- .../src/com/android/server/wm/RecentTasksTest.java | 10 +++++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java index 1b58fc1d2d3e3..851b533a550dd 100644 --- a/services/core/java/com/android/server/wm/RecentTasks.java +++ b/services/core/java/com/android/server/wm/RecentTasks.java @@ -1426,8 +1426,8 @@ class RecentTasks { private void removeUnreachableHiddenTasks(int windowingMode) { for (int i = mHiddenTasks.size() - 1; i >= 0; i--) { final Task hiddenTask = mHiddenTasks.get(i); - if (!hiddenTask.hasChild()) { - // The task was removed by other path. + if (!hiddenTask.hasChild() || hiddenTask.inRecents) { + // The task was removed by other path or it became reachable (added to recents). mHiddenTasks.remove(i); continue; } @@ -1449,6 +1449,9 @@ class RecentTasks { * of task as the given one. */ private void 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 @@ -1460,8 +1463,6 @@ class RecentTasks { // callbacks here. final Task removedTask = mTasks.remove(removeIndex); if (removedTask != task) { - // The added task is in recents so it is not hidden. - mHiddenTasks.remove(task); if (removedTask.hasChild()) { // A non-empty task is replaced by a new task. Because the removed task is no longer // managed by the recent tasks list, add it to the hidden list to prevent the task 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 5005c07832ab7..fd169018782b1 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java @@ -464,15 +464,19 @@ public class RecentTasksTest extends ActivityTestsBase { mRecentTasks.add(task1); final Task task2 = taskBuilder.apply(true /* visible */); mRecentTasks.add(task2); - // Only the last task is kept in recents and the previous 2 tasks will becomes untracked + final Task task3 = createTaskBuilder(className).build(); + mRecentTasks.add(task3); + // Only the last added task is kept in recents and the previous 2 tasks will become hidden // tasks because their intents are identical. - mRecentTasks.add(createTaskBuilder(className).build()); + mRecentTasks.add(task1); // Go home to trigger the removal of untracked tasks. mRecentTasks.add(createTaskBuilder(".Home").setStack(mTaskContainer.getRootHomeTask()) .build()); + // The task was added into recents again so it is not hidden and shouldn't be removed. + assertNotNull(task1.getTopNonFinishingActivity()); // All activities in the invisible task should be finishing or removed. - assertNull(task1.getTopNonFinishingActivity()); + assertNull(task3.getTopNonFinishingActivity()); // The visible task should not be affected. assertNotNull(task2.getTopNonFinishingActivity()); }