OomAdjuster: demote previous process to cached after configurable timeout

Previous processes shouldn't stay out of cached indefinitely; they
should be eventually moved to cached and allowed to be restricted and
frozen. Add a configurable timeout to decide when the previous app
should move to cached.

The default timeout is 60s.

Bug: 261065790
Test: atest MockingOomAdjusterTests

Change-Id: I2a999bbf5915467343441afcf276437e34459051
This commit is contained in:
Tim Murray
2022-11-28 17:52:45 -08:00
parent 17072cefab
commit 1c125c00da
2 changed files with 45 additions and 16 deletions

View File

@@ -129,6 +129,7 @@ final class ActivityManagerConstants extends ContentObserver {
static final String KEY_KILL_BG_RESTRICTED_CACHED_IDLE = "kill_bg_restricted_cached_idle";
static final String KEY_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME =
"kill_bg_restricted_cached_idle_settle_time";
static final String KEY_MAX_PREVIOUS_TIME = "max_previous_time";
/**
* Note this key is on {@link DeviceConfig#NAMESPACE_ACTIVITY_MANAGER_COMPONENT_ALIAS}.
* @see #mEnableComponentAlias
@@ -192,6 +193,7 @@ final class ActivityManagerConstants extends ContentObserver {
private static final float DEFAULT_FGS_START_DENIED_LOG_SAMPLE_RATE = 1; // 100%
private static final long DEFAULT_PROCESS_KILL_TIMEOUT_MS = 10 * 1000;
private static final long DEFAULT_NETWORK_ACCESS_TIMEOUT_MS = 200; // 0.2 sec
private static final long DEFAULT_MAX_PREVIOUS_TIME = 60 * 1000; // 60s
static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60 * 1000;
static final long DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME_MS = 60 * 1000;
@@ -522,6 +524,9 @@ final class ActivityManagerConstants extends ContentObserver {
public long TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION =
DEFAULT_TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION;
// How long a process can remain at previous oom_adj before dropping to cached
public static long MAX_PREVIOUS_TIME = DEFAULT_MAX_PREVIOUS_TIME;
/**
* The minimum time we allow between crashes, for us to consider this
* application to be bad and stop its services and reject broadcasts.
@@ -1144,6 +1149,10 @@ final class ActivityManagerConstants extends ContentObserver {
break;
case KEY_TOP_TO_FGS_GRACE_DURATION:
updateTopToFgsGraceDuration();
break;
case KEY_MAX_PREVIOUS_TIME:
updateMaxPreviousTime();
break;
default:
break;
}
@@ -1790,6 +1799,7 @@ final class ActivityManagerConstants extends ContentObserver {
DEFAULT_LOW_SWAP_THRESHOLD_PERCENT);
}
private void updateTopToFgsGraceDuration() {
TOP_TO_FGS_GRACE_DURATION = DeviceConfig.getLong(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -1797,6 +1807,13 @@ final class ActivityManagerConstants extends ContentObserver {
DEFAULT_TOP_TO_FGS_GRACE_DURATION);
}
private void updateMaxPreviousTime() {
MAX_PREVIOUS_TIME = DeviceConfig.getLong(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
KEY_MAX_PREVIOUS_TIME,
DEFAULT_MAX_PREVIOUS_TIME);
}
private void updateMinAssocLogDuration() {
MIN_ASSOC_LOG_DURATION = DeviceConfig.getLong(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_MIN_ASSOC_LOG_DURATION,

View File

@@ -1961,25 +1961,37 @@ public class OomAdjuster {
}
}
}
if (state.getCachedIsPreviousProcess() && state.getCachedHasActivities()) {
if (adj > PREVIOUS_APP_ADJ) {
// This was the previous process that showed UI to the user.
// We want to try to keep it around more aggressively, to give
// a good experience around switching between two apps.
adj = PREVIOUS_APP_ADJ;
schedGroup = SCHED_GROUP_BACKGROUND;
state.setCached(false);
state.setAdjType("previous");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to prev: " + app);
}
}
if (procState > PROCESS_STATE_LAST_ACTIVITY) {
// This was the previous process that showed UI to the user. We want to
// try to keep it around more aggressively, to give a good experience
// around switching between two apps. However, we don't want to keep the
// process in this privileged state indefinitely. Eventually, allow the
// app to be demoted to cached.
if ((state.getSetProcState() == PROCESS_STATE_LAST_ACTIVITY
&& (state.getLastStateTime() + mConstants.MAX_PREVIOUS_TIME) < now)) {
procState = PROCESS_STATE_LAST_ACTIVITY;
state.setAdjType("previous");
schedGroup = SCHED_GROUP_BACKGROUND;
state.setAdjType("previous-expired");
adj = CACHED_APP_MIN_ADJ;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to prev: " + app);
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Expire prev adj: " + app);
}
} else {
if (adj > PREVIOUS_APP_ADJ) {
adj = PREVIOUS_APP_ADJ;
schedGroup = SCHED_GROUP_BACKGROUND;
state.setCached(false);
state.setAdjType("previous");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to prev: " + app);
}
}
if (procState > PROCESS_STATE_LAST_ACTIVITY) {
procState = PROCESS_STATE_LAST_ACTIVITY;
state.setAdjType("previous");
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to prev: " + app);
}
}
}
}