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

Commit 052e3149 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Work on issue #70859548: Reduce amount of time spent collecting pss data

This slightly reduces the frequency we collect pss data, adjusting
some timings and adding back separate timings for when the device
is asleep.  (Though note that the "same asleep" timings are currently
the same as "same awake," because those are already pretty infrequent.)

Also add some statistics to procstats to keep track of how many
pss samples have been taken, generally why, and how long they took

Bug: 70859548
Test: manual
Change-Id: If3c6cbd4ab045d2e4c00b48fe4257c4ec5ae3f33
parent 107f7cc4
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -153,7 +153,6 @@ public final class ProcessState {
    private int mNumActiveServices;
    private int mNumStartedServices;

    private int mNumExcessiveWake;
    private int mNumExcessiveCpu;

    private int mNumCachedKill;
@@ -470,9 +469,23 @@ public final class ProcessState {
        }
    }

    public void addPss(long pss, long uss, boolean always,
    public void addPss(long pss, long uss, boolean always, int type, long duration,
            ArrayMap<String, ProcessStateHolder> pkgList) {
        ensureNotDead();
        switch (type) {
            case ProcessStats.ADD_PSS_INTERNAL:
                mStats.mInternalPssCount++;
                mStats.mInternalPssTime += duration;
                break;
            case ProcessStats.ADD_PSS_EXTERNAL:
                mStats.mExternalPssCount++;
                mStats.mExternalPssTime += duration;
                break;
            case ProcessStats.ADD_PSS_EXTERNAL_SLOW:
                mStats.mExternalSlowPssCount++;
                mStats.mExternalSlowPssTime += duration;
                break;
        }
        if (!always) {
            if (mLastPssState == mCurState && SystemClock.uptimeMillis()
                    < (mLastPssTime+(30*1000))) {
+64 −1
Original line number Diff line number Diff line
@@ -134,6 +134,10 @@ public final class ProcessStats implements Parcelable {
    public static final int FLAG_SHUTDOWN = 1<<1;
    public static final int FLAG_SYSPROPS = 1<<2;

    public static final int ADD_PSS_INTERNAL = 0;
    public static final int ADD_PSS_EXTERNAL = 1;
    public static final int ADD_PSS_EXTERNAL_SLOW = 2;

    public static final int[] ALL_MEM_ADJ = new int[] { ADJ_MEM_FACTOR_NORMAL,
            ADJ_MEM_FACTOR_MODERATE, ADJ_MEM_FACTOR_LOW, ADJ_MEM_FACTOR_CRITICAL };

@@ -158,7 +162,7 @@ public final class ProcessStats implements Parcelable {
    };

    // Current version of the parcel format.
    private static final int PARCEL_VERSION = 23;
    private static final int PARCEL_VERSION = 24;
    // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
    private static final int MAGIC = 0x50535454;

@@ -183,6 +187,18 @@ public final class ProcessStats implements Parcelable {

    boolean mHasSwappedOutPss;

    // Count and total time expended doing "quick" pss computations for internal use.
    public long mInternalPssCount;
    public long mInternalPssTime;

    // Count and total time expended doing "quick" pss computations due to external requests.
    public long mExternalPssCount;
    public long mExternalPssTime;

    // Count and total time expended doing full/slow pss computations due to external requests.
    public long mExternalSlowPssCount;
    public long mExternalSlowPssTime;

    public final SparseMappingTable mTableData = new SparseMappingTable();

    public final long[] mSysMemUsageArgs = new long[SYS_MEM_USAGE_COUNT];
@@ -302,6 +318,13 @@ public final class ProcessStats implements Parcelable {
        mTimePeriodEndRealtime += other.mTimePeriodEndRealtime - other.mTimePeriodStartRealtime;
        mTimePeriodEndUptime += other.mTimePeriodEndUptime - other.mTimePeriodStartUptime;

        mInternalPssCount += other.mInternalPssCount;
        mInternalPssTime += other.mInternalPssTime;
        mExternalPssCount += other.mExternalPssCount;
        mExternalPssTime += other.mExternalPssTime;
        mExternalSlowPssCount += other.mExternalSlowPssCount;
        mExternalSlowPssTime += other.mExternalSlowPssTime;

        mHasSwappedOutPss |= other.mHasSwappedOutPss;
    }

@@ -500,6 +523,12 @@ public final class ProcessStats implements Parcelable {
        buildTimePeriodStartClockStr();
        mTimePeriodStartRealtime = mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
        mTimePeriodStartUptime = mTimePeriodEndUptime = SystemClock.uptimeMillis();
        mInternalPssCount = 0;
        mInternalPssTime = 0;
        mExternalPssCount = 0;
        mExternalPssTime = 0;
        mExternalSlowPssCount = 0;
        mExternalSlowPssTime = 0;
        mTableData.reset();
        Arrays.fill(mMemFactorDurations, 0);
        mSysMemUsage.resetTable();
@@ -760,6 +789,12 @@ public final class ProcessStats implements Parcelable {
        out.writeLong(mTimePeriodEndRealtime);
        out.writeLong(mTimePeriodStartUptime);
        out.writeLong(mTimePeriodEndUptime);
        out.writeLong(mInternalPssCount);
        out.writeLong(mInternalPssTime);
        out.writeLong(mExternalPssCount);
        out.writeLong(mExternalPssTime);
        out.writeLong(mExternalSlowPssCount);
        out.writeLong(mExternalSlowPssTime);
        out.writeString(mRuntime);
        out.writeInt(mHasSwappedOutPss ? 1 : 0);
        out.writeInt(mFlags);
@@ -928,6 +963,12 @@ public final class ProcessStats implements Parcelable {
        mTimePeriodEndRealtime = in.readLong();
        mTimePeriodStartUptime = in.readLong();
        mTimePeriodEndUptime = in.readLong();
        mInternalPssCount = in.readLong();
        mInternalPssTime = in.readLong();
        mExternalPssCount = in.readLong();
        mExternalPssTime = in.readLong();
        mExternalSlowPssCount = in.readLong();
        mExternalSlowPssTime = in.readLong();
        mRuntime = in.readString();
        mHasSwappedOutPss = in.readInt() != 0;
        mFlags = in.readInt();
@@ -1484,9 +1525,31 @@ public final class ProcessStats implements Parcelable {
                totalMem.processStateWeight[STATE_SERVICE_RESTARTING], totalMem.totalTime, totalPss,
                totalMem.processStateSamples[STATE_SERVICE_RESTARTING]);
        pw.println();
        pw.println("PSS collection stats:");
        pw.print("  Internal: ");
        pw.print(mInternalPssCount);
        pw.print("x over ");
        TimeUtils.formatDuration(mInternalPssTime, pw);
        pw.println();
        pw.print("  External: ");
        pw.print(mExternalPssCount);
        pw.print("x over ");
        TimeUtils.formatDuration(mExternalPssTime, pw);
        pw.println();
        pw.print("  External Slow: ");
        pw.print(mExternalSlowPssCount);
        pw.print("x over ");
        TimeUtils.formatDuration(mExternalSlowPssTime, pw);
        pw.println();
        pw.println();
        pw.print("          Start time: ");
        pw.print(DateFormat.format("yyyy-MM-dd HH:mm:ss", mTimePeriodStartClock));
        pw.println();
        pw.print("        Total uptime: ");
        TimeUtils.formatDuration(
                (mRunning ? SystemClock.uptimeMillis() : mTimePeriodEndUptime)
                        - mTimePeriodStartUptime, pw);
        pw.println();
        pw.print("  Total elapsed time: ");
        TimeUtils.formatDuration(
                (mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime)
+2 −2
Original line number Diff line number Diff line
@@ -77,8 +77,8 @@ final class ActivityManagerConstants extends ContentObserver {
    private static final long DEFAULT_CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
    private static final long DEFAULT_GC_TIMEOUT = 5*1000;
    private static final long DEFAULT_GC_MIN_INTERVAL = 60*1000;
    private static final long DEFAULT_FULL_PSS_MIN_INTERVAL = 10*60*1000;
    private static final long DEFAULT_FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
    private static final long DEFAULT_FULL_PSS_MIN_INTERVAL = 20*60*1000;
    private static final long DEFAULT_FULL_PSS_LOWERED_INTERVAL = 5*60*1000;
    private static final long DEFAULT_POWER_CHECK_INTERVAL = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    private static final int DEFAULT_POWER_CHECK_MAX_CPU_1 = 25;
    private static final int DEFAULT_POWER_CHECK_MAX_CPU_2 = 25;
+41 −8
Original line number Diff line number Diff line
@@ -2521,13 +2521,15 @@ public class ActivityManagerService extends IActivityManager.Stub
                        }
                    }
                    if (proc != null) {
                        long startTime = SystemClock.currentThreadTimeMillis();
                        long pss = Debug.getPss(pid, tmp, null);
                        long endTime = SystemClock.currentThreadTimeMillis();
                        synchronized (ActivityManagerService.this) {
                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
                                num++;
                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
                                        SystemClock.uptimeMillis());
                                        endTime-startTime, SystemClock.uptimeMillis());
                            }
                        }
                    }
@@ -6539,13 +6541,17 @@ public class ActivityManagerService extends IActivityManager.Stub
                }
            }
            infos[i] = new Debug.MemoryInfo();
            long startTime = SystemClock.currentThreadTimeMillis();
            Debug.getMemoryInfo(pids[i], infos[i]);
            long endTime = SystemClock.currentThreadTimeMillis();
            if (proc != null) {
                synchronized (this) {
                    if (proc.thread != null && proc.setAdj == oomAdj) {
                        // Record this for posterity if the process has been stable.
                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
                                infos[i].getTotalUss(), false, proc.pkgList);
                                infos[i].getTotalUss(), false,
                                ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime-startTime,
                                proc.pkgList);
                    }
                }
            }
@@ -6567,12 +6573,15 @@ public class ActivityManagerService extends IActivityManager.Stub
                }
            }
            long[] tmpUss = new long[1];
            long startTime = SystemClock.currentThreadTimeMillis();
            pss[i] = Debug.getPss(pids[i], tmpUss, null);
            long endTime = SystemClock.currentThreadTimeMillis();
            if (proc != null) {
                synchronized (this) {
                    if (proc.thread != null && proc.setAdj == oomAdj) {
                        // Record this for posterity if the process has been stable.
                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false,
                                ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList);
                    }
                }
            }
