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
This commit is contained in:
Tim Murray
2020-02-26 09:20:32 -08:00
parent 0b66590fbf
commit 7b4b26bab5
3 changed files with 32 additions and 14 deletions

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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