diff options
| author | 2024-11-06 21:09:49 +0000 | |
|---|---|---|
| committer | 2024-11-07 11:46:00 -0800 | |
| commit | 26a8abbd0a3527c009ab437c7e6fd9b7932d0118 (patch) | |
| tree | 44a27b51f0c20d32a9031f2a7f1118df9c5d723f | |
| parent | 6349ad595039ec4cb2fefa367031d72ee7da5130 (diff) | |
Revert^2 "OomAdjuster Freeze Handling with CPU capability"
This reverts commit 58093e8be25c5bf023998d44d9de5fcbdc38a0dc.
Reason for revert: Re-land CL with test fix
Change-Id: I583cc22d890f202e644b84653bfbefb4ba4f444e
8 files changed, 271 insertions, 65 deletions
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index b447897733e1..1b707f79ab81 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -1017,6 +1017,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}. * * Don't expose it as TestApi -- we may add new capabilities any time, which could @@ -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 @@ -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 */ @@ -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' : '-'); } /** diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index 416c11090515..da5b1fd1c079 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -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"; diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index c0676623a1e9..b84bf6b90711 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -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; @@ -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; @@ -469,7 +471,6 @@ public class OomAdjuster { } Process.setThreadPriority(tid, priority); } - } // TODO(b/346822474): hook up global state usage. @@ -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; @@ -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); @@ -2597,6 +2599,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) { @@ -2739,8 +2742,12 @@ public class OomAdjuster { if (app.mOptRecord.setShouldNotFreeze(true, dryRun, app.mOptRecord.shouldNotFreezeReason() | client.mOptRecord.shouldNotFreezeReason(), mAdjSeq)) { - // Bail out early, as we only care about the return value for a dryrun. - return true; + 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; + } } } @@ -2751,6 +2758,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(); @@ -2809,9 +2818,14 @@ public class OomAdjuster { app.mOptRecord.shouldNotFreezeReason() | ProcessCachedOptimizerRecord .SHOULD_NOT_FREEZE_REASON_BINDER_ALLOW_OOM_MANAGEMENT, mAdjSeq)) { - // Bail out early, as we only care about the return value for a dryrun. - return true; + 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. @@ -3053,9 +3067,14 @@ public class OomAdjuster { app.mOptRecord.shouldNotFreezeReason() | ProcessCachedOptimizerRecord .SHOULD_NOT_FREEZE_REASON_BIND_WAIVE_PRIORITY, mAdjSeq)) { - // Bail out early, as we only care about the return value for a dryrun. - return true; + 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)) { @@ -3108,9 +3127,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) { @@ -3186,6 +3220,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. @@ -3196,8 +3232,12 @@ public class OomAdjuster { if (app.mOptRecord.setShouldNotFreeze(true, dryRun, app.mOptRecord.shouldNotFreezeReason() | client.mOptRecord.shouldNotFreezeReason(), mAdjSeq)) { - // Bail out early, as we only care about the return value for a dryrun. - return true; + 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; + } } } @@ -3273,10 +3313,25 @@ public class OomAdjuster { capability &= ~PROCESS_CAPABILITY_BFSL; } - if (dryRun && (adj < prevRawAdj || procState < prevProcState || schedGroup > prevSchedGroup - || (capability != prevCapability - && (capability & prevCapability) == prevCapability))) { - return true; + 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) { @@ -3328,6 +3383,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). */ @@ -3376,6 +3454,15 @@ public class OomAdjuster { } /** + * @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. * @param app @@ -3955,6 +4042,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) { @@ -3969,43 +4089,44 @@ 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 { + // This process should not be frozen. + if (opt.isFrozen() || opt.isPendingFreeze()) { + mCachedAppOptimizer.unfreezeAppLSP(app, + CachedAppOptimizer.getUnfreezeReasonCodeFromOomAdjReason(oomAdjReason)); } - } else if (state.getSetAdj() < FREEZER_CUTOFF_ADJ) { - mCachedAppOptimizer.unfreezeAppLSP(app, - CachedAppOptimizer.getUnfreezeReasonCodeFromOomAdjReason(oomAdjReason)); } } @@ -4029,7 +4150,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(); } diff --git a/services/core/java/com/android/server/am/OomAdjusterModernImpl.java b/services/core/java/com/android/server/am/OomAdjusterModernImpl.java index 8b660559f550..1b7e8f0bd244 100644 --- a/services/core/java/com/android/server/am/OomAdjusterModernImpl.java +++ b/services/core/java/com/android/server/am/OomAdjusterModernImpl.java @@ -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( diff --git a/services/core/java/com/android/server/am/ProcessServiceRecord.java b/services/core/java/com/android/server/am/ProcessServiceRecord.java index 5cb8b954a2ba..364497491785 100644 --- a/services/core/java/com/android/server/am/ProcessServiceRecord.java +++ b/services/core/java/com/android/server/am/ProcessServiceRecord.java @@ -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; } diff --git a/services/core/java/com/android/server/am/ProcessStateController.java b/services/core/java/com/android/server/am/ProcessStateController.java index 01468c640f6c..57899228e6ad 100644 --- a/services/core/java/com/android/server/am/ProcessStateController.java +++ b/services/core/java/com/android/server/am/ProcessStateController.java @@ -29,6 +29,7 @@ import android.util.Slog; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; import com.android.server.ServiceThread; /** @@ -44,13 +45,14 @@ public class ProcessStateController { private final GlobalState mGlobalState = new GlobalState(); private ProcessStateController(ActivityManagerService ams, ProcessList processList, - ActiveUids activeUids, ServiceThread handlerThread, OomAdjuster.Injector oomAdjInjector, + ActiveUids activeUids, ServiceThread handlerThread, + CachedAppOptimizer cachedAppOptimizer, OomAdjuster.Injector oomAdjInjector, boolean useOomAdjusterModernImpl) { mOomAdjuster = useOomAdjusterModernImpl ? new OomAdjusterModernImpl(ams, processList, activeUids, handlerThread, - mGlobalState, oomAdjInjector) + mGlobalState, cachedAppOptimizer, oomAdjInjector) : new OomAdjuster(ams, processList, activeUids, handlerThread, mGlobalState, - oomAdjInjector); + cachedAppOptimizer, oomAdjInjector); } /** @@ -594,6 +596,7 @@ public class ProcessStateController { private final ActiveUids mActiveUids; private ServiceThread mHandlerThread = null; + private CachedAppOptimizer mCachedAppOptimizer = null; private OomAdjuster.Injector mOomAdjInjector = null; private boolean mUseOomAdjusterModernImpl = false; @@ -610,24 +613,38 @@ public class ProcessStateController { if (mHandlerThread == null) { mHandlerThread = OomAdjuster.createAdjusterThread(); } + if (mCachedAppOptimizer == null) { + mCachedAppOptimizer = new CachedAppOptimizer(mAms); + } if (mOomAdjInjector == null) { mOomAdjInjector = new OomAdjuster.Injector(); } return new ProcessStateController(mAms, mProcessList, mActiveUids, mHandlerThread, - mOomAdjInjector, mUseOomAdjusterModernImpl); + mCachedAppOptimizer, mOomAdjInjector, mUseOomAdjusterModernImpl); } /** * For Testing Purposes. Set what thread OomAdjuster will offload tasks on to. */ + @VisibleForTesting public Builder setHandlerThread(ServiceThread handlerThread) { mHandlerThread = handlerThread; return this; } /** + * For Testing Purposes. Set the CachedAppOptimzer used by OomAdjuster. + */ + @VisibleForTesting + public Builder setCachedAppOptimizer(CachedAppOptimizer cachedAppOptimizer) { + mCachedAppOptimizer = cachedAppOptimizer; + return this; + } + + /** * For Testing Purposes. Set an injector for OomAdjuster. */ + @VisibleForTesting public Builder setOomAdjusterInjector(OomAdjuster.Injector injector) { mOomAdjInjector = injector; return this; diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig index 5d5b35b8c4fb..3f0dd7f81092 100644 --- a/services/core/java/com/android/server/am/flags.aconfig +++ b/services/core/java/com/android/server/am/flags.aconfig @@ -261,3 +261,10 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "use_cpu_time_capability" + namespace: "backstage_power" + description: "Use PROCESS_CAPABILITY_CPU_TIME to control unfreeze state." + bug: "370817323" +} diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java index 4a1315583ad4..f82a86092064 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java @@ -109,6 +109,7 @@ import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; import android.util.ArrayMap; import android.util.SparseArray; +import android.util.SparseBooleanArray; import android.util.SparseIntArray; import com.android.server.LocalServices; @@ -175,6 +176,7 @@ public class MockingOomAdjusterTests { private ActiveUids mActiveUids; private PackageManagerInternal mPackageManagerInternal; private ActivityManagerService mService; + private TestCachedAppOptimizer mTestCachedAppOptimizer; private OomAdjusterInjector mInjector = new OomAdjusterInjector(); private int mUiTierSize; @@ -242,9 +244,11 @@ public class MockingOomAdjusterTests { doNothing().when(pr).enqueueProcessChangeItemLocked(anyInt(), anyInt(), anyInt(), anyBoolean()); mActiveUids = new ActiveUids(mService, false); + mTestCachedAppOptimizer = new TestCachedAppOptimizer(mService); mProcessStateController = new ProcessStateController.Builder(mService, mService.mProcessList, mActiveUids) .useModernOomAdjuster(mService.mConstants.ENABLE_NEW_OOMADJ) + .setCachedAppOptimizer(mTestCachedAppOptimizer) .setOomAdjusterInjector(mInjector) .build(); mService.mProcessStateController = mProcessStateController; @@ -3110,13 +3114,13 @@ public class MockingOomAdjusterTests { mProcessStateController.setUidTempAllowlistStateLSP(MOCKAPP_UID, true); assertEquals(true, app.getUidRecord().isSetAllowListed()); - assertEquals(true, app.mOptRecord.shouldNotFreeze()); - assertEquals(true, app2.mOptRecord.shouldNotFreeze()); + assertFreezeState(app, false); + assertFreezeState(app2, false); mProcessStateController.setUidTempAllowlistStateLSP(MOCKAPP_UID, false); assertEquals(false, app.getUidRecord().isSetAllowListed()); - assertEquals(false, app.mOptRecord.shouldNotFreeze()); - assertEquals(false, app2.mOptRecord.shouldNotFreeze()); + assertFreezeState(app, true); + assertFreezeState(app2, true); } @SuppressWarnings("GuardedBy") @@ -3138,25 +3142,25 @@ public class MockingOomAdjusterTests { assertEquals(true, app.getUidRecord().isSetAllowListed()); assertEquals(true, app2.getUidRecord().isSetAllowListed()); - assertEquals(true, app.mOptRecord.shouldNotFreeze()); - assertEquals(true, app2.mOptRecord.shouldNotFreeze()); - assertEquals(true, app3.mOptRecord.shouldNotFreeze()); + assertFreezeState(app, false); + assertFreezeState(app2, false); + assertFreezeState(app3, false); // Remove app1 from allowlist. mProcessStateController.setUidTempAllowlistStateLSP(MOCKAPP_UID, false); assertEquals(false, app.getUidRecord().isSetAllowListed()); assertEquals(true, app2.getUidRecord().isSetAllowListed()); - assertEquals(false, app.mOptRecord.shouldNotFreeze()); - assertEquals(true, app2.mOptRecord.shouldNotFreeze()); - assertEquals(true, app3.mOptRecord.shouldNotFreeze()); + assertFreezeState(app, true); + assertFreezeState(app2, false); + assertFreezeState(app3, false); // Now remove app2 from allowlist. mProcessStateController.setUidTempAllowlistStateLSP(MOCKAPP2_UID, false); assertEquals(false, app.getUidRecord().isSetAllowListed()); assertEquals(false, app2.getUidRecord().isSetAllowListed()); - assertEquals(false, app.mOptRecord.shouldNotFreeze()); - assertEquals(false, app2.mOptRecord.shouldNotFreeze()); - assertEquals(false, app3.mOptRecord.shouldNotFreeze()); + assertFreezeState(app, true); + assertFreezeState(app2, true); + assertFreezeState(app3, true); } @SuppressWarnings("GuardedBy") @@ -3370,6 +3374,14 @@ public class MockingOomAdjusterTests { assertEquals(expectedCached, state.isCached()); } + @SuppressWarnings("GuardedBy") + private void assertFreezeState(ProcessRecord app, boolean expectedFreezeState) { + boolean actualFreezeState = mTestCachedAppOptimizer.mLastSetFreezeState.get(app.getPid(), + false); + assertEquals("Unexcepted freeze state for " + app.processName, expectedFreezeState, + actualFreezeState); + } + private class ProcessRecordBuilder { @SuppressWarnings("UnusedVariable") int mPid; @@ -3513,6 +3525,39 @@ public class MockingOomAdjusterTests { return app; } } + private static final class TestProcessDependencies + implements CachedAppOptimizer.ProcessDependencies { + @Override + public long[] getRss(int pid) { + return new long[]{/*totalRSS*/ 0, /*fileRSS*/ 0, /*anonRSS*/ 0, /*swap*/ 0}; + } + + @Override + public void performCompaction(CachedAppOptimizer.CompactProfile action, int pid) {} + } + + private static class TestCachedAppOptimizer extends CachedAppOptimizer { + private SparseBooleanArray mLastSetFreezeState = new SparseBooleanArray(); + + TestCachedAppOptimizer(ActivityManagerService ams) { + super(ams, null, new TestProcessDependencies()); + } + + @Override + public boolean useFreezer() { + return true; + } + + @Override + public void freezeAppAsyncLSP(ProcessRecord app) { + mLastSetFreezeState.put(app.getPid(), true); + } + + @Override + public void unfreezeAppLSP(ProcessRecord app, @UnfreezeReason int reason) { + mLastSetFreezeState.put(app.getPid(), false); + } + } static class OomAdjusterInjector extends OomAdjuster.Injector { // Jump ahead in time by this offset amount. @@ -3524,7 +3569,6 @@ public class MockingOomAdjusterTests { mLastSetOomAdj.clear(); } - void jumpUptimeAheadTo(long uptimeMillis) { final long jumpMs = uptimeMillis - getUptimeMillis(); if (jumpMs <= 0) return; |