Loading core/java/android/content/Context.java +9 −0 Original line number Diff line number Diff line Loading @@ -326,6 +326,15 @@ public abstract class Context { */ public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0080; /** * Flag for {@link #bindService}: If binding from something better than perceptible, * still set the adjust below perceptible. This would be used for bound services that can * afford to be evicted when under extreme memory pressure, but should be restarted as soon * as possible. * @hide */ public static final int BIND_ADJUST_BELOW_PERCEPTIBLE = 0x0100; /** * @hide Flag for {@link #bindService}: allows binding to a service provided * by an instant app. Note that the caller may not have access to the instant Loading services/core/java/com/android/server/am/ActivityManagerConstants.java +10 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ final class ActivityManagerConstants extends ContentObserver { static final String KEY_BOUND_SERVICE_CRASH_MAX_RETRY = "service_crash_max_retry"; static final String KEY_PROCESS_START_ASYNC = "process_start_async"; static final String KEY_MEMORY_INFO_THROTTLE_TIME = "memory_info_throttle_time"; static final String KEY_TOP_TO_FGS_GRACE_DURATION = "top_to_fgs_grace_duration"; private static final int DEFAULT_MAX_CACHED_PROCESSES = 32; private static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60*1000; Loading Loading @@ -97,6 +98,7 @@ final class ActivityManagerConstants extends ContentObserver { private static final int DEFAULT_BOUND_SERVICE_CRASH_MAX_RETRY = 16; private static final boolean DEFAULT_PROCESS_START_ASYNC = true; private static final long DEFAULT_MEMORY_INFO_THROTTLE_TIME = 5*60*1000; private static final long DEFAULT_TOP_TO_FGS_GRACE_DURATION = 15 * 1000; // Maximum number of cached processes we will allow. public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES; Loading Loading @@ -212,6 +214,10 @@ final class ActivityManagerConstants extends ContentObserver { // throttle requests from apps. public long MEMORY_INFO_THROTTLE_TIME = DEFAULT_MEMORY_INFO_THROTTLE_TIME; // Allow app just moving from TOP to FOREGROUND_SERVICE to stay in a higher adj value for // this long. public long TOP_TO_FGS_GRACE_DURATION = DEFAULT_TOP_TO_FGS_GRACE_DURATION; // Indicates whether the activity starts logging is enabled. // Controlled by Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED boolean mFlagActivityStartsLoggingEnabled; Loading Loading @@ -355,6 +361,8 @@ final class ActivityManagerConstants extends ContentObserver { DEFAULT_PROCESS_START_ASYNC); MEMORY_INFO_THROTTLE_TIME = mParser.getLong(KEY_MEMORY_INFO_THROTTLE_TIME, DEFAULT_MEMORY_INFO_THROTTLE_TIME); TOP_TO_FGS_GRACE_DURATION = mParser.getDurationMillis(KEY_TOP_TO_FGS_GRACE_DURATION, DEFAULT_TOP_TO_FGS_GRACE_DURATION); updateMaxCachedProcesses(); } Loading Loading @@ -438,6 +446,8 @@ final class ActivityManagerConstants extends ContentObserver { pw.println(FLAG_PROCESS_START_ASYNC); pw.print(" "); pw.print(KEY_MEMORY_INFO_THROTTLE_TIME); pw.print("="); pw.println(MEMORY_INFO_THROTTLE_TIME); pw.print(" "); pw.print(KEY_TOP_TO_FGS_GRACE_DURATION); pw.print("="); pw.println(TOP_TO_FGS_GRACE_DURATION); pw.println(); if (mOverrideMaxCachedProcesses >= 0) { Loading services/core/java/com/android/server/am/ActivityManagerService.java +26 −0 Original line number Diff line number Diff line Loading @@ -17778,6 +17778,19 @@ public class ActivityManagerService extends IActivityManager.Stub } } // If the app was recently in the foreground and moved to a foreground service status, // allow it to get a higher rank in memory for some time, compared to other foreground // services so that it can finish performing any persistence/processing of in-memory state. if (app.hasForegroundServices() && adj > ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ && (app.lastTopTime + mConstants.TOP_TO_FGS_GRACE_DURATION > now || app.setProcState <= ActivityManager.PROCESS_STATE_TOP)) { adj = ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ; app.adjType = "fg-service-act"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to recent fg: " + app); } } if (adj > ProcessList.PERCEPTIBLE_APP_ADJ || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) { if (app.forcingToImportant != null) { Loading Loading @@ -18045,6 +18058,10 @@ public class ActivityManagerService extends IActivityManager.Stub cr.trackProcState(procState, mAdjSeq, now); trackedProcState = true; } } else if ((cr.flags & Context.BIND_ADJUST_BELOW_PERCEPTIBLE) != 0 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ && adj > ProcessList.PERCEPTIBLE_APP_ADJ + 1) { newAdj = ProcessList.PERCEPTIBLE_APP_ADJ + 1; } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { Loading Loading @@ -19044,6 +19061,8 @@ public class ActivityManagerService extends IActivityManager.Stub // Must be called before updating setProcState maybeUpdateUsageStatsLocked(app, nowElapsed); maybeUpdateLastTopTime(app, now); app.setProcState = app.curProcState; if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { app.notCachedSinceIdle = false; Loading Loading @@ -19268,6 +19287,13 @@ public class ActivityManagerService extends IActivityManager.Stub } } private void maybeUpdateLastTopTime(ProcessRecord app, long nowUptime) { if (app.setProcState <= ActivityManager.PROCESS_STATE_TOP && app.curProcState > ActivityManager.PROCESS_STATE_TOP) { app.lastTopTime = nowUptime; } } private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { if (proc.thread != null && proc.baseProcessTracker != null) { proc.baseProcessTracker.setState( services/core/java/com/android/server/am/ProcessList.java +5 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,11 @@ public final class ProcessList { static final int VISIBLE_APP_ADJ = 100; static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1; // This is a process that was recently TOP and moved to FGS. Continue to treat it almost // like a foreground app for a while. // @see TOP_TO_FGS_GRACE_PERIOD static final int PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50; // This is the process running the current foreground app. We'd really // rather not kill it! static final int FOREGROUND_APP_ADJ = 0; Loading services/core/java/com/android/server/am/ProcessRecord.java +6 −0 Original line number Diff line number Diff line Loading @@ -198,6 +198,7 @@ final class ProcessRecord implements WindowProcessListener { long lastRequestedGc; // When we last asked the app to do a gc long lastLowMemory; // When we last told the app that memory is low long lastProviderTime; // The last time someone else was using a provider in this process. long lastTopTime; // The last time the process was in the TOP state or greater. boolean reportLowMemory; // Set to true when waiting to report low mem boolean empty; // Is this an empty background process? boolean cached; // Is this a cached process? Loading Loading @@ -415,6 +416,11 @@ final class ProcessRecord implements WindowProcessListener { TimeUtils.formatDuration(lastProviderTime, nowUptime, pw); pw.println(); } if (lastTopTime > 0) { pw.print(prefix); pw.print("lastTopTime="); TimeUtils.formatDuration(lastTopTime, nowUptime, pw); pw.println(); } if (hasStartedServices) { pw.print(prefix); pw.print("hasStartedServices="); pw.println(hasStartedServices); } Loading Loading
core/java/android/content/Context.java +9 −0 Original line number Diff line number Diff line Loading @@ -326,6 +326,15 @@ public abstract class Context { */ public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0080; /** * Flag for {@link #bindService}: If binding from something better than perceptible, * still set the adjust below perceptible. This would be used for bound services that can * afford to be evicted when under extreme memory pressure, but should be restarted as soon * as possible. * @hide */ public static final int BIND_ADJUST_BELOW_PERCEPTIBLE = 0x0100; /** * @hide Flag for {@link #bindService}: allows binding to a service provided * by an instant app. Note that the caller may not have access to the instant Loading
services/core/java/com/android/server/am/ActivityManagerConstants.java +10 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ final class ActivityManagerConstants extends ContentObserver { static final String KEY_BOUND_SERVICE_CRASH_MAX_RETRY = "service_crash_max_retry"; static final String KEY_PROCESS_START_ASYNC = "process_start_async"; static final String KEY_MEMORY_INFO_THROTTLE_TIME = "memory_info_throttle_time"; static final String KEY_TOP_TO_FGS_GRACE_DURATION = "top_to_fgs_grace_duration"; private static final int DEFAULT_MAX_CACHED_PROCESSES = 32; private static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60*1000; Loading Loading @@ -97,6 +98,7 @@ final class ActivityManagerConstants extends ContentObserver { private static final int DEFAULT_BOUND_SERVICE_CRASH_MAX_RETRY = 16; private static final boolean DEFAULT_PROCESS_START_ASYNC = true; private static final long DEFAULT_MEMORY_INFO_THROTTLE_TIME = 5*60*1000; private static final long DEFAULT_TOP_TO_FGS_GRACE_DURATION = 15 * 1000; // Maximum number of cached processes we will allow. public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES; Loading Loading @@ -212,6 +214,10 @@ final class ActivityManagerConstants extends ContentObserver { // throttle requests from apps. public long MEMORY_INFO_THROTTLE_TIME = DEFAULT_MEMORY_INFO_THROTTLE_TIME; // Allow app just moving from TOP to FOREGROUND_SERVICE to stay in a higher adj value for // this long. public long TOP_TO_FGS_GRACE_DURATION = DEFAULT_TOP_TO_FGS_GRACE_DURATION; // Indicates whether the activity starts logging is enabled. // Controlled by Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED boolean mFlagActivityStartsLoggingEnabled; Loading Loading @@ -355,6 +361,8 @@ final class ActivityManagerConstants extends ContentObserver { DEFAULT_PROCESS_START_ASYNC); MEMORY_INFO_THROTTLE_TIME = mParser.getLong(KEY_MEMORY_INFO_THROTTLE_TIME, DEFAULT_MEMORY_INFO_THROTTLE_TIME); TOP_TO_FGS_GRACE_DURATION = mParser.getDurationMillis(KEY_TOP_TO_FGS_GRACE_DURATION, DEFAULT_TOP_TO_FGS_GRACE_DURATION); updateMaxCachedProcesses(); } Loading Loading @@ -438,6 +446,8 @@ final class ActivityManagerConstants extends ContentObserver { pw.println(FLAG_PROCESS_START_ASYNC); pw.print(" "); pw.print(KEY_MEMORY_INFO_THROTTLE_TIME); pw.print("="); pw.println(MEMORY_INFO_THROTTLE_TIME); pw.print(" "); pw.print(KEY_TOP_TO_FGS_GRACE_DURATION); pw.print("="); pw.println(TOP_TO_FGS_GRACE_DURATION); pw.println(); if (mOverrideMaxCachedProcesses >= 0) { Loading
services/core/java/com/android/server/am/ActivityManagerService.java +26 −0 Original line number Diff line number Diff line Loading @@ -17778,6 +17778,19 @@ public class ActivityManagerService extends IActivityManager.Stub } } // If the app was recently in the foreground and moved to a foreground service status, // allow it to get a higher rank in memory for some time, compared to other foreground // services so that it can finish performing any persistence/processing of in-memory state. if (app.hasForegroundServices() && adj > ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ && (app.lastTopTime + mConstants.TOP_TO_FGS_GRACE_DURATION > now || app.setProcState <= ActivityManager.PROCESS_STATE_TOP)) { adj = ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ; app.adjType = "fg-service-act"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to recent fg: " + app); } } if (adj > ProcessList.PERCEPTIBLE_APP_ADJ || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) { if (app.forcingToImportant != null) { Loading Loading @@ -18045,6 +18058,10 @@ public class ActivityManagerService extends IActivityManager.Stub cr.trackProcState(procState, mAdjSeq, now); trackedProcState = true; } } else if ((cr.flags & Context.BIND_ADJUST_BELOW_PERCEPTIBLE) != 0 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ && adj > ProcessList.PERCEPTIBLE_APP_ADJ + 1) { newAdj = ProcessList.PERCEPTIBLE_APP_ADJ + 1; } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { Loading Loading @@ -19044,6 +19061,8 @@ public class ActivityManagerService extends IActivityManager.Stub // Must be called before updating setProcState maybeUpdateUsageStatsLocked(app, nowElapsed); maybeUpdateLastTopTime(app, now); app.setProcState = app.curProcState; if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { app.notCachedSinceIdle = false; Loading Loading @@ -19268,6 +19287,13 @@ public class ActivityManagerService extends IActivityManager.Stub } } private void maybeUpdateLastTopTime(ProcessRecord app, long nowUptime) { if (app.setProcState <= ActivityManager.PROCESS_STATE_TOP && app.curProcState > ActivityManager.PROCESS_STATE_TOP) { app.lastTopTime = nowUptime; } } private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { if (proc.thread != null && proc.baseProcessTracker != null) { proc.baseProcessTracker.setState(
services/core/java/com/android/server/am/ProcessList.java +5 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,11 @@ public final class ProcessList { static final int VISIBLE_APP_ADJ = 100; static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1; // This is a process that was recently TOP and moved to FGS. Continue to treat it almost // like a foreground app for a while. // @see TOP_TO_FGS_GRACE_PERIOD static final int PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50; // This is the process running the current foreground app. We'd really // rather not kill it! static final int FOREGROUND_APP_ADJ = 0; Loading
services/core/java/com/android/server/am/ProcessRecord.java +6 −0 Original line number Diff line number Diff line Loading @@ -198,6 +198,7 @@ final class ProcessRecord implements WindowProcessListener { long lastRequestedGc; // When we last asked the app to do a gc long lastLowMemory; // When we last told the app that memory is low long lastProviderTime; // The last time someone else was using a provider in this process. long lastTopTime; // The last time the process was in the TOP state or greater. boolean reportLowMemory; // Set to true when waiting to report low mem boolean empty; // Is this an empty background process? boolean cached; // Is this a cached process? Loading Loading @@ -415,6 +416,11 @@ final class ProcessRecord implements WindowProcessListener { TimeUtils.formatDuration(lastProviderTime, nowUptime, pw); pw.println(); } if (lastTopTime > 0) { pw.print(prefix); pw.print("lastTopTime="); TimeUtils.formatDuration(lastTopTime, nowUptime, pw); pw.println(); } if (hasStartedServices) { pw.print(prefix); pw.print("hasStartedServices="); pw.println(hasStartedServices); } Loading