From 92cffb3fd8911199edddf8136c7aa76edb952fbb Mon Sep 17 00:00:00 2001 From: Edgar Arriaga Date: Thu, 11 Aug 2022 00:24:56 +0000 Subject: [PATCH] Fix for out of bounds exception in CachedAppOptimizer The exception happens when cancelAllCompactions is called since the size changed while iterating in the loop caused by the inner cancelCompactionForProcess function. Changing the iteration to a while loop fixes the issue until consumed fixes the issue. Bug: 242010026 Test: Manual Change-Id: I92049ae3d06e403a37e69ee252ed993c89b6d9a7 --- .../com/android/server/am/CachedAppOptimizer.java | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index 45265ac0c8f38..363c9d0a963a3 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -1392,25 +1392,17 @@ public final class CachedAppOptimizer { void cancelAllCompactions(CancelCompactReason reason) { synchronized (mProcLock) { - int size = mPendingCompactionProcesses.size(); - ProcessRecord record; - for (int i=0; i < size; ++i) { - record = mPendingCompactionProcesses.get(i); - cancelCompactionForProcess(record, reason); - // The process record is kept alive after compactions are cleared, - // so make sure to reset the compaction state to avoid skipping any future - // compactions due to a stale value here. - record.mOptRecord.setHasPendingCompact(false); + while(!mPendingCompactionProcesses.isEmpty()) { + cancelCompactionForProcess(mPendingCompactionProcesses.get(0), reason); } mPendingCompactionProcesses.clear(); } - cancelCompaction(); } @GuardedBy("mProcLock") void cancelCompactionForProcess(ProcessRecord app, CancelCompactReason cancelReason) { boolean cancelled = false; - if (!mPendingCompactionProcesses.isEmpty() && mPendingCompactionProcesses.contains(app)) { + if (mPendingCompactionProcesses.contains(app)) { app.mOptRecord.setHasPendingCompact(false); mPendingCompactionProcesses.remove(app); cancelled = true;