From 26a92f5db0c6313c6f4aa5a9f619cacd74b3a8ba Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Wed, 7 Dec 2022 09:47:57 +0000 Subject: [PATCH] Prevent IndexOutOfBoundsException while removing activities IndexOutOfBoundsException was thrown when traversing the Task from bottom to top because the activity could be removed from the Task and the activities are less than its original size. Bug: 260643770 Test: 1) Start multiple activities in a Task 2) Swipe up to home 3) Kill the app process from shell 4) Remove the task from Recents Change-Id: I64955415c04da30d7dc8a4681474ceb06db1e88b --- .../core/java/com/android/server/wm/Task.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index a74a4b001670b..6d4a526fd9543 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -1591,15 +1591,22 @@ class Task extends TaskFragment { removeChild(r, reason); }); } else { + final ArrayList finishingActivities = new ArrayList<>(); + forAllActivities(r -> { + if (r.finishing || (excludingTaskOverlay && r.isTaskOverlay())) { + return; + } + finishingActivities.add(r); + }); + // Finish or destroy apps from the bottom to ensure that all the other activity have // been finished and the top task in another task gets resumed when a top activity is // removed. Otherwise, the next top activity could be started while the top activity // is removed, which is not necessary since the next top activity is on the same Task // and should also be removed. - forAllActivities((r) -> { - if (r.finishing || (excludingTaskOverlay && r.isTaskOverlay())) { - return; - } + for (int i = finishingActivities.size() - 1; i >= 0; i--) { + final ActivityRecord r = finishingActivities.get(i); + // Prevent the transition from being executed too early if the top activity is // resumed but the mVisibleRequested of any other activity is true, the transition // should wait until next activity resumed. @@ -1609,7 +1616,7 @@ class Task extends TaskFragment { } else { r.destroyIfPossible(reason); } - }, false /* traverseTopToBottom */); + } } }