diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index eec68dc7353e6..be483747d2cf8 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -911,10 +911,12 @@ public final class CachedAppOptimizer { pid = proc.pid; name = proc.processName; - if (proc.curAdj <= ProcessList.CACHED_APP_MIN_ADJ) { + if (proc.curAdj < ProcessList.CACHED_APP_MIN_ADJ + || proc.shouldNotFreeze) { if (DEBUG_FREEZER) { Slog.d(TAG_AM, "Skipping freeze for process " + pid - + " " + name + " (not cached)"); + + " " + name + " curAdj = " + proc.curAdj + + ", shouldNotFreeze = " + proc.shouldNotFreeze); } return; } diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index c239feb155c67..3fd1b7830ba05 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -1109,6 +1109,7 @@ public final class OomAdjuster { app.adjTarget = null; app.empty = false; app.setCached(false); + app.shouldNotFreeze = false; final int appUid = app.info.uid; final int logUid = mService.mCurOomAdjUid; @@ -1542,23 +1543,24 @@ public final class OomAdjuster { } boolean trackedProcState = false; - if ((cr.flags& Context.BIND_WAIVE_PRIORITY) == 0) { - ProcessRecord client = cr.binding.client; - if (computeClients) { - computeOomAdjLocked(client, cachedAdj, topApp, doingAll, now, - cycleReEval, true); - } else { - client.setCurRawAdj(client.setAdj); - client.setCurRawProcState(client.setProcState); - } + ProcessRecord client = cr.binding.client; + if (computeClients) { + computeOomAdjLocked(client, cachedAdj, topApp, doingAll, now, + cycleReEval, true); + } else { + client.setCurRawAdj(client.setAdj); + client.setCurRawProcState(client.setProcState); + } + + int clientAdj = client.getCurRawAdj(); + int clientProcState = client.getCurRawProcState(); + + if ((cr.flags & Context.BIND_WAIVE_PRIORITY) == 0) { if (shouldSkipDueToCycle(app, client, procState, adj, cycleReEval)) { continue; } - int clientAdj = client.getCurRawAdj(); - int clientProcState = client.getCurRawProcState(); - if (clientProcState == PROCESS_STATE_FOREGROUND_SERVICE) { procStateFromFGSClient = true; } @@ -1762,6 +1764,19 @@ public final class OomAdjuster { + ProcessList.makeProcStateString(procState)); } } + } else { // BIND_WAIVE_PRIORITY == true + // BIND_WAIVE_PRIORITY bindings are special when it comes to the + // freezer. Processes bound via WPRI are expected to be running, + // but they are not promoted in the LRU list to keep them out of + // cached. As a result, they can freeze based on oom_adj alone. + // Normally, bindToDeath would fire when a cached app would die + // in the background, but nothing will fire when a running process + // pings a frozen process. Accordingly, any cached app that is + // bound by an unfrozen app via a WPRI binding has to remain + // unfrozen. + if (clientAdj < ProcessList.CACHED_APP_MIN_ADJ) { + app.shouldNotFreeze = true; + } } if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { app.treatLikeActivity = true; diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index c2f03ec8d6c41..f2ca1daec3063 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -167,6 +167,7 @@ class ProcessRecord implements WindowProcessListener { int lastCompactAction; // The most recent compaction action performed for this app. boolean frozen; // True when the process is frozen. long freezeUnfreezeTime; // Last time the app was (un)frozen, 0 for never + boolean shouldNotFreeze; // True if a process has a WPRI binding from an unfrozen process private int mCurSchedGroup; // Currently desired scheduling class int setSchedGroup; // Last set to background scheduling class int trimMemoryLevel; // Last selected memory trimming level