From 7b4b26bab5667430e46d7653ce230de23e32e7c9 Mon Sep 17 00:00:00 2001 From: Tim Murray Date: Wed, 26 Feb 2020 09:20:32 -0800 Subject: [PATCH] freezer: don't freeze WPRI-bound apps If an app is bound with WPRI, it's expected to be responsive to communication from other apps even though it could be in the cached state. In this case, freezing an app that is bound via a WPRI binding will cause some other app to hang because it will not receive a message from those apps. As a result, don't freeze these apps. Test: webview-using apps work reliably when freezer is enabled Bug: 150114383 Change-Id: I72f71bbe3dc54ed0c274d518250ac9d00310c2d5 --- .../android/server/am/CachedAppOptimizer.java | 6 ++- .../com/android/server/am/OomAdjuster.java | 39 +++++++++++++------ .../com/android/server/am/ProcessRecord.java | 1 + 3 files changed, 32 insertions(+), 14 deletions(-) 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