Loading core/java/android/app/ActivityManager.java +10 −1 Original line number Diff line number Diff line Loading @@ -1016,6 +1016,12 @@ public class ActivityManager { */ public static final int PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL = 1 << 6; /** * @hide * Process is guaranteed cpu time (IE. it will not be frozen). */ public static final int PROCESS_CAPABILITY_CPU_TIME = 1 << 7; /** * @hide all capabilities, the ORing of all flags in {@link ProcessCapability}. * Loading @@ -1028,7 +1034,8 @@ public class ActivityManager { | PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK | PROCESS_CAPABILITY_BFSL | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK | PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL; | PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL | PROCESS_CAPABILITY_CPU_TIME; /** * All implicit capabilities. This capability set is currently only used for processes under Loading @@ -1053,6 +1060,7 @@ public class ActivityManager { pw.print((caps & PROCESS_CAPABILITY_BFSL) != 0 ? 'F' : '-'); pw.print((caps & PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK) != 0 ? 'U' : '-'); pw.print((caps & PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL) != 0 ? 'A' : '-'); pw.print((caps & PROCESS_CAPABILITY_CPU_TIME) != 0 ? 'T' : '-'); } /** @hide */ Loading @@ -1065,6 +1073,7 @@ public class ActivityManager { sb.append((caps & PROCESS_CAPABILITY_BFSL) != 0 ? 'F' : '-'); sb.append((caps & PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK) != 0 ? 'U' : '-'); sb.append((caps & PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL) != 0 ? 'A' : '-'); sb.append((caps & PROCESS_CAPABILITY_CPU_TIME) != 0 ? 'T' : '-'); } /** Loading services/core/java/com/android/server/am/CachedAppOptimizer.java +1 −1 Original line number Diff line number Diff line Loading @@ -101,7 +101,7 @@ import java.util.Random; import java.util.Set; import java.util.concurrent.Executor; public final class CachedAppOptimizer { public class CachedAppOptimizer { // Flags stored in the DeviceConfig API. @VisibleForTesting static final String KEY_USE_COMPACTION = "use_compaction"; Loading services/core/java/com/android/server/am/OomAdjuster.java +163 −41 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.am; import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL; import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL_IMPLICIT; import static android.app.ActivityManager.PROCESS_CAPABILITY_BFSL; import static android.app.ActivityManager.PROCESS_CAPABILITY_CPU_TIME; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION; Loading Loading @@ -155,6 +156,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.Trace; import android.os.UserHandle; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; Loading Loading @@ -469,7 +471,6 @@ public class OomAdjuster { } Process.setThreadPriority(tid, priority); } } // TODO(b/346822474): hook up global state usage. Loading Loading @@ -499,7 +500,8 @@ public class OomAdjuster { } OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids, ServiceThread adjusterThread, GlobalState globalState, Injector injector) { ServiceThread adjusterThread, GlobalState globalState, CachedAppOptimizer cachedAppOptimizer, Injector injector) { mService = service; mGlobalState = globalState; mInjector = injector; Loading @@ -508,7 +510,7 @@ public class OomAdjuster { mActiveUids = activeUids; mConstants = mService.mConstants; mCachedAppOptimizer = new CachedAppOptimizer(mService); mCachedAppOptimizer = cachedAppOptimizer; mCacheOomRanker = new CacheOomRanker(service); mLogger = new OomAdjusterDebugLogger(this, mService.mConstants); Loading Loading @@ -2590,6 +2592,7 @@ public class OomAdjuster { } capability |= getDefaultCapability(app, procState); capability |= getCpuCapability(app, now); // Procstates below BFGS should never have this capability. if (procState > PROCESS_STATE_BOUND_FOREGROUND_SERVICE) { Loading Loading @@ -2732,10 +2735,14 @@ public class OomAdjuster { if (app.mOptRecord.setShouldNotFreeze(true, dryRun, app.mOptRecord.shouldNotFreezeReason() | client.mOptRecord.shouldNotFreezeReason(), mAdjSeq)) { if (Flags.useCpuTimeCapability()) { // Do nothing, capability updated check will handle the dryrun output. } else { // Bail out early, as we only care about the return value for a dryrun. return true; } } } boolean trackedProcState = false; Loading @@ -2744,6 +2751,8 @@ public class OomAdjuster { // we check the final procstate, and remove it if the procsate is below BFGS. capability |= getBfslCapabilityFromClient(client); capability |= getCpuCapabilityFromClient(client); if (cr.notHasFlag(Context.BIND_WAIVE_PRIORITY)) { if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) { capability |= cstate.getCurCapability(); Loading Loading @@ -2802,10 +2811,15 @@ public class OomAdjuster { app.mOptRecord.shouldNotFreezeReason() | ProcessCachedOptimizerRecord .SHOULD_NOT_FREEZE_REASON_BINDER_ALLOW_OOM_MANAGEMENT, mAdjSeq)) { if (Flags.useCpuTimeCapability()) { // Do nothing, capability updated check will handle the dryrun output. } else { // Bail out early, as we only care about the return value for a dryrun. return true; } } capability |= PROCESS_CAPABILITY_CPU_TIME; } // Not doing bind OOM management, so treat // this guy more like a started service. if (state.hasShownUi() && !state.getCachedIsHomeProcess()) { Loading Loading @@ -3046,10 +3060,15 @@ public class OomAdjuster { app.mOptRecord.shouldNotFreezeReason() | ProcessCachedOptimizerRecord .SHOULD_NOT_FREEZE_REASON_BIND_WAIVE_PRIORITY, mAdjSeq)) { if (Flags.useCpuTimeCapability()) { // Do nothing, capability updated check will handle the dryrun output. } else { // Bail out early, as we only care about the return value for a dryrun. return true; } } capability |= PROCESS_CAPABILITY_CPU_TIME; } } if (cr.hasFlag(Context.BIND_TREAT_LIKE_ACTIVITY)) { if (!dryRun) { Loading Loading @@ -3101,9 +3120,24 @@ public class OomAdjuster { capability &= ~PROCESS_CAPABILITY_BFSL; } if (!updated) { updated = adj < prevRawAdj || procState < prevProcState || schedGroup > prevSchedGroup || (capability != prevCapability && (capability & prevCapability) == prevCapability); if (adj < prevRawAdj || procState < prevProcState || schedGroup > prevSchedGroup) { updated = true; } if (Flags.useCpuTimeCapability()) { if ((capability != prevCapability) && ((capability & prevCapability) == prevCapability)) { updated = true; } } else { // Ignore PROCESS_CAPABILITY_CPU_TIME in capability comparison final int curFiltered = capability & ~PROCESS_CAPABILITY_CPU_TIME; final int prevFiltered = prevCapability & ~PROCESS_CAPABILITY_CPU_TIME; if ((curFiltered != prevFiltered) && ((curFiltered & prevFiltered) == prevFiltered)) { updated = true; } } } if (dryRun) { Loading Loading @@ -3179,6 +3213,8 @@ public class OomAdjuster { // we check the final procstate, and remove it if the procsate is below BFGS. capability |= getBfslCapabilityFromClient(client); capability |= getCpuCapabilityFromClient(client); if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) { // If the other app is cached for any reason, for purposes here // we are going to consider it empty. Loading @@ -3189,10 +3225,14 @@ public class OomAdjuster { if (app.mOptRecord.setShouldNotFreeze(true, dryRun, app.mOptRecord.shouldNotFreezeReason() | client.mOptRecord.shouldNotFreezeReason(), mAdjSeq)) { if (Flags.useCpuTimeCapability()) { // Do nothing, capability updated check will handle the dryrun output. } else { // Bail out early, as we only care about the return value for a dryrun. return true; } } } if (!dryRun) { state.setCurBoundByNonBgRestrictedApp(state.isCurBoundByNonBgRestrictedApp() Loading Loading @@ -3266,12 +3306,27 @@ public class OomAdjuster { capability &= ~PROCESS_CAPABILITY_BFSL; } if (dryRun && (adj < prevRawAdj || procState < prevProcState || schedGroup > prevSchedGroup || (capability != prevCapability && (capability & prevCapability) == prevCapability))) { if (dryRun) { if (adj < prevRawAdj || procState < prevProcState || schedGroup > prevSchedGroup) { return true; } if (Flags.useCpuTimeCapability()) { if ((capability != prevCapability) && ((capability & prevCapability) == prevCapability)) { return true; } } else { // Ignore PROCESS_CAPABILITY_CPU_TIME in capability comparison final int curFiltered = capability & ~PROCESS_CAPABILITY_CPU_TIME; final int prevFiltered = prevCapability & ~PROCESS_CAPABILITY_CPU_TIME; if ((curFiltered != prevFiltered) && ((curFiltered & prevFiltered) == prevFiltered)) { return true; } } } if (adj < prevRawAdj) { schedGroup = setIntermediateAdjLSP(app, adj, prevRawAdj, schedGroup); } Loading Loading @@ -3321,6 +3376,29 @@ public class OomAdjuster { return baseCapabilities | networkCapabilities; } private static int getCpuCapability(ProcessRecord app, long nowUptime) { final UidRecord uidRec = app.getUidRecord(); if (uidRec != null && uidRec.isCurAllowListed()) { // Process has user visible activities. return PROCESS_CAPABILITY_CPU_TIME; } if (UserHandle.isCore(app.uid)) { // Make sure all system components are not frozen. return PROCESS_CAPABILITY_CPU_TIME; } if (app.mState.getCachedHasVisibleActivities()) { // Process has user visible activities. return PROCESS_CAPABILITY_CPU_TIME; } if (app.mServices.hasUndemotedShortForegroundService(nowUptime)) { // It running a short fgs, just give it cpu time. return PROCESS_CAPABILITY_CPU_TIME; } // TODO(b/370817323): Populate this method with all of the reasons to keep a process // unfrozen. return 0; } /** * @return the BFSL capability from a client (of a service binding or provider). */ Loading Loading @@ -3368,6 +3446,15 @@ public class OomAdjuster { return client.mState.getCurCapability() & PROCESS_CAPABILITY_BFSL; } /** * @return the CPU capability from a client (of a service binding or provider). */ private static int getCpuCapabilityFromClient(ProcessRecord client) { // Just grant CPU capability every time // TODO(b/370817323): Populate with reasons to not propagate cpu capability across bindings. return client.mState.getCurCapability() & PROCESS_CAPABILITY_CPU_TIME; } /** * Checks if for the given app and client, there's a cycle that should skip over the client * for now or use partial values to evaluate the effect of the client binding. Loading Loading @@ -3949,6 +4036,39 @@ public class OomAdjuster { mCacheOomRanker.dump(pw); } /** * Return whether or not a process should be frozen. */ boolean getFreezePolicy(ProcessRecord proc) { // Reasons to not freeze: if (Flags.useCpuTimeCapability()) { if ((proc.mState.getCurCapability() & PROCESS_CAPABILITY_CPU_TIME) != 0) { /// App is important enough (see {@link #getCpuCapability}) or bound by something /// important enough to not be frozen. return false; } } else { // The CPU capability handling covers all setShouldNotFreeze paths. Must check // shouldNotFreeze, if the CPU capability is not being used. if (proc.mOptRecord.shouldNotFreeze()) { return false; } } if (proc.mOptRecord.isFreezeExempt()) { return false; } // Reasons to freeze: if (proc.mState.getCurAdj() >= FREEZER_CUTOFF_ADJ) { // Oomscore is in a high enough state, it is safe to freeze. return true; } // Default, do not freeze a process. return false; } @GuardedBy({"mService", "mProcLock"}) void updateAppFreezeStateLSP(ProcessRecord app, @OomAdjReason int oomAdjReason, boolean immediate, int oldOomAdj) { Loading @@ -3963,45 +4083,46 @@ public class OomAdjuster { (state.getCurAdj() >= FREEZER_CUTOFF_ADJ ^ oldOomAdj >= FREEZER_CUTOFF_ADJ) || oldOomAdj == UNKNOWN_ADJ; final boolean shouldNotFreezeChanged = opt.shouldNotFreezeAdjSeq() == mAdjSeq; if ((oomAdjChanged || shouldNotFreezeChanged) final boolean hasCpuCapability = (PROCESS_CAPABILITY_CPU_TIME & app.mState.getCurCapability()) == PROCESS_CAPABILITY_CPU_TIME; final boolean usedToHaveCpuCapability = (PROCESS_CAPABILITY_CPU_TIME & app.mState.getSetCapability()) == PROCESS_CAPABILITY_CPU_TIME; final boolean cpuCapabilityChanged = hasCpuCapability != usedToHaveCpuCapability; if ((oomAdjChanged || shouldNotFreezeChanged || cpuCapabilityChanged) && Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) { Trace.instantForTrack(Trace.TRACE_TAG_ACTIVITY_MANAGER, CachedAppOptimizer.ATRACE_FREEZER_TRACK, "updateAppFreezeStateLSP " + app.processName + " pid: " + app.getPid() + " isFreezeExempt: " + opt.isFreezeExempt() + " isFrozen: " + opt.isFrozen() + " shouldNotFreeze: " + opt.shouldNotFreeze() + " shouldNotFreezeReason: " + opt.shouldNotFreezeReason() + " curAdj: " + state.getCurAdj() + " oldOomAdj: " + oldOomAdj + " immediate: " + immediate); + " immediate: " + immediate + " cpuCapability: " + hasCpuCapability); } } if (app.mOptRecord.isFreezeExempt()) { return; } // if an app is already frozen and shouldNotFreeze becomes true, immediately unfreeze if (opt.isFrozen() && opt.shouldNotFreeze()) { mCachedAppOptimizer.unfreezeAppLSP(app, CachedAppOptimizer.getUnfreezeReasonCodeFromOomAdjReason(oomAdjReason)); return; } // Use current adjustment when freezing, set adjustment when unfreezing. if (state.getCurAdj() >= FREEZER_CUTOFF_ADJ && !opt.isFrozen() && !opt.shouldNotFreeze()) { if (!immediate) { mCachedAppOptimizer.freezeAppAsyncLSP(app); } else { if (getFreezePolicy(app)) { // This process should be frozen. if (immediate && !opt.isFrozen()) { // And it will be frozen immediately. mCachedAppOptimizer.freezeAppAsyncAtEarliestLSP(app); } else if (!opt.isFrozen() || !opt.isPendingFreeze()) { mCachedAppOptimizer.freezeAppAsyncLSP(app); } } else if (state.getSetAdj() < FREEZER_CUTOFF_ADJ) { } else { // This process should not be frozen. if (opt.isFrozen() || opt.isPendingFreeze()) { mCachedAppOptimizer.unfreezeAppLSP(app, CachedAppOptimizer.getUnfreezeReasonCodeFromOomAdjReason(oomAdjReason)); } } } @GuardedBy("mService") void unfreezeTemporarily(ProcessRecord app, @OomAdjReason int reason) { Loading @@ -4023,7 +4144,8 @@ public class OomAdjuster { final int size = processes.size(); for (int i = 0; i < size; i++) { ProcessRecord proc = processes.get(i); mCachedAppOptimizer.unfreezeTemporarily(proc, reason); mCachedAppOptimizer.unfreezeTemporarily(proc, CachedAppOptimizer.getUnfreezeReasonCodeFromOomAdjReason(reason)); } processes.clear(); } Loading services/core/java/com/android/server/am/OomAdjusterModernImpl.java +3 −2 Original line number Diff line number Diff line Loading @@ -758,8 +758,9 @@ public class OomAdjusterModernImpl extends OomAdjuster { OomAdjusterModernImpl(ActivityManagerService service, ProcessList processList, ActiveUids activeUids, ServiceThread adjusterThread, GlobalState globalState, Injector injector) { super(service, processList, activeUids, adjusterThread, globalState, injector); CachedAppOptimizer cachedAppOptimizer, Injector injector) { super(service, processList, activeUids, adjusterThread, globalState, cachedAppOptimizer, injector); } private final ProcessRecordNodes mProcessRecordProcStateNodes = new ProcessRecordNodes( Loading services/core/java/com/android/server/am/ProcessServiceRecord.java +8 −2 Original line number Diff line number Diff line Loading @@ -256,18 +256,24 @@ final class ProcessServiceRecord { } // Now we need to look at all short-FGS within the process and see if all of them are // procstate-timed-out or not. return !hasUndemotedShortForegroundService(nowUptime); } boolean hasUndemotedShortForegroundService(long nowUptime) { for (int i = mServices.size() - 1; i >= 0; i--) { final ServiceRecord sr = mServices.valueAt(i); if (!sr.isShortFgs() || !sr.hasShortFgsInfo()) { continue; } if (sr.getShortFgsInfo().getProcStateDemoteTime() >= nowUptime) { return false; // This short fgs has not timed out yet. return true; } } return true; return false; } int getReportedForegroundServiceTypes() { return mRepFgServiceTypes; } Loading Loading
core/java/android/app/ActivityManager.java +10 −1 Original line number Diff line number Diff line Loading @@ -1016,6 +1016,12 @@ public class ActivityManager { */ public static final int PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL = 1 << 6; /** * @hide * Process is guaranteed cpu time (IE. it will not be frozen). */ public static final int PROCESS_CAPABILITY_CPU_TIME = 1 << 7; /** * @hide all capabilities, the ORing of all flags in {@link ProcessCapability}. * Loading @@ -1028,7 +1034,8 @@ public class ActivityManager { | PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK | PROCESS_CAPABILITY_BFSL | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK | PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL; | PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL | PROCESS_CAPABILITY_CPU_TIME; /** * All implicit capabilities. This capability set is currently only used for processes under Loading @@ -1053,6 +1060,7 @@ public class ActivityManager { pw.print((caps & PROCESS_CAPABILITY_BFSL) != 0 ? 'F' : '-'); pw.print((caps & PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK) != 0 ? 'U' : '-'); pw.print((caps & PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL) != 0 ? 'A' : '-'); pw.print((caps & PROCESS_CAPABILITY_CPU_TIME) != 0 ? 'T' : '-'); } /** @hide */ Loading @@ -1065,6 +1073,7 @@ public class ActivityManager { sb.append((caps & PROCESS_CAPABILITY_BFSL) != 0 ? 'F' : '-'); sb.append((caps & PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK) != 0 ? 'U' : '-'); sb.append((caps & PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL) != 0 ? 'A' : '-'); sb.append((caps & PROCESS_CAPABILITY_CPU_TIME) != 0 ? 'T' : '-'); } /** Loading
services/core/java/com/android/server/am/CachedAppOptimizer.java +1 −1 Original line number Diff line number Diff line Loading @@ -101,7 +101,7 @@ import java.util.Random; import java.util.Set; import java.util.concurrent.Executor; public final class CachedAppOptimizer { public class CachedAppOptimizer { // Flags stored in the DeviceConfig API. @VisibleForTesting static final String KEY_USE_COMPACTION = "use_compaction"; Loading
services/core/java/com/android/server/am/OomAdjuster.java +163 −41 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.am; import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL; import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL_IMPLICIT; import static android.app.ActivityManager.PROCESS_CAPABILITY_BFSL; import static android.app.ActivityManager.PROCESS_CAPABILITY_CPU_TIME; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION; Loading Loading @@ -155,6 +156,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.Trace; import android.os.UserHandle; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; Loading Loading @@ -469,7 +471,6 @@ public class OomAdjuster { } Process.setThreadPriority(tid, priority); } } // TODO(b/346822474): hook up global state usage. Loading Loading @@ -499,7 +500,8 @@ public class OomAdjuster { } OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids, ServiceThread adjusterThread, GlobalState globalState, Injector injector) { ServiceThread adjusterThread, GlobalState globalState, CachedAppOptimizer cachedAppOptimizer, Injector injector) { mService = service; mGlobalState = globalState; mInjector = injector; Loading @@ -508,7 +510,7 @@ public class OomAdjuster { mActiveUids = activeUids; mConstants = mService.mConstants; mCachedAppOptimizer = new CachedAppOptimizer(mService); mCachedAppOptimizer = cachedAppOptimizer; mCacheOomRanker = new CacheOomRanker(service); mLogger = new OomAdjusterDebugLogger(this, mService.mConstants); Loading Loading @@ -2590,6 +2592,7 @@ public class OomAdjuster { } capability |= getDefaultCapability(app, procState); capability |= getCpuCapability(app, now); // Procstates below BFGS should never have this capability. if (procState > PROCESS_STATE_BOUND_FOREGROUND_SERVICE) { Loading Loading @@ -2732,10 +2735,14 @@ public class OomAdjuster { if (app.mOptRecord.setShouldNotFreeze(true, dryRun, app.mOptRecord.shouldNotFreezeReason() | client.mOptRecord.shouldNotFreezeReason(), mAdjSeq)) { if (Flags.useCpuTimeCapability()) { // Do nothing, capability updated check will handle the dryrun output. } else { // Bail out early, as we only care about the return value for a dryrun. return true; } } } boolean trackedProcState = false; Loading @@ -2744,6 +2751,8 @@ public class OomAdjuster { // we check the final procstate, and remove it if the procsate is below BFGS. capability |= getBfslCapabilityFromClient(client); capability |= getCpuCapabilityFromClient(client); if (cr.notHasFlag(Context.BIND_WAIVE_PRIORITY)) { if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) { capability |= cstate.getCurCapability(); Loading Loading @@ -2802,10 +2811,15 @@ public class OomAdjuster { app.mOptRecord.shouldNotFreezeReason() | ProcessCachedOptimizerRecord .SHOULD_NOT_FREEZE_REASON_BINDER_ALLOW_OOM_MANAGEMENT, mAdjSeq)) { if (Flags.useCpuTimeCapability()) { // Do nothing, capability updated check will handle the dryrun output. } else { // Bail out early, as we only care about the return value for a dryrun. return true; } } capability |= PROCESS_CAPABILITY_CPU_TIME; } // Not doing bind OOM management, so treat // this guy more like a started service. if (state.hasShownUi() && !state.getCachedIsHomeProcess()) { Loading Loading @@ -3046,10 +3060,15 @@ public class OomAdjuster { app.mOptRecord.shouldNotFreezeReason() | ProcessCachedOptimizerRecord .SHOULD_NOT_FREEZE_REASON_BIND_WAIVE_PRIORITY, mAdjSeq)) { if (Flags.useCpuTimeCapability()) { // Do nothing, capability updated check will handle the dryrun output. } else { // Bail out early, as we only care about the return value for a dryrun. return true; } } capability |= PROCESS_CAPABILITY_CPU_TIME; } } if (cr.hasFlag(Context.BIND_TREAT_LIKE_ACTIVITY)) { if (!dryRun) { Loading Loading @@ -3101,9 +3120,24 @@ public class OomAdjuster { capability &= ~PROCESS_CAPABILITY_BFSL; } if (!updated) { updated = adj < prevRawAdj || procState < prevProcState || schedGroup > prevSchedGroup || (capability != prevCapability && (capability & prevCapability) == prevCapability); if (adj < prevRawAdj || procState < prevProcState || schedGroup > prevSchedGroup) { updated = true; } if (Flags.useCpuTimeCapability()) { if ((capability != prevCapability) && ((capability & prevCapability) == prevCapability)) { updated = true; } } else { // Ignore PROCESS_CAPABILITY_CPU_TIME in capability comparison final int curFiltered = capability & ~PROCESS_CAPABILITY_CPU_TIME; final int prevFiltered = prevCapability & ~PROCESS_CAPABILITY_CPU_TIME; if ((curFiltered != prevFiltered) && ((curFiltered & prevFiltered) == prevFiltered)) { updated = true; } } } if (dryRun) { Loading Loading @@ -3179,6 +3213,8 @@ public class OomAdjuster { // we check the final procstate, and remove it if the procsate is below BFGS. capability |= getBfslCapabilityFromClient(client); capability |= getCpuCapabilityFromClient(client); if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) { // If the other app is cached for any reason, for purposes here // we are going to consider it empty. Loading @@ -3189,10 +3225,14 @@ public class OomAdjuster { if (app.mOptRecord.setShouldNotFreeze(true, dryRun, app.mOptRecord.shouldNotFreezeReason() | client.mOptRecord.shouldNotFreezeReason(), mAdjSeq)) { if (Flags.useCpuTimeCapability()) { // Do nothing, capability updated check will handle the dryrun output. } else { // Bail out early, as we only care about the return value for a dryrun. return true; } } } if (!dryRun) { state.setCurBoundByNonBgRestrictedApp(state.isCurBoundByNonBgRestrictedApp() Loading Loading @@ -3266,12 +3306,27 @@ public class OomAdjuster { capability &= ~PROCESS_CAPABILITY_BFSL; } if (dryRun && (adj < prevRawAdj || procState < prevProcState || schedGroup > prevSchedGroup || (capability != prevCapability && (capability & prevCapability) == prevCapability))) { if (dryRun) { if (adj < prevRawAdj || procState < prevProcState || schedGroup > prevSchedGroup) { return true; } if (Flags.useCpuTimeCapability()) { if ((capability != prevCapability) && ((capability & prevCapability) == prevCapability)) { return true; } } else { // Ignore PROCESS_CAPABILITY_CPU_TIME in capability comparison final int curFiltered = capability & ~PROCESS_CAPABILITY_CPU_TIME; final int prevFiltered = prevCapability & ~PROCESS_CAPABILITY_CPU_TIME; if ((curFiltered != prevFiltered) && ((curFiltered & prevFiltered) == prevFiltered)) { return true; } } } if (adj < prevRawAdj) { schedGroup = setIntermediateAdjLSP(app, adj, prevRawAdj, schedGroup); } Loading Loading @@ -3321,6 +3376,29 @@ public class OomAdjuster { return baseCapabilities | networkCapabilities; } private static int getCpuCapability(ProcessRecord app, long nowUptime) { final UidRecord uidRec = app.getUidRecord(); if (uidRec != null && uidRec.isCurAllowListed()) { // Process has user visible activities. return PROCESS_CAPABILITY_CPU_TIME; } if (UserHandle.isCore(app.uid)) { // Make sure all system components are not frozen. return PROCESS_CAPABILITY_CPU_TIME; } if (app.mState.getCachedHasVisibleActivities()) { // Process has user visible activities. return PROCESS_CAPABILITY_CPU_TIME; } if (app.mServices.hasUndemotedShortForegroundService(nowUptime)) { // It running a short fgs, just give it cpu time. return PROCESS_CAPABILITY_CPU_TIME; } // TODO(b/370817323): Populate this method with all of the reasons to keep a process // unfrozen. return 0; } /** * @return the BFSL capability from a client (of a service binding or provider). */ Loading Loading @@ -3368,6 +3446,15 @@ public class OomAdjuster { return client.mState.getCurCapability() & PROCESS_CAPABILITY_BFSL; } /** * @return the CPU capability from a client (of a service binding or provider). */ private static int getCpuCapabilityFromClient(ProcessRecord client) { // Just grant CPU capability every time // TODO(b/370817323): Populate with reasons to not propagate cpu capability across bindings. return client.mState.getCurCapability() & PROCESS_CAPABILITY_CPU_TIME; } /** * Checks if for the given app and client, there's a cycle that should skip over the client * for now or use partial values to evaluate the effect of the client binding. Loading Loading @@ -3949,6 +4036,39 @@ public class OomAdjuster { mCacheOomRanker.dump(pw); } /** * Return whether or not a process should be frozen. */ boolean getFreezePolicy(ProcessRecord proc) { // Reasons to not freeze: if (Flags.useCpuTimeCapability()) { if ((proc.mState.getCurCapability() & PROCESS_CAPABILITY_CPU_TIME) != 0) { /// App is important enough (see {@link #getCpuCapability}) or bound by something /// important enough to not be frozen. return false; } } else { // The CPU capability handling covers all setShouldNotFreeze paths. Must check // shouldNotFreeze, if the CPU capability is not being used. if (proc.mOptRecord.shouldNotFreeze()) { return false; } } if (proc.mOptRecord.isFreezeExempt()) { return false; } // Reasons to freeze: if (proc.mState.getCurAdj() >= FREEZER_CUTOFF_ADJ) { // Oomscore is in a high enough state, it is safe to freeze. return true; } // Default, do not freeze a process. return false; } @GuardedBy({"mService", "mProcLock"}) void updateAppFreezeStateLSP(ProcessRecord app, @OomAdjReason int oomAdjReason, boolean immediate, int oldOomAdj) { Loading @@ -3963,45 +4083,46 @@ public class OomAdjuster { (state.getCurAdj() >= FREEZER_CUTOFF_ADJ ^ oldOomAdj >= FREEZER_CUTOFF_ADJ) || oldOomAdj == UNKNOWN_ADJ; final boolean shouldNotFreezeChanged = opt.shouldNotFreezeAdjSeq() == mAdjSeq; if ((oomAdjChanged || shouldNotFreezeChanged) final boolean hasCpuCapability = (PROCESS_CAPABILITY_CPU_TIME & app.mState.getCurCapability()) == PROCESS_CAPABILITY_CPU_TIME; final boolean usedToHaveCpuCapability = (PROCESS_CAPABILITY_CPU_TIME & app.mState.getSetCapability()) == PROCESS_CAPABILITY_CPU_TIME; final boolean cpuCapabilityChanged = hasCpuCapability != usedToHaveCpuCapability; if ((oomAdjChanged || shouldNotFreezeChanged || cpuCapabilityChanged) && Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) { Trace.instantForTrack(Trace.TRACE_TAG_ACTIVITY_MANAGER, CachedAppOptimizer.ATRACE_FREEZER_TRACK, "updateAppFreezeStateLSP " + app.processName + " pid: " + app.getPid() + " isFreezeExempt: " + opt.isFreezeExempt() + " isFrozen: " + opt.isFrozen() + " shouldNotFreeze: " + opt.shouldNotFreeze() + " shouldNotFreezeReason: " + opt.shouldNotFreezeReason() + " curAdj: " + state.getCurAdj() + " oldOomAdj: " + oldOomAdj + " immediate: " + immediate); + " immediate: " + immediate + " cpuCapability: " + hasCpuCapability); } } if (app.mOptRecord.isFreezeExempt()) { return; } // if an app is already frozen and shouldNotFreeze becomes true, immediately unfreeze if (opt.isFrozen() && opt.shouldNotFreeze()) { mCachedAppOptimizer.unfreezeAppLSP(app, CachedAppOptimizer.getUnfreezeReasonCodeFromOomAdjReason(oomAdjReason)); return; } // Use current adjustment when freezing, set adjustment when unfreezing. if (state.getCurAdj() >= FREEZER_CUTOFF_ADJ && !opt.isFrozen() && !opt.shouldNotFreeze()) { if (!immediate) { mCachedAppOptimizer.freezeAppAsyncLSP(app); } else { if (getFreezePolicy(app)) { // This process should be frozen. if (immediate && !opt.isFrozen()) { // And it will be frozen immediately. mCachedAppOptimizer.freezeAppAsyncAtEarliestLSP(app); } else if (!opt.isFrozen() || !opt.isPendingFreeze()) { mCachedAppOptimizer.freezeAppAsyncLSP(app); } } else if (state.getSetAdj() < FREEZER_CUTOFF_ADJ) { } else { // This process should not be frozen. if (opt.isFrozen() || opt.isPendingFreeze()) { mCachedAppOptimizer.unfreezeAppLSP(app, CachedAppOptimizer.getUnfreezeReasonCodeFromOomAdjReason(oomAdjReason)); } } } @GuardedBy("mService") void unfreezeTemporarily(ProcessRecord app, @OomAdjReason int reason) { Loading @@ -4023,7 +4144,8 @@ public class OomAdjuster { final int size = processes.size(); for (int i = 0; i < size; i++) { ProcessRecord proc = processes.get(i); mCachedAppOptimizer.unfreezeTemporarily(proc, reason); mCachedAppOptimizer.unfreezeTemporarily(proc, CachedAppOptimizer.getUnfreezeReasonCodeFromOomAdjReason(reason)); } processes.clear(); } Loading
services/core/java/com/android/server/am/OomAdjusterModernImpl.java +3 −2 Original line number Diff line number Diff line Loading @@ -758,8 +758,9 @@ public class OomAdjusterModernImpl extends OomAdjuster { OomAdjusterModernImpl(ActivityManagerService service, ProcessList processList, ActiveUids activeUids, ServiceThread adjusterThread, GlobalState globalState, Injector injector) { super(service, processList, activeUids, adjusterThread, globalState, injector); CachedAppOptimizer cachedAppOptimizer, Injector injector) { super(service, processList, activeUids, adjusterThread, globalState, cachedAppOptimizer, injector); } private final ProcessRecordNodes mProcessRecordProcStateNodes = new ProcessRecordNodes( Loading
services/core/java/com/android/server/am/ProcessServiceRecord.java +8 −2 Original line number Diff line number Diff line Loading @@ -256,18 +256,24 @@ final class ProcessServiceRecord { } // Now we need to look at all short-FGS within the process and see if all of them are // procstate-timed-out or not. return !hasUndemotedShortForegroundService(nowUptime); } boolean hasUndemotedShortForegroundService(long nowUptime) { for (int i = mServices.size() - 1; i >= 0; i--) { final ServiceRecord sr = mServices.valueAt(i); if (!sr.isShortFgs() || !sr.hasShortFgsInfo()) { continue; } if (sr.getShortFgsInfo().getProcStateDemoteTime() >= nowUptime) { return false; // This short fgs has not timed out yet. return true; } } return true; return false; } int getReportedForegroundServiceTypes() { return mRepFgServiceTypes; } Loading