Loading services/core/java/com/android/server/am/ActivityManagerShellCommand.java +103 −14 Original line number Original line Diff line number Diff line Loading @@ -247,6 +247,10 @@ final class ActivityManagerShellCommand extends ShellCommand { return runSendBroadcast(pw); return runSendBroadcast(pw); case "compact": case "compact": return runCompact(pw); return runCompact(pw); case "freeze": return runFreeze(pw); case "unfreeze": return runUnfreeze(pw); case "instrument": case "instrument": getOutPrintWriter().println("Error: must be invoked through 'am instrument'."); getOutPrintWriter().println("Error: must be invoked through 'am instrument'."); return -1; return -1; Loading Loading @@ -1074,20 +1078,10 @@ final class ActivityManagerShellCommand extends ShellCommand { boolean isFullCompact = op.equals("full"); boolean isFullCompact = op.equals("full"); boolean isSomeCompact = op.equals("some"); boolean isSomeCompact = op.equals("some"); if (isFullCompact || isSomeCompact) { if (isFullCompact || isSomeCompact) { String processName = getNextArgRequired(); app = getProcessFromShell(); synchronized (mInternal.mProcLock) { if (app == null) { // Default to current user getErrPrintWriter().println("Error: could not find process"); int userId = mInterface.getCurrentUserId(); return -1; String userOpt = getNextOption(); if (userOpt != null && "--user".equals(userOpt)) { int inputUserId = UserHandle.parseUserArg(getNextArgRequired()); if (inputUserId != UserHandle.USER_CURRENT) { userId = inputUserId; } } final int uid = mInternal.getPackageManagerInternal().getPackageUid(processName, 0, userId); app = mInternal.getProcessRecordLocked(processName, uid); } } pw.println("Process record found pid: " + app.mPid); pw.println("Process record found pid: " + app.mPid); if (isFullCompact) { if (isFullCompact) { Loading Loading @@ -1143,6 +1137,93 @@ final class ActivityManagerShellCommand extends ShellCommand { return 0; return 0; } } @NeverCompile int runFreeze(PrintWriter pw) throws RemoteException { String freezerOpt = getNextOption(); boolean isSticky = false; if (freezerOpt != null) { isSticky = freezerOpt.equals("--sticky"); } ProcessRecord app = getProcessFromShell(); if (app == null) { getErrPrintWriter().println("Error: could not find process"); return -1; } pw.println("Freezing pid: " + app.mPid + " sticky=" + isSticky); synchronized (mInternal) { synchronized (mInternal.mProcLock) { app.mOptRecord.setFreezeSticky(isSticky); mInternal.mOomAdjuster.mCachedAppOptimizer.freezeAppAsyncInternalLSP(app, 0, true); } } return 0; } @NeverCompile int runUnfreeze(PrintWriter pw) throws RemoteException { String freezerOpt = getNextOption(); boolean isSticky = false; if (freezerOpt != null) { isSticky = freezerOpt.equals("--sticky"); } ProcessRecord app = getProcessFromShell(); if (app == null) { getErrPrintWriter().println("Error: could not find process"); return -1; } pw.println("Unfreezing pid: " + app.mPid); synchronized (mInternal) { synchronized (mInternal.mProcLock) { synchronized (mInternal.mOomAdjuster.mCachedAppOptimizer.mFreezerLock) { app.mOptRecord.setFreezeSticky(isSticky); mInternal.mOomAdjuster.mCachedAppOptimizer.unfreezeAppInternalLSP(app, 0, false); } } } return 0; } /** * Parses from the shell the process name and user id if provided and provides the corresponding * {@link ProcessRecord)} If no user is provided, it will fallback to current user. * Example usage: {@code <processname> --user current} or {@code <processname>} * @return process record of process, null if none found. * @throws RemoteException */ @NeverCompile ProcessRecord getProcessFromShell() throws RemoteException { ProcessRecord app; String processName = getNextArgRequired(); synchronized (mInternal.mProcLock) { // Default to current user int userId = getUserIdFromShellOrFallback(); final int uid = mInternal.getPackageManagerInternal().getPackageUid(processName, 0, userId); app = mInternal.getProcessRecordLocked(processName, uid); } return app; } /** * @return User id from command line provided in the form of * {@code --user <userid|current|all>} and if the argument is not found it will fallback * to current user. * @throws RemoteException */ @NeverCompile int getUserIdFromShellOrFallback() throws RemoteException { int userId = mInterface.getCurrentUserId(); String userOpt = getNextOption(); if (userOpt != null && "--user".equals(userOpt)) { int inputUserId = UserHandle.parseUserArg(getNextArgRequired()); if (inputUserId != UserHandle.USER_CURRENT) { userId = inputUserId; } } return userId; } int runDumpHeap(PrintWriter pw) throws RemoteException { int runDumpHeap(PrintWriter pw) throws RemoteException { final PrintWriter err = getErrPrintWriter(); final PrintWriter err = getErrPrintWriter(); boolean managed = true; boolean managed = true; Loading Loading @@ -4061,6 +4142,14 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println(" Perform a native compaction for process with <pid>."); pw.println(" Perform a native compaction for process with <pid>."); pw.println(" some: execute file compaction."); pw.println(" some: execute file compaction."); pw.println(" full: execute anon + file compaction."); pw.println(" full: execute anon + file compaction."); pw.println(" freeze [--sticky] <processname> [--user <USER_ID>]"); pw.println(" Freeze a process."); pw.println(" --sticky: persists the frozen state for the process lifetime or"); pw.println(" until an unfreeze is triggered via shell"); pw.println(" unfreeze [--sticky] <processname> [--user <USER_ID>]"); pw.println(" Unfreeze a process."); pw.println(" --sticky: persists the unfrozen state for the process lifetime or"); pw.println(" until a freeze is triggered via shell"); pw.println(" instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]"); pw.println(" instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]"); pw.println(" [--user <USER_ID> | current]"); pw.println(" [--user <USER_ID> | current]"); pw.println(" [--no-hidden-api-checks [--no-test-api-access]]"); pw.println(" [--no-hidden-api-checks [--no-test-api-access]]"); Loading services/core/java/com/android/server/am/CachedAppOptimizer.java +32 −17 Original line number Original line Diff line number Diff line Loading @@ -342,7 +342,7 @@ public final class CachedAppOptimizer { private final ActivityManagerGlobalLock mProcLock; private final ActivityManagerGlobalLock mProcLock; private final Object mFreezerLock = new Object(); public final Object mFreezerLock = new Object(); private final OnPropertiesChangedListener mOnFlagsChangedListener = private final OnPropertiesChangedListener mOnFlagsChangedListener = new OnPropertiesChangedListener() { new OnPropertiesChangedListener() { Loading Loading @@ -763,8 +763,9 @@ public final class CachedAppOptimizer { pw.println(" Apps frozen: " + size); pw.println(" Apps frozen: " + size); for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) { ProcessRecord app = mFrozenProcesses.valueAt(i); ProcessRecord app = mFrozenProcesses.valueAt(i); pw.println(" " + app.mOptRecord.getFreezeUnfreezeTime() pw.println(" " + app.mOptRecord.getFreezeUnfreezeTime() + ": " + app.getPid() + ": " + app.getPid() + " " + app.processName); + " " + app.processName + (app.mOptRecord.isFreezeSticky() ? " (sticky)" : "")); } } if (!mPendingCompactionProcesses.isEmpty()) { if (!mPendingCompactionProcesses.isEmpty()) { Loading Loading @@ -1283,12 +1284,26 @@ public final class CachedAppOptimizer { @GuardedBy({"mAm", "mProcLock"}) @GuardedBy({"mAm", "mProcLock"}) void freezeAppAsyncLSP(ProcessRecord app) { void freezeAppAsyncLSP(ProcessRecord app) { freezeAppAsyncInternalLSP(app, mFreezerDebounceTimeout, false); } @GuardedBy({"mAm", "mProcLock"}) void freezeAppAsyncInternalLSP(ProcessRecord app, long delayMillis, boolean force) { final ProcessCachedOptimizerRecord opt = app.mOptRecord; final ProcessCachedOptimizerRecord opt = app.mOptRecord; if (opt.isPendingFreeze()) { if (opt.isPendingFreeze()) { // Skip redundant DO_FREEZE message // Skip redundant DO_FREEZE message return; return; } } if (opt.isFreezeSticky() && !force) { if (DEBUG_FREEZER) { Slog.d(TAG_AM, "Skip freezing because unfrozen state is sticky pid=" + app.getPid() + " " + app.processName); } return; } if (mAm.mConstants.USE_MODERN_TRIM if (mAm.mConstants.USE_MODERN_TRIM && app.mState.getSetAdj() >= ProcessList.CACHED_APP_MIN_ADJ) { && app.mState.getSetAdj() >= ProcessList.CACHED_APP_MIN_ADJ) { final IApplicationThread thread = app.getThread(); final IApplicationThread thread = app.getThread(); Loading @@ -1301,9 +1316,8 @@ public final class CachedAppOptimizer { } } } } mFreezeHandler.sendMessageDelayed( mFreezeHandler.sendMessageDelayed( mFreezeHandler.obtainMessage( mFreezeHandler.obtainMessage(SET_FROZEN_PROCESS_MSG, DO_FREEZE, 0, app), SET_FROZEN_PROCESS_MSG, DO_FREEZE, 0, app), delayMillis); mFreezerDebounceTimeout); opt.setPendingFreeze(true); opt.setPendingFreeze(true); if (DEBUG_FREEZER) { if (DEBUG_FREEZER) { Slog.d(TAG_AM, "Async freezing " + app.getPid() + " " + app.processName); Slog.d(TAG_AM, "Async freezing " + app.getPid() + " " + app.processName); Loading @@ -1311,9 +1325,19 @@ public final class CachedAppOptimizer { } } @GuardedBy({"mAm", "mProcLock", "mFreezerLock"}) @GuardedBy({"mAm", "mProcLock", "mFreezerLock"}) void unfreezeAppInternalLSP(ProcessRecord app, @UnfreezeReason int reason) { void unfreezeAppInternalLSP(ProcessRecord app, @UnfreezeReason int reason, boolean force) { final int pid = app.getPid(); final int pid = app.getPid(); final ProcessCachedOptimizerRecord opt = app.mOptRecord; final ProcessCachedOptimizerRecord opt = app.mOptRecord; boolean sticky = opt.isFreezeSticky(); if (sticky && !force) { // Sticky freezes will not change their state unless forced out of it. if (DEBUG_FREEZER) { Slog.d(TAG_AM, "Skip unfreezing because frozen state is sticky pid=" + pid + " " + app.processName); } return; } if (opt.isPendingFreeze()) { if (opt.isPendingFreeze()) { // Remove pending DO_FREEZE message // Remove pending DO_FREEZE message mFreezeHandler.removeMessages(SET_FROZEN_PROCESS_MSG, app); mFreezeHandler.removeMessages(SET_FROZEN_PROCESS_MSG, app); Loading Loading @@ -1406,7 +1430,7 @@ public final class CachedAppOptimizer { @GuardedBy({"mAm", "mProcLock"}) @GuardedBy({"mAm", "mProcLock"}) void unfreezeAppLSP(ProcessRecord app, @UnfreezeReason int reason) { void unfreezeAppLSP(ProcessRecord app, @UnfreezeReason int reason) { synchronized (mFreezerLock) { synchronized (mFreezerLock) { unfreezeAppInternalLSP(app, reason); unfreezeAppInternalLSP(app, reason, false); } } } } Loading Loading @@ -2080,15 +2104,6 @@ public final class CachedAppOptimizer { synchronized (mProcLock) { synchronized (mProcLock) { pid = proc.getPid(); pid = proc.getPid(); if (proc.mState.getCurAdj() < ProcessList.CACHED_APP_MIN_ADJ || opt.shouldNotFreeze()) { if (DEBUG_FREEZER) { Slog.d(TAG_AM, "Skipping freeze for process " + pid + " " + name + " curAdj = " + proc.mState.getCurAdj() + ", shouldNotFreeze = " + opt.shouldNotFreeze()); } return; } if (mFreezerOverride) { if (mFreezerOverride) { opt.setFreezerOverride(true); opt.setFreezerOverride(true); Loading services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java +18 −0 Original line number Original line Diff line number Diff line Loading @@ -74,6 +74,15 @@ final class ProcessCachedOptimizerRecord { @GuardedBy("mProcLock") @GuardedBy("mProcLock") private boolean mFrozen; private boolean mFrozen; /** * If set to true it will make the (un)freeze decision sticky which means that the freezer * decision will remain the same unless a freeze is forced via {@link #mForceFreezeOps}. * This property is usually set to true when external user wants to maintain a (un)frozen state * after being applied. */ @GuardedBy("mProcLock") private boolean mFreezeSticky; /** /** * Set to false after the process has been frozen. * Set to false after the process has been frozen. * Set to true after we have collected PSS for the frozen process. * Set to true after we have collected PSS for the frozen process. Loading Loading @@ -195,6 +204,15 @@ final class ProcessCachedOptimizerRecord { void setFrozen(boolean frozen) { void setFrozen(boolean frozen) { mFrozen = frozen; mFrozen = frozen; } } @GuardedBy("mProcLock") void setFreezeSticky(boolean sticky) { mFreezeSticky = sticky; } @GuardedBy("mProcLock") boolean isFreezeSticky() { return mFreezeSticky; } boolean skipPSSCollectionBecauseFrozen() { boolean skipPSSCollectionBecauseFrozen() { boolean collected = mHasCollectedFrozenPSS; boolean collected = mHasCollectedFrozenPSS; Loading Loading
services/core/java/com/android/server/am/ActivityManagerShellCommand.java +103 −14 Original line number Original line Diff line number Diff line Loading @@ -247,6 +247,10 @@ final class ActivityManagerShellCommand extends ShellCommand { return runSendBroadcast(pw); return runSendBroadcast(pw); case "compact": case "compact": return runCompact(pw); return runCompact(pw); case "freeze": return runFreeze(pw); case "unfreeze": return runUnfreeze(pw); case "instrument": case "instrument": getOutPrintWriter().println("Error: must be invoked through 'am instrument'."); getOutPrintWriter().println("Error: must be invoked through 'am instrument'."); return -1; return -1; Loading Loading @@ -1074,20 +1078,10 @@ final class ActivityManagerShellCommand extends ShellCommand { boolean isFullCompact = op.equals("full"); boolean isFullCompact = op.equals("full"); boolean isSomeCompact = op.equals("some"); boolean isSomeCompact = op.equals("some"); if (isFullCompact || isSomeCompact) { if (isFullCompact || isSomeCompact) { String processName = getNextArgRequired(); app = getProcessFromShell(); synchronized (mInternal.mProcLock) { if (app == null) { // Default to current user getErrPrintWriter().println("Error: could not find process"); int userId = mInterface.getCurrentUserId(); return -1; String userOpt = getNextOption(); if (userOpt != null && "--user".equals(userOpt)) { int inputUserId = UserHandle.parseUserArg(getNextArgRequired()); if (inputUserId != UserHandle.USER_CURRENT) { userId = inputUserId; } } final int uid = mInternal.getPackageManagerInternal().getPackageUid(processName, 0, userId); app = mInternal.getProcessRecordLocked(processName, uid); } } pw.println("Process record found pid: " + app.mPid); pw.println("Process record found pid: " + app.mPid); if (isFullCompact) { if (isFullCompact) { Loading Loading @@ -1143,6 +1137,93 @@ final class ActivityManagerShellCommand extends ShellCommand { return 0; return 0; } } @NeverCompile int runFreeze(PrintWriter pw) throws RemoteException { String freezerOpt = getNextOption(); boolean isSticky = false; if (freezerOpt != null) { isSticky = freezerOpt.equals("--sticky"); } ProcessRecord app = getProcessFromShell(); if (app == null) { getErrPrintWriter().println("Error: could not find process"); return -1; } pw.println("Freezing pid: " + app.mPid + " sticky=" + isSticky); synchronized (mInternal) { synchronized (mInternal.mProcLock) { app.mOptRecord.setFreezeSticky(isSticky); mInternal.mOomAdjuster.mCachedAppOptimizer.freezeAppAsyncInternalLSP(app, 0, true); } } return 0; } @NeverCompile int runUnfreeze(PrintWriter pw) throws RemoteException { String freezerOpt = getNextOption(); boolean isSticky = false; if (freezerOpt != null) { isSticky = freezerOpt.equals("--sticky"); } ProcessRecord app = getProcessFromShell(); if (app == null) { getErrPrintWriter().println("Error: could not find process"); return -1; } pw.println("Unfreezing pid: " + app.mPid); synchronized (mInternal) { synchronized (mInternal.mProcLock) { synchronized (mInternal.mOomAdjuster.mCachedAppOptimizer.mFreezerLock) { app.mOptRecord.setFreezeSticky(isSticky); mInternal.mOomAdjuster.mCachedAppOptimizer.unfreezeAppInternalLSP(app, 0, false); } } } return 0; } /** * Parses from the shell the process name and user id if provided and provides the corresponding * {@link ProcessRecord)} If no user is provided, it will fallback to current user. * Example usage: {@code <processname> --user current} or {@code <processname>} * @return process record of process, null if none found. * @throws RemoteException */ @NeverCompile ProcessRecord getProcessFromShell() throws RemoteException { ProcessRecord app; String processName = getNextArgRequired(); synchronized (mInternal.mProcLock) { // Default to current user int userId = getUserIdFromShellOrFallback(); final int uid = mInternal.getPackageManagerInternal().getPackageUid(processName, 0, userId); app = mInternal.getProcessRecordLocked(processName, uid); } return app; } /** * @return User id from command line provided in the form of * {@code --user <userid|current|all>} and if the argument is not found it will fallback * to current user. * @throws RemoteException */ @NeverCompile int getUserIdFromShellOrFallback() throws RemoteException { int userId = mInterface.getCurrentUserId(); String userOpt = getNextOption(); if (userOpt != null && "--user".equals(userOpt)) { int inputUserId = UserHandle.parseUserArg(getNextArgRequired()); if (inputUserId != UserHandle.USER_CURRENT) { userId = inputUserId; } } return userId; } int runDumpHeap(PrintWriter pw) throws RemoteException { int runDumpHeap(PrintWriter pw) throws RemoteException { final PrintWriter err = getErrPrintWriter(); final PrintWriter err = getErrPrintWriter(); boolean managed = true; boolean managed = true; Loading Loading @@ -4061,6 +4142,14 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println(" Perform a native compaction for process with <pid>."); pw.println(" Perform a native compaction for process with <pid>."); pw.println(" some: execute file compaction."); pw.println(" some: execute file compaction."); pw.println(" full: execute anon + file compaction."); pw.println(" full: execute anon + file compaction."); pw.println(" freeze [--sticky] <processname> [--user <USER_ID>]"); pw.println(" Freeze a process."); pw.println(" --sticky: persists the frozen state for the process lifetime or"); pw.println(" until an unfreeze is triggered via shell"); pw.println(" unfreeze [--sticky] <processname> [--user <USER_ID>]"); pw.println(" Unfreeze a process."); pw.println(" --sticky: persists the unfrozen state for the process lifetime or"); pw.println(" until a freeze is triggered via shell"); pw.println(" instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]"); pw.println(" instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]"); pw.println(" [--user <USER_ID> | current]"); pw.println(" [--user <USER_ID> | current]"); pw.println(" [--no-hidden-api-checks [--no-test-api-access]]"); pw.println(" [--no-hidden-api-checks [--no-test-api-access]]"); Loading
services/core/java/com/android/server/am/CachedAppOptimizer.java +32 −17 Original line number Original line Diff line number Diff line Loading @@ -342,7 +342,7 @@ public final class CachedAppOptimizer { private final ActivityManagerGlobalLock mProcLock; private final ActivityManagerGlobalLock mProcLock; private final Object mFreezerLock = new Object(); public final Object mFreezerLock = new Object(); private final OnPropertiesChangedListener mOnFlagsChangedListener = private final OnPropertiesChangedListener mOnFlagsChangedListener = new OnPropertiesChangedListener() { new OnPropertiesChangedListener() { Loading Loading @@ -763,8 +763,9 @@ public final class CachedAppOptimizer { pw.println(" Apps frozen: " + size); pw.println(" Apps frozen: " + size); for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) { ProcessRecord app = mFrozenProcesses.valueAt(i); ProcessRecord app = mFrozenProcesses.valueAt(i); pw.println(" " + app.mOptRecord.getFreezeUnfreezeTime() pw.println(" " + app.mOptRecord.getFreezeUnfreezeTime() + ": " + app.getPid() + ": " + app.getPid() + " " + app.processName); + " " + app.processName + (app.mOptRecord.isFreezeSticky() ? " (sticky)" : "")); } } if (!mPendingCompactionProcesses.isEmpty()) { if (!mPendingCompactionProcesses.isEmpty()) { Loading Loading @@ -1283,12 +1284,26 @@ public final class CachedAppOptimizer { @GuardedBy({"mAm", "mProcLock"}) @GuardedBy({"mAm", "mProcLock"}) void freezeAppAsyncLSP(ProcessRecord app) { void freezeAppAsyncLSP(ProcessRecord app) { freezeAppAsyncInternalLSP(app, mFreezerDebounceTimeout, false); } @GuardedBy({"mAm", "mProcLock"}) void freezeAppAsyncInternalLSP(ProcessRecord app, long delayMillis, boolean force) { final ProcessCachedOptimizerRecord opt = app.mOptRecord; final ProcessCachedOptimizerRecord opt = app.mOptRecord; if (opt.isPendingFreeze()) { if (opt.isPendingFreeze()) { // Skip redundant DO_FREEZE message // Skip redundant DO_FREEZE message return; return; } } if (opt.isFreezeSticky() && !force) { if (DEBUG_FREEZER) { Slog.d(TAG_AM, "Skip freezing because unfrozen state is sticky pid=" + app.getPid() + " " + app.processName); } return; } if (mAm.mConstants.USE_MODERN_TRIM if (mAm.mConstants.USE_MODERN_TRIM && app.mState.getSetAdj() >= ProcessList.CACHED_APP_MIN_ADJ) { && app.mState.getSetAdj() >= ProcessList.CACHED_APP_MIN_ADJ) { final IApplicationThread thread = app.getThread(); final IApplicationThread thread = app.getThread(); Loading @@ -1301,9 +1316,8 @@ public final class CachedAppOptimizer { } } } } mFreezeHandler.sendMessageDelayed( mFreezeHandler.sendMessageDelayed( mFreezeHandler.obtainMessage( mFreezeHandler.obtainMessage(SET_FROZEN_PROCESS_MSG, DO_FREEZE, 0, app), SET_FROZEN_PROCESS_MSG, DO_FREEZE, 0, app), delayMillis); mFreezerDebounceTimeout); opt.setPendingFreeze(true); opt.setPendingFreeze(true); if (DEBUG_FREEZER) { if (DEBUG_FREEZER) { Slog.d(TAG_AM, "Async freezing " + app.getPid() + " " + app.processName); Slog.d(TAG_AM, "Async freezing " + app.getPid() + " " + app.processName); Loading @@ -1311,9 +1325,19 @@ public final class CachedAppOptimizer { } } @GuardedBy({"mAm", "mProcLock", "mFreezerLock"}) @GuardedBy({"mAm", "mProcLock", "mFreezerLock"}) void unfreezeAppInternalLSP(ProcessRecord app, @UnfreezeReason int reason) { void unfreezeAppInternalLSP(ProcessRecord app, @UnfreezeReason int reason, boolean force) { final int pid = app.getPid(); final int pid = app.getPid(); final ProcessCachedOptimizerRecord opt = app.mOptRecord; final ProcessCachedOptimizerRecord opt = app.mOptRecord; boolean sticky = opt.isFreezeSticky(); if (sticky && !force) { // Sticky freezes will not change their state unless forced out of it. if (DEBUG_FREEZER) { Slog.d(TAG_AM, "Skip unfreezing because frozen state is sticky pid=" + pid + " " + app.processName); } return; } if (opt.isPendingFreeze()) { if (opt.isPendingFreeze()) { // Remove pending DO_FREEZE message // Remove pending DO_FREEZE message mFreezeHandler.removeMessages(SET_FROZEN_PROCESS_MSG, app); mFreezeHandler.removeMessages(SET_FROZEN_PROCESS_MSG, app); Loading Loading @@ -1406,7 +1430,7 @@ public final class CachedAppOptimizer { @GuardedBy({"mAm", "mProcLock"}) @GuardedBy({"mAm", "mProcLock"}) void unfreezeAppLSP(ProcessRecord app, @UnfreezeReason int reason) { void unfreezeAppLSP(ProcessRecord app, @UnfreezeReason int reason) { synchronized (mFreezerLock) { synchronized (mFreezerLock) { unfreezeAppInternalLSP(app, reason); unfreezeAppInternalLSP(app, reason, false); } } } } Loading Loading @@ -2080,15 +2104,6 @@ public final class CachedAppOptimizer { synchronized (mProcLock) { synchronized (mProcLock) { pid = proc.getPid(); pid = proc.getPid(); if (proc.mState.getCurAdj() < ProcessList.CACHED_APP_MIN_ADJ || opt.shouldNotFreeze()) { if (DEBUG_FREEZER) { Slog.d(TAG_AM, "Skipping freeze for process " + pid + " " + name + " curAdj = " + proc.mState.getCurAdj() + ", shouldNotFreeze = " + opt.shouldNotFreeze()); } return; } if (mFreezerOverride) { if (mFreezerOverride) { opt.setFreezerOverride(true); opt.setFreezerOverride(true); Loading
services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java +18 −0 Original line number Original line Diff line number Diff line Loading @@ -74,6 +74,15 @@ final class ProcessCachedOptimizerRecord { @GuardedBy("mProcLock") @GuardedBy("mProcLock") private boolean mFrozen; private boolean mFrozen; /** * If set to true it will make the (un)freeze decision sticky which means that the freezer * decision will remain the same unless a freeze is forced via {@link #mForceFreezeOps}. * This property is usually set to true when external user wants to maintain a (un)frozen state * after being applied. */ @GuardedBy("mProcLock") private boolean mFreezeSticky; /** /** * Set to false after the process has been frozen. * Set to false after the process has been frozen. * Set to true after we have collected PSS for the frozen process. * Set to true after we have collected PSS for the frozen process. Loading Loading @@ -195,6 +204,15 @@ final class ProcessCachedOptimizerRecord { void setFrozen(boolean frozen) { void setFrozen(boolean frozen) { mFrozen = frozen; mFrozen = frozen; } } @GuardedBy("mProcLock") void setFreezeSticky(boolean sticky) { mFreezeSticky = sticky; } @GuardedBy("mProcLock") boolean isFreezeSticky() { return mFreezeSticky; } boolean skipPSSCollectionBecauseFrozen() { boolean skipPSSCollectionBecauseFrozen() { boolean collected = mHasCollectedFrozenPSS; boolean collected = mHasCollectedFrozenPSS; Loading