@@ -17647,11 +17656,20 @@ public class ActivityManagerService extends IActivityManager.Stub
                if (mi == null) {
                    mi = new Debug.MemoryInfo();
                }
                final int reportType;
                final long startTime;
                final long endTime;
                if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
                    reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
                    startTime = SystemClock.currentThreadTimeMillis();
                    Debug.getMemoryInfo(pid, mi);
                    endTime = SystemClock.currentThreadTimeMillis();
                    hasSwapPss = mi.hasSwappedOutPss;
                } else {
                    reportType = ProcessStats.ADD_PSS_EXTERNAL;
                    startTime = SystemClock.currentThreadTimeMillis();
                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
                    endTime = SystemClock.currentThreadTimeMillis();
                    mi.dalvikPrivateDirty = (int)tmpLong[0];
                }
                if (opts.dumpDetails) {
@@ -17694,7 +17712,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                synchronized (this) {
                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
                        // Record this for posterity if the process has been stable.
                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true,
                                reportType, endTime-startTime, r.pkgList);
                    }
                }
@@ -18137,11 +18156,20 @@ public class ActivityManagerService extends IActivityManager.Stub
            if (mi == null) {
                mi = new Debug.MemoryInfo();
            }
            final int reportType;
            final long startTime;
            final long endTime;
            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
                reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
                startTime = SystemClock.currentThreadTimeMillis();
                Debug.getMemoryInfo(pid, mi);
                endTime = SystemClock.currentThreadTimeMillis();
                hasSwapPss = mi.hasSwappedOutPss;
            } else {
                reportType = ProcessStats.ADD_PSS_EXTERNAL;
                startTime = SystemClock.currentThreadTimeMillis();
                mi.dalvikPss = (int) Debug.getPss(pid, tmpLong, null);
                endTime = SystemClock.currentThreadTimeMillis();
                mi.dalvikPrivateDirty = (int) tmpLong[0];
            }
            if (opts.dumpDetails) {
@@ -18180,7 +18208,8 @@ public class ActivityManagerService extends IActivityManager.Stub
            synchronized (this) {
                if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
                    // Record this for posterity if the process has been stable.
                    r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
                    r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true,
                            reportType, endTime-startTime, r.pkgList);
                }
            }
