From 7cfc1c2d26383e4cb938fd403f9a653c730e637d Mon Sep 17 00:00:00 2001 From: Hui Yu Date: Sat, 18 Feb 2023 00:00:24 +0000 Subject: [PATCH] Fix a outer loop iterates on item that is removed by inner loop problem. updateForegroundApps() has the outer loop that iterate on mActiveForegroundApps, but inside the loop stopAllForegroundServicesLocked() calls setServiceForegroundInnerLocked() which calls decActiveForegroundAppLocked() to remove item from mActiveForegroundApps, the end result is an ArrayIndexOutOfBoundsException. Bug: 243841000 Test: build and run Change-Id: Ia64816799fb7d36c481f382496c035e2ab85c2a3 --- .../core/java/com/android/server/am/ActiveServices.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index ede4c5ee0b701..a59395034dfa2 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -522,6 +522,7 @@ public final class ActiveServices { final ArrayList mStartingBackground = new ArrayList<>(); final ArrayMap mActiveForegroundApps = new ArrayMap<>(); + final ArrayList mPendingRemoveForegroundApps = new ArrayList<>(); boolean mActiveForegroundAppsChanged; @@ -1657,13 +1658,14 @@ public final class ActiveServices { if (smap != null) { if (DEBUG_FOREGROUND_SERVICE) Slog.d(TAG, "Updating foreground apps for user " + smap.mUserId); + smap.mPendingRemoveForegroundApps.clear(); for (int i = smap.mActiveForegroundApps.size()-1; i >= 0; i--) { ActiveForegroundApp aa = smap.mActiveForegroundApps.valueAt(i); if (aa.mEndTime != 0) { boolean canRemove = foregroundAppShownEnoughLocked(aa, now); if (canRemove) { // This was up for longer than the timeout, so just remove immediately. - smap.mActiveForegroundApps.removeAt(i); + smap.mPendingRemoveForegroundApps.add(smap.mActiveForegroundApps.keyAt(i)); smap.mActiveForegroundAppsChanged = true; continue; } @@ -1688,6 +1690,9 @@ public final class ActiveServices { } } } + for(int i = smap.mPendingRemoveForegroundApps.size() - 1; i >= 0; i--) { + smap.mActiveForegroundApps.remove(smap.mPendingRemoveForegroundApps.get(i)); + } smap.removeMessages(ServiceMap.MSG_UPDATE_FOREGROUND_APPS); if (nextUpdateTime < Long.MAX_VALUE) { if (DEBUG_FOREGROUND_SERVICE) Slog.d(TAG, "Next update time in: "