diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index a172018ab2910..e49497e8688c0 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -479,19 +479,33 @@ public final class CachedAppOptimizer { @GuardedBy("mProcLock") void compactAppSome(ProcessRecord app, boolean force) { app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_SOME); - if (DEBUG_COMPACTION) { - Slog.d(TAG_AM, " compactAppSome requested for " + app.processName + " force: " + force); + compactApp(app, force, "some"); + } + + // This method returns true only if requirements are met. Note, that requirements are different + // from throttles applied at the time a compaction is trying to be executed in the sense that + // these are not subject to change dependent on time or memory as throttles usually do. + @GuardedBy("mProcLock") + boolean meetsCompactionRequirements(ProcessRecord proc) { + if (mAm.mInternal.isPendingTopUid(proc.uid)) { + // In case the OOM Adjust has not yet been propagated we see if this is + // pending on becoming top app in which case we should not compact. + if (DEBUG_COMPACTION) { + Slog.d(TAG_AM, "Skip compaction since UID is active for " + proc.processName); + } + return false; } - if (force || !app.mOptRecord.hasPendingCompact()) { - Trace.instantForTrack(Trace.TRACE_TAG_ACTIVITY_MANAGER, ATRACE_COMPACTION_TRACK, - "compactAppSome " + app.processName != null ? app.processName : ""); - app.mOptRecord.setHasPendingCompact(true); - app.mOptRecord.setForceCompact(force); - mPendingCompactionProcesses.add(app); - mCompactionHandler.sendMessage( - mCompactionHandler.obtainMessage( - COMPACT_PROCESS_MSG, app.mState.getSetAdj(), app.mState.getSetProcState())); + + if (proc.mState.hasForegroundActivities()) { + if (DEBUG_COMPACTION) { + Slog.e(TAG_AM, + "Skip compaction as process " + proc.processName + + " has foreground activities"); + } + return false; } + + return true; } @GuardedBy("mProcLock") @@ -508,19 +522,7 @@ public final class CachedAppOptimizer { // Apply OOM adj score throttle for Full App Compaction. if (force || oomAdjEnteredCached) { app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_FULL); - if (!app.mOptRecord.hasPendingCompact()) { - Trace.instantForTrack(Trace.TRACE_TAG_ACTIVITY_MANAGER, ATRACE_COMPACTION_TRACK, - "compactAppFull " + app.processName != null ? app.processName : ""); - app.mOptRecord.setHasPendingCompact(true); - app.mOptRecord.setForceCompact(force); - mPendingCompactionProcesses.add(app); - mCompactionHandler.sendMessage(mCompactionHandler.obtainMessage( - COMPACT_PROCESS_MSG, app.mState.getSetAdj(), app.mState.getSetProcState())); - } else if (DEBUG_COMPACTION) { - Slog.d(TAG_AM, - " compactAppFull Skipped for " + app.processName - + " since it has a pending compact"); - } + compactApp(app, force, "Full"); } else { if (DEBUG_COMPACTION) { Slog.d(TAG_AM, "Skipping full compaction for " + app.processName @@ -533,15 +535,34 @@ public final class CachedAppOptimizer { @GuardedBy("mProcLock") void compactAppPersistent(ProcessRecord app) { app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_PERSISTENT); - if (!app.mOptRecord.hasPendingCompact()) { + compactApp(app, false, "Persistent"); + } + + @GuardedBy("mProcLock") + boolean compactApp(ProcessRecord app, boolean force, String compactRequestType) { + if (!app.mOptRecord.hasPendingCompact() && meetsCompactionRequirements(app)) { + final String processName = (app.processName != null ? app.processName : ""); + if (DEBUG_COMPACTION) { + Slog.d(TAG_AM, "compactApp " + compactRequestType + " " + processName); + } Trace.instantForTrack(Trace.TRACE_TAG_ACTIVITY_MANAGER, ATRACE_COMPACTION_TRACK, - "compactAppPersistent " + app.processName != null ? app.processName : ""); + "compactApp " + compactRequestType + " " + processName); app.mOptRecord.setHasPendingCompact(true); + app.mOptRecord.setForceCompact(force); mPendingCompactionProcesses.add(app); - mCompactionHandler.sendMessage( - mCompactionHandler.obtainMessage( + mCompactionHandler.sendMessage(mCompactionHandler.obtainMessage( COMPACT_PROCESS_MSG, app.mState.getCurAdj(), app.mState.getSetProcState())); + return true; } + + if (DEBUG_COMPACTION) { + Slog.d(TAG_AM, + " compactApp Skipped for " + app.processName + + " pendingCompact= " + app.mOptRecord.hasPendingCompact() + + " meetsCompactionRequirements=" + meetsCompactionRequirements(app) + + ". Requested compact: " + app.mOptRecord.getReqCompactAction()); + } + return false; } @GuardedBy("mProcLock") @@ -553,15 +574,7 @@ public final class CachedAppOptimizer { @GuardedBy("mProcLock") void compactAppBfgs(ProcessRecord app) { app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_BFGS); - if (!app.mOptRecord.hasPendingCompact()) { - Trace.instantForTrack(Trace.TRACE_TAG_ACTIVITY_MANAGER, ATRACE_COMPACTION_TRACK, - "compactAppBfgs " + app.processName != null ? app.processName : ""); - app.mOptRecord.setHasPendingCompact(true); - mPendingCompactionProcesses.add(app); - mCompactionHandler.sendMessage( - mCompactionHandler.obtainMessage( - COMPACT_PROCESS_MSG, app.mState.getCurAdj(), app.mState.getSetProcState())); - } + compactApp(app, false, " Bfgs"); } @GuardedBy("mProcLock") @@ -572,6 +585,9 @@ public final class CachedAppOptimizer { void compactAllSystem() { if (useCompaction()) { + if (DEBUG_COMPACTION) { + Slog.d(TAG_AM, "compactAllSystem"); + } Trace.instantForTrack( Trace.TRACE_TAG_ACTIVITY_MANAGER, ATRACE_COMPACTION_TRACK, "compactAllSystem"); mCompactionHandler.sendMessage(mCompactionHandler.obtainMessage( @@ -1175,13 +1191,13 @@ public final class CachedAppOptimizer { cancelCompaction(); } - // Perform a minor compaction when a perceptible app becomes the prev/home app - // Perform a major compaction when any app enters cached if (oldAdj <= ProcessList.PERCEPTIBLE_APP_ADJ && (newAdj == ProcessList.PREVIOUS_APP_ADJ || newAdj == ProcessList.HOME_APP_ADJ)) { + // Perform a minor compaction when a perceptible app becomes the prev/home app compactAppSome(app, false); } else if (newAdj >= ProcessList.CACHED_APP_MIN_ADJ && newAdj <= ProcessList.CACHED_APP_MAX_ADJ) { + // Perform a major compaction when any app enters cached compactAppFull(app, false); } } @@ -1241,12 +1257,6 @@ public final class CachedAppOptimizer { private boolean shouldOomAdjThrottleCompaction(ProcessRecord proc, int action) { final String name = proc.processName; - if (mAm.mInternal.isPendingTopUid(proc.uid)) { - // In case the OOM Adjust has not yet been propagated we see if this is - // pending on becoming top app in which case we should not compact. - Slog.e(TAG_AM, "Skip compaction since UID is active for " + name); - return true; - } // don't compact if the process has returned to perceptible // and this is only a cached/home/prev compaction diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index 4d10574149ffd..3ae8b980a311a 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -2556,20 +2556,21 @@ public class OomAdjuster { // reminder: here, setAdj is previous state, curAdj is upcoming state if (state.getCurAdj() != state.getSetAdj()) { mCachedAppOptimizer.onOomAdjustChanged(state.getSetAdj(), state.getCurAdj(), app); - } else if (mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE - && state.getSetAdj() < ProcessList.FOREGROUND_APP_ADJ - && !state.isRunningRemoteAnimation() - // Because these can fire independent of oom_adj/procstate changes, we need - // to throttle the actual dispatch of these requests in addition to the - // processing of the requests. As a result, there is throttling both here - // and in CachedAppOptimizer. - && mCachedAppOptimizer.shouldCompactPersistent(app, now)) { - mCachedAppOptimizer.compactAppPersistent(app); - } else if (mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE - && state.getCurProcState() - == ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE - && mCachedAppOptimizer.shouldCompactBFGS(app, now)) { - mCachedAppOptimizer.compactAppBfgs(app); + } else if (mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE) { + // See if we can compact persistent and bfgs services now that screen is off + if (state.getSetAdj() < ProcessList.FOREGROUND_APP_ADJ + && !state.isRunningRemoteAnimation() + // Because these can fire independent of oom_adj/procstate changes, we need + // to throttle the actual dispatch of these requests in addition to the + // processing of the requests. As a result, there is throttling both here + // and in CachedAppOptimizer. + && mCachedAppOptimizer.shouldCompactPersistent(app, now)) { + mCachedAppOptimizer.compactAppPersistent(app); + } else if (state.getCurProcState() + == ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE + && mCachedAppOptimizer.shouldCompactBFGS(app, now)) { + mCachedAppOptimizer.compactAppBfgs(app); + } } }