@@ -22444,11 +22473,12 @@ public class ActivityManagerService extends IActivityManager.Stub
     * Record new PSS sample for a process.
     */
    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
            long now) {
            long pssDuration, long now) {
        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
                swapPss * 1024);
        proc.lastPssTime = now;
        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
        proc.baseProcessTracker.addPss(pss, uss, true, ProcessStats.ADD_PSS_INTERNAL,
                pssDuration, proc.pkgList);
        if (DEBUG_PSS) Slog.d(TAG_PSS,
                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
                + " state=" + ProcessList.makeProcStateString(procState));
@@ -22943,8 +22973,11 @@ public class ActivityManagerService extends IActivityManager.Stub
                // the data right when a process is transitioning between process
                // states, which well tend to give noisy data.
                long start = SystemClock.uptimeMillis();
                long startTime = SystemClock.currentThreadTimeMillis();
                long pss = Debug.getPss(app.pid, mTmpLong, null);
                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
                long endTime = SystemClock.currentThreadTimeMillis();
                recordPssSampleLocked(app, app.curProcState, pss, endTime-startTime,
                        mTmpLong[0], mTmpLong[1], now);
                mPendingPssProcesses.remove(app);
                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
                        + " to " + app.curProcState + ": "
+68 −9
Original line number Diff line number Diff line
@@ -432,13 +432,13 @@ public final class ProcessList {
    public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000;

    // The maximum amount of time we want to go between PSS collections.
    public static final int PSS_MAX_INTERVAL = 30*60*1000;
    public static final int PSS_MAX_INTERVAL = 40*60*1000;

    // The minimum amount of time between successive PSS requests for *all* processes.
    public static final int PSS_ALL_INTERVAL = 10*60*1000;
    public static final int PSS_ALL_INTERVAL = 20*60*1000;

    // The minimum amount of time between successive PSS requests for a process.
    private static final int PSS_SHORT_INTERVAL = 2*60*1000;
    // The amount of time until PSS when a persistent process first appears.
    private static final int PSS_FIRST_PERSISTENT_INTERVAL = 30*1000;

    // The amount of time until PSS when a process first becomes top.
    private static final int PSS_FIRST_TOP_INTERVAL = 10*1000;
@@ -449,6 +449,9 @@ public final class ProcessList {
    // The amount of time until PSS when a process first becomes cached.
    private static final int PSS_FIRST_CACHED_INTERVAL = 30*1000;

    // The amount of time until PSS when the top process stays in the same state.
    private static final int PSS_SAME_TOP_INTERVAL = 5*60*1000;

    // The amount of time until PSS when an important process stays in the same state.
    private static final int PSS_SAME_IMPORTANT_INTERVAL = 15*60*1000;

@@ -458,6 +461,18 @@ public final class ProcessList {
    // The amount of time until PSS when a cached process stays in the same state.
    private static final int PSS_SAME_CACHED_INTERVAL = 30*60*1000;

    // The amount of time until PSS when a persistent process first appears.
    private static final int PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL = 1*60*1000;

    // The amount of time until PSS when a process first becomes top.
    private static final int PSS_FIRST_ASLEEP_TOP_INTERVAL = 20*1000;

    // The amount of time until PSS when a process first goes into the background.
    private static final int PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL = 30*1000;

    // The amount of time until PSS when a process first becomes cached.
    private static final int PSS_FIRST_ASLEEP_CACHED_INTERVAL = 1*60*1000;

    // The minimum time interval after a state change it is safe to collect PSS.
    public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000;

@@ -502,8 +517,8 @@ public final class ProcessList {
    };

    private static final long[] sFirstAwakePssTimes = new long[] {
        PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_PERSISTENT
        PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_PERSISTENT_UI
        PSS_FIRST_PERSISTENT_INTERVAL,  // ActivityManager.PROCESS_STATE_PERSISTENT
        PSS_FIRST_PERSISTENT_INTERVAL,  // ActivityManager.PROCESS_STATE_PERSISTENT_UI
        PSS_FIRST_TOP_INTERVAL,         // ActivityManager.PROCESS_STATE_TOP
        PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
        PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
@@ -526,7 +541,51 @@ public final class ProcessList {
    private static final long[] sSameAwakePssTimes = new long[] {
        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_PERSISTENT
        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_PERSISTENT_UI
        PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_TOP
        PSS_SAME_TOP_INTERVAL,          // ActivityManager.PROCESS_STATE_TOP
        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_BACKUP
        PSS_SAME_SERVICE_INTERVAL,      // ActivityManager.PROCESS_STATE_SERVICE
        PSS_SAME_SERVICE_INTERVAL,      // ActivityManager.PROCESS_STATE_RECEIVER
        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_TOP_SLEEPING
        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_HOME
        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_RECENT
        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_EMPTY
    };

    private static final long[] sFirstAsleepPssTimes = new long[] {
        PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL,   // ActivityManager.PROCESS_STATE_PERSISTENT
        PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL,   // ActivityManager.PROCESS_STATE_PERSISTENT_UI
        PSS_FIRST_ASLEEP_TOP_INTERVAL,          // ActivityManager.PROCESS_STATE_TOP
        PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
        PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
        PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
        PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
        PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
        PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // ActivityManager.PROCESS_STATE_BACKUP
        PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL,   // ActivityManager.PROCESS_STATE_SERVICE
        PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_RECEIVER
        PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_TOP_SLEEPING
        PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
        PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_HOME
        PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
        PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
        PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
        PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_RECENT
        PSS_FIRST_ASLEEP_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_EMPTY
    };

    private static final long[] sSameAsleepPssTimes = new long[] {
        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_PERSISTENT
        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_PERSISTENT_UI
        PSS_SAME_TOP_INTERVAL,          // ActivityManager.PROCESS_STATE_TOP
        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
@@ -604,8 +663,8 @@ public final class ProcessList {
                        ? sTestFirstPssTimes
                        : sTestSamePssTimes)
                : (first
                        ? sFirstAwakePssTimes
                        : sSameAwakePssTimes);
                        ? (sleeping ? sFirstAsleepPssTimes : sFirstAwakePssTimes)
                        : (sleeping ? sSameAsleepPssTimes : sSameAwakePssTimes));
        return now + table[procState];
    }