Loading services/core/java/com/android/server/am/ActivityManagerService.java +13 −1 Original line number Diff line number Diff line Loading @@ -8392,7 +8392,7 @@ public class ActivityManagerService extends IActivityManager.Stub * thread of the given process. */ @GuardedBy("mProcLock") static void setFifoPriority(@NonNull ProcessRecord app, boolean enable) { static void setFifoPriority(@NonNull ProcessRecordInternal app, boolean enable) { final int pid = app.getPid(); final int renderThreadTid = app.getRenderThreadTid(); if (enable) { Loading Loading @@ -19469,6 +19469,18 @@ public class ActivityManagerService extends IActivityManager.Stub } } } @Override public void onProcStateUpdated(ProcessRecordInternal appInternal, long now, boolean forceUpdatePssTime) { final ProcessRecord app = (ProcessRecord) appInternal; synchronized (mAppProfiler.mProfilerLock) { app.mProfile.updateProcState(app); mAppProfiler.updateNextPssTimeLPf(app.getCurProcState(), app.mProfile, now, forceUpdatePssTime); } } } services/core/java/com/android/server/am/OomAdjuster.java +49 −48 Original line number Diff line number Diff line Loading @@ -408,6 +408,10 @@ public abstract class OomAdjuster { void onProcessFreezabilityChanged(ProcessRecordInternal app, boolean freezePolicy, @OomAdjReason int oomAdjReason, boolean immediate, int oldOomAdj, boolean shouldNotFreezeChanged); /** Notifies the client component when a process's process state is updated. */ void onProcStateUpdated(ProcessRecordInternal app, long now, boolean forceUpdatePssTime); } @VisibleForTesting Loading Loading @@ -540,7 +544,7 @@ public abstract class OomAdjuster { } } void setAppAndChildProcessGroup(ProcessRecord app, int group) { void setAppAndChildProcessGroup(ProcessRecordInternal app, int group) { mProcessGroupHandler.sendMessage(mProcessGroupHandler.obtainMessage( group, app)); } Loading Loading @@ -2069,14 +2073,13 @@ public abstract class OomAdjuster { /** Applies the computed oomadj, procstate and sched group values and freezes them in set* */ @GuardedBy({"mService", "mProcLock"}) protected boolean applyOomAdjLSP(ProcessRecord app, boolean doingAll, long now, protected boolean applyOomAdjLSP(ProcessRecordInternal state, boolean doingAll, long now, long nowElapsed, @OomAdjReason int oomAdjReson, boolean isBatchingOomAdj) { boolean success = true; final ProcessRecordInternal state = app; final UidRecordInternal uidRec = app.getUidRecord(); final UidRecordInternal uidRec = state.getUidRecord(); final boolean reportDebugMsgs = DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == app.info.uid; final boolean reportDebugMsgs = DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == state.getApplicationUid(); if (state.getCurRawAdj() != state.getSetRawAdj()) { state.setSetRawAdj(state.getCurRawAdj()); Loading @@ -2085,19 +2088,19 @@ public abstract class OomAdjuster { int changes = 0; if (state.getCurAdj() != state.getSetAdj()) { mCallback.onOomAdjustChanged(state.getSetAdj(), state.getCurAdj(), app); mCallback.onOomAdjustChanged(state.getSetAdj(), state.getCurAdj(), state); } final int oldOomAdj = state.getSetAdj(); if (state.getCurAdj() != state.getSetAdj()) { if (isBatchingOomAdj && mConstants.ENABLE_BATCHING_OOM_ADJ) { mProcsToOomAdj.add(app); mProcsToOomAdj.add(state); } else { mInjector.setOomAdj(app.getPid(), app.uid, state.getCurAdj()); mInjector.setOomAdj(state.getPid(), state.uid, state.getCurAdj()); } if (reportDebugMsgs) { String msg = "Set " + app.getPid() + " " + app.processName + " adj " String msg = "Set " + state.getPid() + " " + state.processName + " adj " + state.getCurAdj() + ": " + state.getAdjType(); reportOomAdjMessageLocked(TAG_OOM_ADJ, msg); } Loading @@ -2109,17 +2112,17 @@ public abstract class OomAdjuster { } final int curSchedGroup = state.getCurrentSchedulingGroup(); if (app.getWaitingToKill() != null && !app.getReceivers().isReceivingBroadcast() if (state.getWaitingToKill() != null && !state.getReceivers().isReceivingBroadcast() && ActivityManager.isProcStateBackground(state.getCurProcState()) && !state.getHasStartedServices()) { app.killLocked(app.getWaitingToKill(), ApplicationExitInfo.REASON_USER_REQUESTED, state.killLocked(state.getWaitingToKill(), ApplicationExitInfo.REASON_USER_REQUESTED, ApplicationExitInfo.SUBREASON_REMOVE_TASK, true); success = false; } else if (state.getSetSchedGroup() != curSchedGroup) { int oldSchedGroup = state.getSetSchedGroup(); state.setSetSchedGroup(curSchedGroup); if (reportDebugMsgs) { String msg = "Setting sched group of " + app.processName String msg = "Setting sched group of " + state.processName + " to " + curSchedGroup + ": " + state.getAdjType(); reportOomAdjMessageLocked(TAG_OOM_ADJ, msg); } Loading @@ -2142,20 +2145,20 @@ public abstract class OomAdjuster { processGroup = THREAD_GROUP_DEFAULT; break; } setAppAndChildProcessGroup(app, processGroup); setAppAndChildProcessGroup(state, processGroup); try { final int renderThreadTid = app.getRenderThreadTid(); final int renderThreadTid = state.getRenderThreadTid(); if (curSchedGroup == SCHED_GROUP_TOP_APP) { // do nothing if we already switched to RT if (oldSchedGroup != SCHED_GROUP_TOP_APP) { app.notifyTopProcChanged(); if (app.useFifoUiScheduling()) { state.notifyTopProcChanged(); if (state.useFifoUiScheduling()) { // Switch UI pipeline for app to SCHED_FIFO state.setSavedPriority(Process.getThreadPriority(app.getPid())); ActivityManagerService.setFifoPriority(app, true /* enable */); state.setSavedPriority(Process.getThreadPriority(state.getPid())); ActivityManagerService.setFifoPriority(state, true /* enable */); } else { // Boost priority for top app UI and render threads mInjector.setThreadPriority(app.getPid(), mInjector.setThreadPriority(state.getPid(), THREAD_PRIORITY_TOP_APP_BOOST); if (renderThreadTid != 0) { try { Loading @@ -2169,14 +2172,14 @@ public abstract class OomAdjuster { } } else if (oldSchedGroup == SCHED_GROUP_TOP_APP && curSchedGroup != SCHED_GROUP_TOP_APP) { app.notifyTopProcChanged(); if (app.useFifoUiScheduling()) { state.notifyTopProcChanged(); if (state.useFifoUiScheduling()) { // Reset UI pipeline to SCHED_OTHER ActivityManagerService.setFifoPriority(app, false /* enable */); mInjector.setThreadPriority(app.getPid(), state.getSavedPriority()); ActivityManagerService.setFifoPriority(state, false /* enable */); mInjector.setThreadPriority(state.getPid(), state.getSavedPriority()); } else { // Reset priority for top app UI and render threads mInjector.setThreadPriority(app.getPid(), 0); mInjector.setThreadPriority(state.getPid(), 0); } if (renderThreadTid != 0) { Loading @@ -2185,7 +2188,7 @@ public abstract class OomAdjuster { } } catch (Exception e) { if (DEBUG_ALL) { Slog.w(TAG, "Failed setting thread priority of " + app.getPid(), e); Slog.w(TAG, "Failed setting thread priority of " + state.getPid(), e); } } } Loading @@ -2194,11 +2197,11 @@ public abstract class OomAdjuster { changes |= ActivityManagerService.ProcessChangeItem.CHANGE_ACTIVITIES; } updateAppFreezeStateLSP(app, oomAdjReson, false, oldOomAdj); updateAppFreezeStateLSP(state, oomAdjReson, false, oldOomAdj); if (state.getReportedProcState() != state.getCurProcState()) { state.setReportedProcState(state.getCurProcState()); app.setProcessStateToThread(state.getReportedProcState()); state.setProcessStateToThread(state.getReportedProcState()); } boolean forceUpdatePssTime = false; if (state.getSetProcState() == PROCESS_STATE_NONEXISTENT Loading @@ -2210,18 +2213,15 @@ public abstract class OomAdjuster { Slog.d(TAG_PSS, "Process state change from " + ProcessList.makeProcStateString(state.getSetProcState()) + " to " + ProcessList.makeProcStateString(state.getCurProcState()) + " next pss in " + (app.mProfile.getNextPssTime() - now) + ": " + app); } + (state.getNextPssTime() - now) + ": " + state); } synchronized (mService.mAppProfiler.mProfilerLock) { app.mProfile.updateProcState(app); mService.mAppProfiler.updateNextPssTimeLPf( state.getCurProcState(), app.mProfile, now, forceUpdatePssTime); } mCallback.onProcStateUpdated(state, now, forceUpdatePssTime); int oldProcState = state.getSetProcState(); if (state.getSetProcState() != state.getCurProcState()) { if (reportDebugMsgs) { String msg = "Proc state change of " + app.processName String msg = "Proc state change of " + state.processName + " to " + ProcessList.makeProcStateString(state.getCurProcState()) + " (" + state.getCurProcState() + ")" + ": " + state.getAdjType(); reportOomAdjMessageLocked(TAG_OOM_ADJ, msg); Loading @@ -2233,18 +2233,19 @@ public abstract class OomAdjuster { // arbitrary amounts of battery power. Note its current CPU time to later know to // kill it if it is not behaving well. state.setWhenUnimportant(now); app.mProfile.mLastCpuTime.set(0); state.setLastCpuTime(0); } // Inform UsageStats of important process state change // Must be called before updating setProcState maybeUpdateUsageStatsLSP(app, nowElapsed); maybeUpdateUsageStatsLSP(state, nowElapsed); maybeUpdateLastTopTime(state, now); state.setSetProcState(state.getCurProcState()); if (!doingAll) { synchronized (mService.mProcessStats.mLock) { mService.setProcessTrackerStateLOSP(app, // TODO: b/441408003 - Decouple the AMS usage out of OomAdjuster. mService.setProcessTrackerStateLOSP((ProcessRecord) state, mService.mProcessStats.getMemFactorLocked()); } } Loading @@ -2257,7 +2258,7 @@ public abstract class OomAdjuster { // For apps that sit around for a long time in the interactive state, we need // to report this at least once a day so they don't go idle. if ((nowElapsed - state.getInteractionEventTime()) > interactionThreshold) { maybeUpdateUsageStatsLSP(app, nowElapsed); maybeUpdateUsageStatsLSP(state, nowElapsed); } } else { final boolean fgsInteractionChangeEnabled = state.getCachedCompatChange( Loading @@ -2267,7 +2268,7 @@ public abstract class OomAdjuster { : mConstants.SERVICE_USAGE_INTERACTION_TIME_PRE_S; // For foreground services that sit around for a long time but are not interacted with. if ((nowElapsed - state.getFgInteractionTime()) > interactionThreshold) { maybeUpdateUsageStatsLSP(app, nowElapsed); maybeUpdateUsageStatsLSP(state, nowElapsed); } } Loading @@ -2284,7 +2285,7 @@ public abstract class OomAdjuster { mService.mHandler.post(() -> { synchronized (mService) { mService.mServices.stopAllForegroundServicesLocked( app.uid, app.getPackageName()); state.uid, state.getPackageName()); } }); } Loading @@ -2292,12 +2293,12 @@ public abstract class OomAdjuster { if (changes != 0) { if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, "Changes in " + app + ": " + changes); mProcessList.enqueueProcessChangeItemLocked(app.getPid(), app.info.uid, "Changes in " + state + ": " + changes); mProcessList.enqueueProcessChangeItemLocked(state.getPid(), state.getApplicationUid(), changes, state.getHasRepForegroundActivities()); if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, "Enqueued process change item for " + app.toShortString() + ": changes=" + changes + state.toShortString() + ": changes=" + changes + " foreground=" + state.getHasRepForegroundActivities() + " type=" + state.getAdjType() + " source=" + state.getAdjSource() + " target=" + state.getAdjTarget()); Loading @@ -2311,9 +2312,9 @@ public abstract class OomAdjuster { state.setLastCachedTime(nowElapsed); if (mService.mDeterministicUidIdle || !mService.mHandler.hasMessages(IDLE_UIDS_MSG)) { if (mLogger.shouldLog(app.uid)) { if (mLogger.shouldLog(state.uid)) { mLogger.logScheduleUidIdle2( uidRec.getUid(), app.getPid(), uidRec.getUid(), state.getPid(), mConstants.mKillBgRestrictedAndCachedIdleSettleTimeMs); } mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, Loading @@ -2322,8 +2323,8 @@ public abstract class OomAdjuster { } state.setSetCached(state.isCached()); if (((oldProcState != state.getSetProcState()) || (oldOomAdj != state.getSetAdj())) && mLogger.shouldLog(app.uid)) { mLogger.logProcStateChanged(app.uid, app.getPid(), && mLogger.shouldLog(state.uid)) { mLogger.logProcStateChanged(state.uid, state.getPid(), state.getSetProcState(), oldProcState, state.getSetAdj(), oldOomAdj); } Loading services/core/java/com/android/server/am/ProcessRecord.java +16 −59 Original line number Diff line number Diff line Loading @@ -235,12 +235,6 @@ class ProcessRecord extends ProcessRecordInternal implements WindowProcessListen @GuardedBy("mProcLock") private boolean mUnlocked; /** * TID for RenderThread. */ @GuardedBy("mProcLock") private int mRenderThreadTid; /** * Last used compatibility mode. */ Loading Loading @@ -283,12 +277,6 @@ class ProcessRecord extends ProcessRecordInternal implements WindowProcessListen @CompositeRWLock({"mService", "mProcLock"}) private long mKillTime; /** * Process is waiting to be killed when in the bg, and reason. */ @GuardedBy("mService") private String mWaitingToKill; /** * Whether this process should be killed and removed from process list. * It is set when the package is force-stopped or the process has crashed too many times. Loading Loading @@ -516,10 +504,10 @@ class ProcessRecord extends ProcessRecordInternal implements WindowProcessListen pw.print(prefix); pw.print("startSeq="); pw.println(mStartSeq); pw.print(prefix); pw.print("mountMode="); pw.println( DebugUtils.valueToString(Zygote.class, "MOUNT_EXTERNAL_", mMountMode)); if (isKilled() || isKilledByAm() || mWaitingToKill != null) { if (isKilled() || isKilledByAm() || getWaitingToKill() != null) { pw.print(prefix); pw.print("killed="); pw.print(isKilled()); pw.print(" killedByAm="); pw.print(isKilledByAm()); pw.print(" waitingToKill="); pw.println(mWaitingToKill); pw.print(" waitingToKill="); pw.println(getWaitingToKill()); } if (mIsolatedEntryPoint != null || mIsolatedEntryPointArgs != null) { pw.print(prefix); pw.print("isolatedEntryPoint="); pw.println(mIsolatedEntryPoint); Loading Loading @@ -904,16 +892,6 @@ class ProcessRecord extends ProcessRecordInternal implements WindowProcessListen mUnlocked = unlocked; } @GuardedBy("mProcLock") int getRenderThreadTid() { return mRenderThreadTid; } @GuardedBy("mProcLock") void setRenderThreadTid(int renderThreadTid) { mRenderThreadTid = renderThreadTid; } @GuardedBy("mService") CompatibilityInfo getCompat() { return mCompat; Loading Loading @@ -1003,16 +981,6 @@ class ProcessRecord extends ProcessRecordInternal implements WindowProcessListen mKillTime = killTime; } @GuardedBy("mService") String getWaitingToKill() { return mWaitingToKill; } @GuardedBy("mService") void setWaitingToKill(String waitingToKill) { mWaitingToKill = waitingToKill; } @Override public boolean isRemoved() { return mRemoved; Loading Loading @@ -1326,31 +1294,9 @@ class ProcessRecord extends ProcessRecordInternal implements WindowProcessListen return (rss != null && rss.length > 0) ? rss[0] : 0; } @Override @GuardedBy("mService") void killLocked(String reason, @Reason int reasonCode, boolean noisy) { killLocked(reason, reasonCode, ApplicationExitInfo.SUBREASON_UNKNOWN, noisy, true); } @GuardedBy("mService") void killLocked(String reason, @Reason int reasonCode, @SubReason int subReason, boolean noisy) { killLocked(reason, reason, reasonCode, subReason, noisy, true); } @GuardedBy("mService") void killLocked(String reason, String description, @Reason int reasonCode, @SubReason int subReason, boolean noisy) { killLocked(reason, description, reasonCode, subReason, noisy, true); } @GuardedBy("mService") void killLocked(String reason, @Reason int reasonCode, @SubReason int subReason, boolean noisy, boolean asyncKPG) { killLocked(reason, reason, reasonCode, subReason, noisy, asyncKPG); } @GuardedBy("mService") void killLocked(String reason, String description, @Reason int reasonCode, public void killLocked(String reason, String description, @Reason int reasonCode, @SubReason int subReason, boolean noisy, boolean asyncKPG) { if (!isKilledByAm()) { if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) { Loading Loading @@ -1468,6 +1414,7 @@ class ProcessRecord extends ProcessRecordInternal implements WindowProcessListen return sb.toString(); } @Override public String toShortString() { final String shortStringName = mShortStringName; if (shortStringName != null) { Loading Loading @@ -1708,6 +1655,16 @@ class ProcessRecord extends ProcessRecordInternal implements WindowProcessListen } } @Override public long getNextPssTime() { return mProfile.getNextPssTime(); } @Override public void setLastCpuTime(long time) { mProfile.mLastCpuTime.set(time); } @Override public void setPendingUiClean(boolean pendingUiClean) { synchronized (mProcLock) { Loading Loading @@ -1760,7 +1717,7 @@ class ProcessRecord extends ProcessRecordInternal implements WindowProcessListen public void onStartActivity(int topProcessState, boolean setProfileProc, String packageName, long versionCode) { synchronized (mService) { mWaitingToKill = null; setWaitingToKill(null); if (setProfileProc) { synchronized (mService.mAppProfiler.mProfilerLock) { mService.mAppProfiler.setProfileProcLPf(this); Loading services/core/java/com/android/server/am/psc/ProcessRecordInternal.java +119 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_ import android.annotation.ElapsedRealtimeLong; import android.app.ActivityManager; import android.app.ApplicationExitInfo; import android.os.Process; import android.os.SystemClock; import android.os.Trace; Loading Loading @@ -283,6 +284,95 @@ public abstract class ProcessRecordInternal { /** Returns an array of package names associated with this process. */ public abstract String[] getPackageList(); /** Returns a short string representation of the process. */ public abstract String toShortString(); /** Returns the next scheduled time for PSS collection for this process. */ public abstract long getNextPssTime(); /** Sets the last recorded CPU time for this process. */ public abstract void setLastCpuTime(long time); /** * Kills the process with the given reason code, using the provided reason string * as both the reason and a default description. The process group is killed * asynchronously. * * @param reason A string describing the reason for the kill. * @param reasonCode The reason code for the kill. * @param noisy If true, a log message will be reported. */ @GuardedBy("mServiceLock") public void killLocked(String reason, @ApplicationExitInfo.Reason int reasonCode, boolean noisy) { killLocked(reason, reasonCode, ApplicationExitInfo.SUBREASON_UNKNOWN, noisy, true); } /** * Kills the process with the given reason and subreason codes, using the provided * reason string as both the reason and a default description. The process group * is killed asynchronously. * * @param reason A string describing the reason for the kill. * @param reasonCode The reason code for the kill. * @param subReason The subreason code for the kill. * @param noisy If true, a log message will be reported. */ @GuardedBy("mServiceLock") public void killLocked(String reason, @ApplicationExitInfo.Reason int reasonCode, @ApplicationExitInfo.SubReason int subReason, boolean noisy) { killLocked(reason, reason, reasonCode, subReason, noisy, true); } /** * Kills the process with detailed reason information. The process group * is killed asynchronously. * * @param reason A string describing the high-level reason for the kill. * @param description A more detailed description of the kill reason. * @param reasonCode The reason code for the kill. * @param subReason The subreason code for the kill. * @param noisy If true, a log message will be reported. */ @GuardedBy("mServiceLock") public void killLocked(String reason, String description, @ApplicationExitInfo.Reason int reasonCode, @ApplicationExitInfo.SubReason int subReason, boolean noisy) { killLocked(reason, description, reasonCode, subReason, noisy, true); } /** * Kills the process with the given reason and subreason codes, using the provided * reason string as both the reason and a default description. Allows control over * whether the process group is killed asynchronously. * * @param reason A string describing the reason for the kill. * @param reasonCode The reason code for the kill. * @param subReason The subreason code for the kill. * @param noisy If true, a log message will be reported. * @param asyncKPG If true, kills the process group asynchronously. */ @GuardedBy("mServiceLock") public void killLocked(String reason, @ApplicationExitInfo.Reason int reasonCode, @ApplicationExitInfo.SubReason int subReason, boolean noisy, boolean asyncKPG) { killLocked(reason, reason, reasonCode, subReason, noisy, asyncKPG); } /** * Kills the process with the given reason, description, reason codes, and async KPG. * * @param reason A string describing the reason for the kill. * @param description A more detailed description of the kill reason. * @param reasonCode The reason code for the kill. * @param subReason The subreason code for the kill. * @param noisy If true, a log message will be reported. * @param asyncKPG If true, kills the process group asynchronously. */ @GuardedBy("mServiceLock") public abstract void killLocked(String reason, String description, @ApplicationExitInfo.Reason int reasonCode, @ApplicationExitInfo.SubReason int subReason, boolean noisy, boolean asyncKPG); // Enable this to trace all OomAdjuster state transitions private static final boolean TRACE_OOM_ADJ = false; Loading Loading @@ -742,6 +832,14 @@ public abstract class ProcessRecordInternal { @GuardedBy("mServiceLock") private long mFollowupUpdateUptimeMs = Long.MAX_VALUE; /** TID for RenderThread. */ @GuardedBy("mProcLock") private int mRenderThreadTid; /** Process is waiting to be killed when in the bg, and reason. */ @GuardedBy("mServiceLock") private String mWaitingToKill; // TODO(b/425766486): Change to package-private after the OomAdjusterImpl class is moved to // the psc package. public final OomAdjusterImpl.ProcessRecordNode[] mLinkedNodes = Loading Loading @@ -1721,6 +1819,27 @@ public abstract class ProcessRecordInternal { return mLastCachedTime; } @GuardedBy("mServiceLock") public String getWaitingToKill() { return mWaitingToKill; } @GuardedBy("mServiceLock") public void setWaitingToKill(String waitingToKill) { mWaitingToKill = waitingToKill; } @GuardedBy("mProcLock") public int getRenderThreadTid() { return mRenderThreadTid; } @GuardedBy("mProcLock") public void setRenderThreadTid(int renderThreadTid) { mRenderThreadTid = renderThreadTid; } /** * Lazily initiates and returns the track name for tracing. */ Loading Loading
services/core/java/com/android/server/am/ActivityManagerService.java +13 −1 Original line number Diff line number Diff line Loading @@ -8392,7 +8392,7 @@ public class ActivityManagerService extends IActivityManager.Stub * thread of the given process. */ @GuardedBy("mProcLock") static void setFifoPriority(@NonNull ProcessRecord app, boolean enable) { static void setFifoPriority(@NonNull ProcessRecordInternal app, boolean enable) { final int pid = app.getPid(); final int renderThreadTid = app.getRenderThreadTid(); if (enable) { Loading Loading @@ -19469,6 +19469,18 @@ public class ActivityManagerService extends IActivityManager.Stub } } } @Override public void onProcStateUpdated(ProcessRecordInternal appInternal, long now, boolean forceUpdatePssTime) { final ProcessRecord app = (ProcessRecord) appInternal; synchronized (mAppProfiler.mProfilerLock) { app.mProfile.updateProcState(app); mAppProfiler.updateNextPssTimeLPf(app.getCurProcState(), app.mProfile, now, forceUpdatePssTime); } } }
services/core/java/com/android/server/am/OomAdjuster.java +49 −48 Original line number Diff line number Diff line Loading @@ -408,6 +408,10 @@ public abstract class OomAdjuster { void onProcessFreezabilityChanged(ProcessRecordInternal app, boolean freezePolicy, @OomAdjReason int oomAdjReason, boolean immediate, int oldOomAdj, boolean shouldNotFreezeChanged); /** Notifies the client component when a process's process state is updated. */ void onProcStateUpdated(ProcessRecordInternal app, long now, boolean forceUpdatePssTime); } @VisibleForTesting Loading Loading @@ -540,7 +544,7 @@ public abstract class OomAdjuster { } } void setAppAndChildProcessGroup(ProcessRecord app, int group) { void setAppAndChildProcessGroup(ProcessRecordInternal app, int group) { mProcessGroupHandler.sendMessage(mProcessGroupHandler.obtainMessage( group, app)); } Loading Loading @@ -2069,14 +2073,13 @@ public abstract class OomAdjuster { /** Applies the computed oomadj, procstate and sched group values and freezes them in set* */ @GuardedBy({"mService", "mProcLock"}) protected boolean applyOomAdjLSP(ProcessRecord app, boolean doingAll, long now, protected boolean applyOomAdjLSP(ProcessRecordInternal state, boolean doingAll, long now, long nowElapsed, @OomAdjReason int oomAdjReson, boolean isBatchingOomAdj) { boolean success = true; final ProcessRecordInternal state = app; final UidRecordInternal uidRec = app.getUidRecord(); final UidRecordInternal uidRec = state.getUidRecord(); final boolean reportDebugMsgs = DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == app.info.uid; final boolean reportDebugMsgs = DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == state.getApplicationUid(); if (state.getCurRawAdj() != state.getSetRawAdj()) { state.setSetRawAdj(state.getCurRawAdj()); Loading @@ -2085,19 +2088,19 @@ public abstract class OomAdjuster { int changes = 0; if (state.getCurAdj() != state.getSetAdj()) { mCallback.onOomAdjustChanged(state.getSetAdj(), state.getCurAdj(), app); mCallback.onOomAdjustChanged(state.getSetAdj(), state.getCurAdj(), state); } final int oldOomAdj = state.getSetAdj(); if (state.getCurAdj() != state.getSetAdj()) { if (isBatchingOomAdj && mConstants.ENABLE_BATCHING_OOM_ADJ) { mProcsToOomAdj.add(app); mProcsToOomAdj.add(state); } else { mInjector.setOomAdj(app.getPid(), app.uid, state.getCurAdj()); mInjector.setOomAdj(state.getPid(), state.uid, state.getCurAdj()); } if (reportDebugMsgs) { String msg = "Set " + app.getPid() + " " + app.processName + " adj " String msg = "Set " + state.getPid() + " " + state.processName + " adj " + state.getCurAdj() + ": " + state.getAdjType(); reportOomAdjMessageLocked(TAG_OOM_ADJ, msg); } Loading @@ -2109,17 +2112,17 @@ public abstract class OomAdjuster { } final int curSchedGroup = state.getCurrentSchedulingGroup(); if (app.getWaitingToKill() != null && !app.getReceivers().isReceivingBroadcast() if (state.getWaitingToKill() != null && !state.getReceivers().isReceivingBroadcast() && ActivityManager.isProcStateBackground(state.getCurProcState()) && !state.getHasStartedServices()) { app.killLocked(app.getWaitingToKill(), ApplicationExitInfo.REASON_USER_REQUESTED, state.killLocked(state.getWaitingToKill(), ApplicationExitInfo.REASON_USER_REQUESTED, ApplicationExitInfo.SUBREASON_REMOVE_TASK, true); success = false; } else if (state.getSetSchedGroup() != curSchedGroup) { int oldSchedGroup = state.getSetSchedGroup(); state.setSetSchedGroup(curSchedGroup); if (reportDebugMsgs) { String msg = "Setting sched group of " + app.processName String msg = "Setting sched group of " + state.processName + " to " + curSchedGroup + ": " + state.getAdjType(); reportOomAdjMessageLocked(TAG_OOM_ADJ, msg); } Loading @@ -2142,20 +2145,20 @@ public abstract class OomAdjuster { processGroup = THREAD_GROUP_DEFAULT; break; } setAppAndChildProcessGroup(app, processGroup); setAppAndChildProcessGroup(state, processGroup); try { final int renderThreadTid = app.getRenderThreadTid(); final int renderThreadTid = state.getRenderThreadTid(); if (curSchedGroup == SCHED_GROUP_TOP_APP) { // do nothing if we already switched to RT if (oldSchedGroup != SCHED_GROUP_TOP_APP) { app.notifyTopProcChanged(); if (app.useFifoUiScheduling()) { state.notifyTopProcChanged(); if (state.useFifoUiScheduling()) { // Switch UI pipeline for app to SCHED_FIFO state.setSavedPriority(Process.getThreadPriority(app.getPid())); ActivityManagerService.setFifoPriority(app, true /* enable */); state.setSavedPriority(Process.getThreadPriority(state.getPid())); ActivityManagerService.setFifoPriority(state, true /* enable */); } else { // Boost priority for top app UI and render threads mInjector.setThreadPriority(app.getPid(), mInjector.setThreadPriority(state.getPid(), THREAD_PRIORITY_TOP_APP_BOOST); if (renderThreadTid != 0) { try { Loading @@ -2169,14 +2172,14 @@ public abstract class OomAdjuster { } } else if (oldSchedGroup == SCHED_GROUP_TOP_APP && curSchedGroup != SCHED_GROUP_TOP_APP) { app.notifyTopProcChanged(); if (app.useFifoUiScheduling()) { state.notifyTopProcChanged(); if (state.useFifoUiScheduling()) { // Reset UI pipeline to SCHED_OTHER ActivityManagerService.setFifoPriority(app, false /* enable */); mInjector.setThreadPriority(app.getPid(), state.getSavedPriority()); ActivityManagerService.setFifoPriority(state, false /* enable */); mInjector.setThreadPriority(state.getPid(), state.getSavedPriority()); } else { // Reset priority for top app UI and render threads mInjector.setThreadPriority(app.getPid(), 0); mInjector.setThreadPriority(state.getPid(), 0); } if (renderThreadTid != 0) { Loading @@ -2185,7 +2188,7 @@ public abstract class OomAdjuster { } } catch (Exception e) { if (DEBUG_ALL) { Slog.w(TAG, "Failed setting thread priority of " + app.getPid(), e); Slog.w(TAG, "Failed setting thread priority of " + state.getPid(), e); } } } Loading @@ -2194,11 +2197,11 @@ public abstract class OomAdjuster { changes |= ActivityManagerService.ProcessChangeItem.CHANGE_ACTIVITIES; } updateAppFreezeStateLSP(app, oomAdjReson, false, oldOomAdj); updateAppFreezeStateLSP(state, oomAdjReson, false, oldOomAdj); if (state.getReportedProcState() != state.getCurProcState()) { state.setReportedProcState(state.getCurProcState()); app.setProcessStateToThread(state.getReportedProcState()); state.setProcessStateToThread(state.getReportedProcState()); } boolean forceUpdatePssTime = false; if (state.getSetProcState() == PROCESS_STATE_NONEXISTENT Loading @@ -2210,18 +2213,15 @@ public abstract class OomAdjuster { Slog.d(TAG_PSS, "Process state change from " + ProcessList.makeProcStateString(state.getSetProcState()) + " to " + ProcessList.makeProcStateString(state.getCurProcState()) + " next pss in " + (app.mProfile.getNextPssTime() - now) + ": " + app); } + (state.getNextPssTime() - now) + ": " + state); } synchronized (mService.mAppProfiler.mProfilerLock) { app.mProfile.updateProcState(app); mService.mAppProfiler.updateNextPssTimeLPf( state.getCurProcState(), app.mProfile, now, forceUpdatePssTime); } mCallback.onProcStateUpdated(state, now, forceUpdatePssTime); int oldProcState = state.getSetProcState(); if (state.getSetProcState() != state.getCurProcState()) { if (reportDebugMsgs) { String msg = "Proc state change of " + app.processName String msg = "Proc state change of " + state.processName + " to " + ProcessList.makeProcStateString(state.getCurProcState()) + " (" + state.getCurProcState() + ")" + ": " + state.getAdjType(); reportOomAdjMessageLocked(TAG_OOM_ADJ, msg); Loading @@ -2233,18 +2233,19 @@ public abstract class OomAdjuster { // arbitrary amounts of battery power. Note its current CPU time to later know to // kill it if it is not behaving well. state.setWhenUnimportant(now); app.mProfile.mLastCpuTime.set(0); state.setLastCpuTime(0); } // Inform UsageStats of important process state change // Must be called before updating setProcState maybeUpdateUsageStatsLSP(app, nowElapsed); maybeUpdateUsageStatsLSP(state, nowElapsed); maybeUpdateLastTopTime(state, now); state.setSetProcState(state.getCurProcState()); if (!doingAll) { synchronized (mService.mProcessStats.mLock) { mService.setProcessTrackerStateLOSP(app, // TODO: b/441408003 - Decouple the AMS usage out of OomAdjuster. mService.setProcessTrackerStateLOSP((ProcessRecord) state, mService.mProcessStats.getMemFactorLocked()); } } Loading @@ -2257,7 +2258,7 @@ public abstract class OomAdjuster { // For apps that sit around for a long time in the interactive state, we need // to report this at least once a day so they don't go idle. if ((nowElapsed - state.getInteractionEventTime()) > interactionThreshold) { maybeUpdateUsageStatsLSP(app, nowElapsed); maybeUpdateUsageStatsLSP(state, nowElapsed); } } else { final boolean fgsInteractionChangeEnabled = state.getCachedCompatChange( Loading @@ -2267,7 +2268,7 @@ public abstract class OomAdjuster { : mConstants.SERVICE_USAGE_INTERACTION_TIME_PRE_S; // For foreground services that sit around for a long time but are not interacted with. if ((nowElapsed - state.getFgInteractionTime()) > interactionThreshold) { maybeUpdateUsageStatsLSP(app, nowElapsed); maybeUpdateUsageStatsLSP(state, nowElapsed); } } Loading @@ -2284,7 +2285,7 @@ public abstract class OomAdjuster { mService.mHandler.post(() -> { synchronized (mService) { mService.mServices.stopAllForegroundServicesLocked( app.uid, app.getPackageName()); state.uid, state.getPackageName()); } }); } Loading @@ -2292,12 +2293,12 @@ public abstract class OomAdjuster { if (changes != 0) { if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, "Changes in " + app + ": " + changes); mProcessList.enqueueProcessChangeItemLocked(app.getPid(), app.info.uid, "Changes in " + state + ": " + changes); mProcessList.enqueueProcessChangeItemLocked(state.getPid(), state.getApplicationUid(), changes, state.getHasRepForegroundActivities()); if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, "Enqueued process change item for " + app.toShortString() + ": changes=" + changes + state.toShortString() + ": changes=" + changes + " foreground=" + state.getHasRepForegroundActivities() + " type=" + state.getAdjType() + " source=" + state.getAdjSource() + " target=" + state.getAdjTarget()); Loading @@ -2311,9 +2312,9 @@ public abstract class OomAdjuster { state.setLastCachedTime(nowElapsed); if (mService.mDeterministicUidIdle || !mService.mHandler.hasMessages(IDLE_UIDS_MSG)) { if (mLogger.shouldLog(app.uid)) { if (mLogger.shouldLog(state.uid)) { mLogger.logScheduleUidIdle2( uidRec.getUid(), app.getPid(), uidRec.getUid(), state.getPid(), mConstants.mKillBgRestrictedAndCachedIdleSettleTimeMs); } mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, Loading @@ -2322,8 +2323,8 @@ public abstract class OomAdjuster { } state.setSetCached(state.isCached()); if (((oldProcState != state.getSetProcState()) || (oldOomAdj != state.getSetAdj())) && mLogger.shouldLog(app.uid)) { mLogger.logProcStateChanged(app.uid, app.getPid(), && mLogger.shouldLog(state.uid)) { mLogger.logProcStateChanged(state.uid, state.getPid(), state.getSetProcState(), oldProcState, state.getSetAdj(), oldOomAdj); } Loading
services/core/java/com/android/server/am/ProcessRecord.java +16 −59 Original line number Diff line number Diff line Loading @@ -235,12 +235,6 @@ class ProcessRecord extends ProcessRecordInternal implements WindowProcessListen @GuardedBy("mProcLock") private boolean mUnlocked; /** * TID for RenderThread. */ @GuardedBy("mProcLock") private int mRenderThreadTid; /** * Last used compatibility mode. */ Loading Loading @@ -283,12 +277,6 @@ class ProcessRecord extends ProcessRecordInternal implements WindowProcessListen @CompositeRWLock({"mService", "mProcLock"}) private long mKillTime; /** * Process is waiting to be killed when in the bg, and reason. */ @GuardedBy("mService") private String mWaitingToKill; /** * Whether this process should be killed and removed from process list. * It is set when the package is force-stopped or the process has crashed too many times. Loading Loading @@ -516,10 +504,10 @@ class ProcessRecord extends ProcessRecordInternal implements WindowProcessListen pw.print(prefix); pw.print("startSeq="); pw.println(mStartSeq); pw.print(prefix); pw.print("mountMode="); pw.println( DebugUtils.valueToString(Zygote.class, "MOUNT_EXTERNAL_", mMountMode)); if (isKilled() || isKilledByAm() || mWaitingToKill != null) { if (isKilled() || isKilledByAm() || getWaitingToKill() != null) { pw.print(prefix); pw.print("killed="); pw.print(isKilled()); pw.print(" killedByAm="); pw.print(isKilledByAm()); pw.print(" waitingToKill="); pw.println(mWaitingToKill); pw.print(" waitingToKill="); pw.println(getWaitingToKill()); } if (mIsolatedEntryPoint != null || mIsolatedEntryPointArgs != null) { pw.print(prefix); pw.print("isolatedEntryPoint="); pw.println(mIsolatedEntryPoint); Loading Loading @@ -904,16 +892,6 @@ class ProcessRecord extends ProcessRecordInternal implements WindowProcessListen mUnlocked = unlocked; } @GuardedBy("mProcLock") int getRenderThreadTid() { return mRenderThreadTid; } @GuardedBy("mProcLock") void setRenderThreadTid(int renderThreadTid) { mRenderThreadTid = renderThreadTid; } @GuardedBy("mService") CompatibilityInfo getCompat() { return mCompat; Loading Loading @@ -1003,16 +981,6 @@ class ProcessRecord extends ProcessRecordInternal implements WindowProcessListen mKillTime = killTime; } @GuardedBy("mService") String getWaitingToKill() { return mWaitingToKill; } @GuardedBy("mService") void setWaitingToKill(String waitingToKill) { mWaitingToKill = waitingToKill; } @Override public boolean isRemoved() { return mRemoved; Loading Loading @@ -1326,31 +1294,9 @@ class ProcessRecord extends ProcessRecordInternal implements WindowProcessListen return (rss != null && rss.length > 0) ? rss[0] : 0; } @Override @GuardedBy("mService") void killLocked(String reason, @Reason int reasonCode, boolean noisy) { killLocked(reason, reasonCode, ApplicationExitInfo.SUBREASON_UNKNOWN, noisy, true); } @GuardedBy("mService") void killLocked(String reason, @Reason int reasonCode, @SubReason int subReason, boolean noisy) { killLocked(reason, reason, reasonCode, subReason, noisy, true); } @GuardedBy("mService") void killLocked(String reason, String description, @Reason int reasonCode, @SubReason int subReason, boolean noisy) { killLocked(reason, description, reasonCode, subReason, noisy, true); } @GuardedBy("mService") void killLocked(String reason, @Reason int reasonCode, @SubReason int subReason, boolean noisy, boolean asyncKPG) { killLocked(reason, reason, reasonCode, subReason, noisy, asyncKPG); } @GuardedBy("mService") void killLocked(String reason, String description, @Reason int reasonCode, public void killLocked(String reason, String description, @Reason int reasonCode, @SubReason int subReason, boolean noisy, boolean asyncKPG) { if (!isKilledByAm()) { if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) { Loading Loading @@ -1468,6 +1414,7 @@ class ProcessRecord extends ProcessRecordInternal implements WindowProcessListen return sb.toString(); } @Override public String toShortString() { final String shortStringName = mShortStringName; if (shortStringName != null) { Loading Loading @@ -1708,6 +1655,16 @@ class ProcessRecord extends ProcessRecordInternal implements WindowProcessListen } } @Override public long getNextPssTime() { return mProfile.getNextPssTime(); } @Override public void setLastCpuTime(long time) { mProfile.mLastCpuTime.set(time); } @Override public void setPendingUiClean(boolean pendingUiClean) { synchronized (mProcLock) { Loading Loading @@ -1760,7 +1717,7 @@ class ProcessRecord extends ProcessRecordInternal implements WindowProcessListen public void onStartActivity(int topProcessState, boolean setProfileProc, String packageName, long versionCode) { synchronized (mService) { mWaitingToKill = null; setWaitingToKill(null); if (setProfileProc) { synchronized (mService.mAppProfiler.mProfilerLock) { mService.mAppProfiler.setProfileProcLPf(this); Loading
services/core/java/com/android/server/am/psc/ProcessRecordInternal.java +119 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_ import android.annotation.ElapsedRealtimeLong; import android.app.ActivityManager; import android.app.ApplicationExitInfo; import android.os.Process; import android.os.SystemClock; import android.os.Trace; Loading Loading @@ -283,6 +284,95 @@ public abstract class ProcessRecordInternal { /** Returns an array of package names associated with this process. */ public abstract String[] getPackageList(); /** Returns a short string representation of the process. */ public abstract String toShortString(); /** Returns the next scheduled time for PSS collection for this process. */ public abstract long getNextPssTime(); /** Sets the last recorded CPU time for this process. */ public abstract void setLastCpuTime(long time); /** * Kills the process with the given reason code, using the provided reason string * as both the reason and a default description. The process group is killed * asynchronously. * * @param reason A string describing the reason for the kill. * @param reasonCode The reason code for the kill. * @param noisy If true, a log message will be reported. */ @GuardedBy("mServiceLock") public void killLocked(String reason, @ApplicationExitInfo.Reason int reasonCode, boolean noisy) { killLocked(reason, reasonCode, ApplicationExitInfo.SUBREASON_UNKNOWN, noisy, true); } /** * Kills the process with the given reason and subreason codes, using the provided * reason string as both the reason and a default description. The process group * is killed asynchronously. * * @param reason A string describing the reason for the kill. * @param reasonCode The reason code for the kill. * @param subReason The subreason code for the kill. * @param noisy If true, a log message will be reported. */ @GuardedBy("mServiceLock") public void killLocked(String reason, @ApplicationExitInfo.Reason int reasonCode, @ApplicationExitInfo.SubReason int subReason, boolean noisy) { killLocked(reason, reason, reasonCode, subReason, noisy, true); } /** * Kills the process with detailed reason information. The process group * is killed asynchronously. * * @param reason A string describing the high-level reason for the kill. * @param description A more detailed description of the kill reason. * @param reasonCode The reason code for the kill. * @param subReason The subreason code for the kill. * @param noisy If true, a log message will be reported. */ @GuardedBy("mServiceLock") public void killLocked(String reason, String description, @ApplicationExitInfo.Reason int reasonCode, @ApplicationExitInfo.SubReason int subReason, boolean noisy) { killLocked(reason, description, reasonCode, subReason, noisy, true); } /** * Kills the process with the given reason and subreason codes, using the provided * reason string as both the reason and a default description. Allows control over * whether the process group is killed asynchronously. * * @param reason A string describing the reason for the kill. * @param reasonCode The reason code for the kill. * @param subReason The subreason code for the kill. * @param noisy If true, a log message will be reported. * @param asyncKPG If true, kills the process group asynchronously. */ @GuardedBy("mServiceLock") public void killLocked(String reason, @ApplicationExitInfo.Reason int reasonCode, @ApplicationExitInfo.SubReason int subReason, boolean noisy, boolean asyncKPG) { killLocked(reason, reason, reasonCode, subReason, noisy, asyncKPG); } /** * Kills the process with the given reason, description, reason codes, and async KPG. * * @param reason A string describing the reason for the kill. * @param description A more detailed description of the kill reason. * @param reasonCode The reason code for the kill. * @param subReason The subreason code for the kill. * @param noisy If true, a log message will be reported. * @param asyncKPG If true, kills the process group asynchronously. */ @GuardedBy("mServiceLock") public abstract void killLocked(String reason, String description, @ApplicationExitInfo.Reason int reasonCode, @ApplicationExitInfo.SubReason int subReason, boolean noisy, boolean asyncKPG); // Enable this to trace all OomAdjuster state transitions private static final boolean TRACE_OOM_ADJ = false; Loading Loading @@ -742,6 +832,14 @@ public abstract class ProcessRecordInternal { @GuardedBy("mServiceLock") private long mFollowupUpdateUptimeMs = Long.MAX_VALUE; /** TID for RenderThread. */ @GuardedBy("mProcLock") private int mRenderThreadTid; /** Process is waiting to be killed when in the bg, and reason. */ @GuardedBy("mServiceLock") private String mWaitingToKill; // TODO(b/425766486): Change to package-private after the OomAdjusterImpl class is moved to // the psc package. public final OomAdjusterImpl.ProcessRecordNode[] mLinkedNodes = Loading Loading @@ -1721,6 +1819,27 @@ public abstract class ProcessRecordInternal { return mLastCachedTime; } @GuardedBy("mServiceLock") public String getWaitingToKill() { return mWaitingToKill; } @GuardedBy("mServiceLock") public void setWaitingToKill(String waitingToKill) { mWaitingToKill = waitingToKill; } @GuardedBy("mProcLock") public int getRenderThreadTid() { return mRenderThreadTid; } @GuardedBy("mProcLock") public void setRenderThreadTid(int renderThreadTid) { mRenderThreadTid = renderThreadTid; } /** * Lazily initiates and returns the track name for tracing. */ Loading