Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4caffe81 authored by Chih-Yu Huang's avatar Chih-Yu Huang
Browse files

am: Migrate applyOomAdjLSP() to ProcessRecordInternal

This change refactors OomAdjuster.applyOomAdjLSP() to use
ProcessRecordInternal and its methods directly, rather than
casting to ProcessRecord.

To support this, several fields (mRenderThreadTid, mWaitingToKill)
and abstract methods (killLocked, toShortString, getNextPssTime,
setLastCpuTime) were moved from ProcessRecord to
ProcessRecordInternal. The OomAdjuster.Callback interface was
also updated to delegate these functionalities, aligning with
the Process State Controller (PSC) refactoring.

Bug: 441412109
Test: m services.core
Test: atest MockingOomAdjusterTests OomAdjusterTests
Test: atest FrameworksServicesTestsRavenwood_ProcessStateController
Flag: EXEMPT PURE_REFACTOR

Change-Id: I4f48d5025e07af52b5cd122b2476d902f6aaa283
parent 8bc51c25
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -8396,7 +8396,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) {
@@ -19473,6 +19473,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);
            }
        }
    }
+49 −48
Original line number Diff line number Diff line
@@ -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
@@ -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));
    }
@@ -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());
@@ -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);
            }
@@ -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);
            }
@@ -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 {
@@ -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) {
@@ -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);
                }
            }
        }
@@ -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
@@ -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);
@@ -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());
                }
            }
@@ -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(
@@ -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);
            }
        }

@@ -2284,7 +2285,7 @@ public abstract class OomAdjuster {
                mService.mHandler.post(() -> {
                    synchronized (mService) {
                        mService.mServices.stopAllForegroundServicesLocked(
                                app.uid, app.getPackageName());
                                state.uid, state.getPackageName());
                    }
                });
            }
@@ -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());
@@ -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,
@@ -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);
        }
+16 −59
Original line number Diff line number Diff line
@@ -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.
     */
@@ -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.
@@ -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);
@@ -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;
@@ -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;
@@ -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)) {
@@ -1468,6 +1414,7 @@ class ProcessRecord extends ProcessRecordInternal implements WindowProcessListen
        return sb.toString();
    }

    @Override
    public String toShortString() {
        final String shortStringName = mShortStringName;
        if (shortStringName != null) {
@@ -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) {
@@ -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);
+119 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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;

@@ -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 =
@@ -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.
     */