diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index 4629d0b77799f..1ddd899505b0d 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -881,7 +881,8 @@ public final class CachedAppOptimizer { @GuardedBy({"mAm", "mProcLock"}) void freezeAppAsyncLSP(ProcessRecord app) { - if (mFreezeHandler.hasMessages(SET_FROZEN_PROCESS_MSG, app)) { + final ProcessCachedOptimizerRecord opt = app.mOptRecord; + if (opt.isPendingFreeze()) { // Skip redundant DO_FREEZE message return; } @@ -890,21 +891,27 @@ public final class CachedAppOptimizer { mFreezeHandler.obtainMessage( SET_FROZEN_PROCESS_MSG, DO_FREEZE, 0, app), mFreezerDebounceTimeout); + opt.setPendingFreeze(true); + if (DEBUG_FREEZER) { + Slog.d(TAG_AM, "Async freezing " + app.getPid() + " " + app.processName); + } } @GuardedBy({"mAm", "mProcLock"}) void unfreezeAppLSP(ProcessRecord app) { - mFreezeHandler.removeMessages(SET_FROZEN_PROCESS_MSG, app); - final int pid = app.getPid(); final ProcessCachedOptimizerRecord opt = app.mOptRecord; + if (opt.isPendingFreeze()) { + // Remove pending DO_FREEZE message + mFreezeHandler.removeMessages(SET_FROZEN_PROCESS_MSG, app); + opt.setPendingFreeze(false); + if (DEBUG_FREEZER) { + Slog.d(TAG_AM, "Cancel freezing " + pid + " " + app.processName); + } + } + opt.setFreezerOverride(false); if (!opt.isFrozen()) { - if (DEBUG_FREEZER) { - Slog.d(TAG_AM, - "Skipping unfreeze for process " + pid + " " - + app.processName + " (not frozen)"); - } return; } @@ -983,7 +990,12 @@ public final class CachedAppOptimizer { @GuardedBy({"mAm", "mProcLock"}) void unscheduleFreezeAppLSP(ProcessRecord app) { if (mUseFreezer) { - mFreezeHandler.removeMessages(SET_FROZEN_PROCESS_MSG, app); + final ProcessCachedOptimizerRecord opt = app.mOptRecord; + if (opt.isPendingFreeze()) { + // Remove pending DO_FREEZE message + mFreezeHandler.removeMessages(SET_FROZEN_PROCESS_MSG, app); + opt.setPendingFreeze(false); + } } } @@ -1278,6 +1290,8 @@ public final class CachedAppOptimizer { final boolean frozen; final ProcessCachedOptimizerRecord opt = proc.mOptRecord; + opt.setPendingFreeze(false); + try { // pre-check for locks to avoid unnecessary freeze/unfreeze operations if (Process.hasFileLocks(pid)) { @@ -1352,7 +1366,6 @@ public final class CachedAppOptimizer { return; } - if (DEBUG_FREEZER) { Slog.d(TAG_AM, "froze " + pid + " " + name); } diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index 4ad99095a8c68..2e2a29751f79d 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -3112,6 +3112,7 @@ public class OomAdjuster { // if an app is already frozen and shouldNotFreeze becomes true, immediately unfreeze if (opt.isFrozen() && opt.shouldNotFreeze()) { mCachedAppOptimizer.unfreezeAppLSP(app); + return; } final ProcessStateRecord state = app.mState; @@ -3119,7 +3120,7 @@ public class OomAdjuster { if (state.getCurAdj() >= ProcessList.CACHED_APP_MIN_ADJ && !opt.isFrozen() && !opt.shouldNotFreeze()) { mCachedAppOptimizer.freezeAppAsyncLSP(app); - } else if (state.getSetAdj() < ProcessList.CACHED_APP_MIN_ADJ && opt.isFrozen()) { + } else if (state.getSetAdj() < ProcessList.CACHED_APP_MIN_ADJ) { mCachedAppOptimizer.unfreezeAppLSP(app); } } diff --git a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java index 408c7cb750dbe..a86ba016eeff7 100644 --- a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java +++ b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java @@ -86,6 +86,12 @@ final class ProcessCachedOptimizerRecord { @GuardedBy("mProcLock") private boolean mFreezeExempt; + /** + * This process has been scheduled for freezing + */ + @GuardedBy("mProcLock") + private boolean mPendingFreeze; + @GuardedBy("mProcLock") long getLastCompactTime() { return mLastCompactTime; @@ -171,6 +177,16 @@ final class ProcessCachedOptimizerRecord { return mFreezeExempt; } + @GuardedBy("mProcLock") + void setPendingFreeze(boolean freeze) { + mPendingFreeze = freeze; + } + + @GuardedBy("mProcLock") + boolean isPendingFreeze() { + return mPendingFreeze; + } + @GuardedBy("mProcLock") void setFreezeExempt(boolean exempt) { mFreezeExempt = exempt; @@ -190,6 +206,7 @@ final class ProcessCachedOptimizerRecord { pw.print(prefix); pw.print("lastCompactTime="); pw.print(mLastCompactTime); pw.print(" lastCompactAction="); pw.println(mLastCompactAction); pw.print(prefix); pw.print("isFreezeExempt="); pw.print(mFreezeExempt); + pw.print(" isPendingFreeze="); pw.print(mPendingFreeze); pw.print(" " + IS_FROZEN + "="); pw.println(mFrozen); } }