From db1c135a591ee5d0c7952bc6ad1b5a937283089e Mon Sep 17 00:00:00 2001 From: Li Li Date: Wed, 29 Mar 2023 16:45:37 -0700 Subject: [PATCH] Unfreeze dependencies for apps receiving broadcast Currently unfreezeTemporarily() doesn't update oomadj of the target frozen process. If that frozen process calls into another frozen service or content provider, it fails. Async calls will be delayed, causing ANR. Sync calls will kill the latter unnecessarily. As it's heavy to recompute and propagate oomadj values of the impacted processes, those frozen processes are temporarily unfrozen to process the incoming broadcasts. The long term goal is to improve the oomadj logic and remove unfreezeTemporarily(). Bug: 272319219 Test: atest CachedAppOptimizerTest BroadcastQueueTest Test: manually verify broadcasts unfreeze apps and their bound services Change-Id: Ia584206a90ca9e4ada8d9c319a7ee103da8a4e4a --- .../android/server/am/BroadcastQueueImpl.java | 4 +-- .../server/am/BroadcastQueueModernImpl.java | 4 +-- .../com/android/server/am/OomAdjuster.java | 26 +++++++++++++++++++ .../android/server/am/BroadcastQueueTest.java | 6 ++--- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/services/core/java/com/android/server/am/BroadcastQueueImpl.java b/services/core/java/com/android/server/am/BroadcastQueueImpl.java index 4b8dc99c67d91..bd36c3ff6f984 100644 --- a/services/core/java/com/android/server/am/BroadcastQueueImpl.java +++ b/services/core/java/com/android/server/am/BroadcastQueueImpl.java @@ -835,7 +835,7 @@ public class BroadcastQueueImpl extends BroadcastQueue { OOM_ADJ_REASON_START_RECEIVER); } } else if (filter.receiverList.app != null) { - mService.mOomAdjuster.mCachedAppOptimizer.unfreezeTemporarily(filter.receiverList.app, + mService.mOomAdjuster.unfreezeTemporarily(filter.receiverList.app, CachedAppOptimizer.UNFREEZE_REASON_START_RECEIVER); } @@ -1129,7 +1129,7 @@ public class BroadcastQueueImpl extends BroadcastQueue { } if (sendResult) { if (r.callerApp != null) { - mService.mOomAdjuster.mCachedAppOptimizer.unfreezeTemporarily( + mService.mOomAdjuster.unfreezeTemporarily( r.callerApp, CachedAppOptimizer.UNFREEZE_REASON_FINISH_RECEIVER); } diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java index 5010ec03285fe..2eeed295b8999 100644 --- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java @@ -927,7 +927,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { final ProcessRecord app = r.resultToApp; final IApplicationThread thread = (app != null) ? app.getOnewayThread() : null; if (thread != null) { - mService.mOomAdjuster.mCachedAppOptimizer.unfreezeTemporarily( + mService.mOomAdjuster.unfreezeTemporarily( app, CachedAppOptimizer.UNFREEZE_REASON_FINISH_RECEIVER); if (r.shareIdentity && app.uid != r.callingUid) { mService.mPackageManagerInt.grantImplicitAccess(r.userId, r.intent, @@ -1513,7 +1513,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { mService.updateLruProcessLocked(queue.app, false, null); } - mService.mOomAdjuster.mCachedAppOptimizer.unfreezeTemporarily(queue.app, + mService.mOomAdjuster.unfreezeTemporarily(queue.app, CachedAppOptimizer.UNFREEZE_REASON_START_RECEIVER); if (queue.runningOomAdjusted) { diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index 84a80993c4b20..a86c02d4b8262 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -349,6 +349,7 @@ public class OomAdjuster { private final ArrayList mTmpBecameIdle = new ArrayList(); private final ActiveUids mTmpUidRecords; private final ArrayDeque mTmpQueue; + private final ArraySet mTmpProcessSet = new ArraySet<>(); private final ArraySet mPendingProcessSet = new ArraySet<>(); private final ArraySet mProcessesInCycle = new ArraySet<>(); @@ -3472,4 +3473,29 @@ public class OomAdjuster { CachedAppOptimizer.getUnfreezeReasonCodeFromOomAdjReason(oomAdjReason)); } } + + @GuardedBy("mService") + void unfreezeTemporarily(ProcessRecord app, @OomAdjuster.OomAdjReason int reason) { + if (!mCachedAppOptimizer.useFreezer()) { + return; + } + + final ProcessCachedOptimizerRecord opt = app.mOptRecord; + if (!opt.isFrozen() && !opt.isPendingFreeze()) { + return; + } + + final ArrayList processes = mTmpProcessList; + final ActiveUids uids = mTmpUidRecords; + mTmpProcessSet.add(app); + collectReachableProcessesLocked(mTmpProcessSet, processes, uids); + mTmpProcessSet.clear(); + // Now processes contains app's downstream and app + final int size = processes.size(); + for (int i = 0; i < size; i++) { + ProcessRecord proc = processes.get(i); + mCachedAppOptimizer.unfreezeTemporarily(proc, reason); + } + processes.clear(); + } } diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java index bca39ae648239..b74729b36cd2d 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java @@ -222,7 +222,7 @@ public class BroadcastQueueTest { realAms.mActivityTaskManager = new ActivityTaskManagerService(mContext); realAms.mActivityTaskManager.initialize(null, null, mContext.getMainLooper()); realAms.mAtmInternal = spy(realAms.mActivityTaskManager.getAtmInternal()); - realAms.mOomAdjuster.mCachedAppOptimizer = spy(realAms.mOomAdjuster.mCachedAppOptimizer); + realAms.mOomAdjuster = spy(realAms.mOomAdjuster); realAms.mPackageManagerInt = mPackageManagerInt; realAms.mUsageStatsService = mUsageStatsManagerInt; realAms.mProcessesReady = true; @@ -951,7 +951,7 @@ public class BroadcastQueueTest { // cold-started apps to be thawed, but the modern stack does } else { // Confirm that app was thawed - verify(mAms.mOomAdjuster.mCachedAppOptimizer, atLeastOnce()).unfreezeTemporarily( + verify(mAms.mOomAdjuster, atLeastOnce()).unfreezeTemporarily( eq(receiverApp), eq(OomAdjuster.OOM_ADJ_REASON_START_RECEIVER)); // Confirm that we added package to process @@ -1394,7 +1394,7 @@ public class BroadcastQueueTest { anyInt(), any()); // Finally, verify that we thawed the final receiver - verify(mAms.mOomAdjuster.mCachedAppOptimizer).unfreezeTemporarily(eq(callerApp), + verify(mAms.mOomAdjuster).unfreezeTemporarily(eq(callerApp), eq(OomAdjuster.OOM_ADJ_REASON_FINISH_RECEIVER)); }