Loading core/java/com/android/internal/app/procstats/AssociationState.java +230 −38 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ public final class AssociationState { private final ProcessStats.PackageState mPackageState; private final String mProcessName; private final String mName; private final DurationsTable mDurations; public final class SourceState { final SourceKey mKey; Loading @@ -49,8 +48,10 @@ public final class AssociationState { long mDuration; long mTrackingUptime; int mActiveCount; int mActiveProcState = ProcessStats.STATE_NOTHING; long mActiveStartUptime; long mActiveDuration; DurationsTable mDurations; SourceState(SourceKey key) { mKey = key; Loading @@ -77,13 +78,15 @@ public final class AssociationState { mProcState = procState; } if (procState < ProcessStats.STATE_HOME) { // If the proc state has become better than cached, then we want to // start tracking it to count when it is actually active. If it drops // down to cached, we will clean it up when we later evaluate all currently // tracked associations in ProcessStats.updateTrackingAssociationsLocked(). if (!mInTrackingList) { mInTrackingList = true; mTrackingUptime = now; mProcessStats.mTrackingAssociations.add(this); } } else { stopTracking(now); } } Loading @@ -102,6 +105,22 @@ public final class AssociationState { mActiveStartUptime = now; mActiveCount++; } if (mActiveProcState != mProcState) { if (mActiveProcState != ProcessStats.STATE_NOTHING) { // Currently active proc state changed, need to store the duration // so far and switch tracking to the new proc state. final long duration = mActiveDuration + now - mActiveStartUptime; if (duration != 0) { if (mDurations == null) { makeDurations(); } mDurations.addDuration(mActiveProcState, duration); mActiveDuration = 0; } mActiveStartUptime = now; } mActiveProcState = mProcState; } } else { Slog.wtf(TAG, "startActive while not tracking: " + this); } Loading @@ -112,15 +131,25 @@ public final class AssociationState { if (!mInTrackingList) { Slog.wtf(TAG, "stopActive while not tracking: " + this); } mActiveDuration += now - mActiveStartUptime; final long duration = mActiveDuration + now - mActiveStartUptime; if (mDurations != null) { mDurations.addDuration(mActiveProcState, duration); } else { mActiveDuration = duration; } mActiveStartUptime = 0; } } void makeDurations() { mDurations = new DurationsTable(mProcessStats.mTableData); } void stopTracking(long now) { stopActive(now); if (mInTrackingList) { mInTrackingList = false; mProcState = ProcessStats.STATE_NOTHING; // Do a manual search for where to remove, since these objects will typically // be towards the end of the array. final ArrayList<SourceState> list = mProcessStats.mTrackingAssociations; Loading Loading @@ -207,7 +236,6 @@ public final class AssociationState { mPackageState = packageState; mName = name; mProcessName = processName; mDurations = new DurationsTable(processStats.mTableData); mProc = proc; } Loading Loading @@ -254,7 +282,6 @@ public final class AssociationState { } public void add(AssociationState other) { mDurations.addDurations(other.mDurations); for (int isrc = other.mSources.size() - 1; isrc >= 0; isrc--) { final SourceKey key = other.mSources.keyAt(isrc); final SourceState otherSrc = other.mSources.valueAt(isrc); Loading @@ -266,7 +293,48 @@ public final class AssociationState { mySrc.mCount += otherSrc.mCount; mySrc.mDuration += otherSrc.mDuration; mySrc.mActiveCount += otherSrc.mActiveCount; mySrc.mActiveDuration += otherSrc.mActiveDuration; if (otherSrc.mActiveDuration != 0 || otherSrc.mDurations != null) { // Only need to do anything if the other one has some duration data. if (mySrc.mDurations != null) { // If the target already has multiple durations, just add in whatever // we have in the other. if (otherSrc.mDurations != null) { mySrc.mDurations.addDurations(otherSrc.mDurations); } else { mySrc.mDurations.addDuration(otherSrc.mActiveProcState, otherSrc.mActiveDuration); } } else if (otherSrc.mDurations != null) { // The other one has multiple durations, but we don't. Expand to // multiple durations and copy over. mySrc.makeDurations(); mySrc.mDurations.addDurations(otherSrc.mDurations); if (mySrc.mActiveDuration != 0) { mySrc.mDurations.addDuration(mySrc.mActiveProcState, mySrc.mActiveDuration); mySrc.mActiveDuration = 0; mySrc.mActiveProcState = ProcessStats.STATE_NOTHING; } } else if (mySrc.mActiveDuration != 0) { // Both have a single inline duration... we can either add them together, // or need to expand to multiple durations. if (mySrc.mActiveProcState == otherSrc.mActiveProcState) { mySrc.mDuration += otherSrc.mDuration; } else { // The two have durations with different proc states, need to turn // in to multiple durations. mySrc.makeDurations(); mySrc.mDurations.addDuration(mySrc.mActiveProcState, mySrc.mActiveDuration); mySrc.mDurations.addDuration(otherSrc.mActiveProcState, otherSrc.mActiveDuration); mySrc.mActiveDuration = 0; mySrc.mActiveProcState = ProcessStats.STATE_NOTHING; } } else { // The other one has a duration, and we know the target doesn't. Copy over. mySrc.mActiveProcState = otherSrc.mActiveProcState; mySrc.mActiveDuration = otherSrc.mActiveDuration; } } } } Loading @@ -275,7 +343,6 @@ public final class AssociationState { } public void resetSafely(long now) { mDurations.resetTable(); if (!isInUse()) { mSources.clear(); } else { Loading @@ -293,6 +360,7 @@ public final class AssociationState { src.mActiveCount = 0; } src.mActiveDuration = 0; src.mDurations = null; } else { mSources.removeAt(isrc); } Loading @@ -301,7 +369,6 @@ public final class AssociationState { } public void writeToParcel(ProcessStats stats, Parcel out, long nowUptime) { mDurations.writeToParcel(out); final int NSRC = mSources.size(); out.writeInt(NSRC); for (int isrc = 0; isrc < NSRC; isrc++) { Loading @@ -312,18 +379,22 @@ public final class AssociationState { out.writeInt(src.mCount); out.writeLong(src.mDuration); out.writeInt(src.mActiveCount); if (src.mDurations != null) { out.writeInt(1); src.mDurations.writeToParcel(out); } else { out.writeInt(0); out.writeInt(src.mActiveProcState); out.writeLong(src.mActiveDuration); } } } /** * Returns non-null if all else fine, else a String that describes the error that * caused it to fail. */ public String readFromParcel(ProcessStats stats, Parcel in, int parcelVersion) { if (!mDurations.readFromParcel(in)) { return "Duration table corrupt"; } final int NSRC = in.readInt(); if (NSRC < 0 || NSRC > 100000) { return "Association with bad src count: " + NSRC; Loading @@ -336,7 +407,15 @@ public final class AssociationState { src.mCount = in.readInt(); src.mDuration = in.readLong(); src.mActiveCount = in.readInt(); if (in.readInt() != 0) { src.makeDurations(); if (!src.mDurations.readFromParcel(in)) { return "Duration table corrupt: " + key + " <- " + src; } } else { src.mActiveProcState = in.readInt(); src.mActiveDuration = in.readLong(); } mSources.put(key, src); } return null; Loading @@ -351,7 +430,12 @@ public final class AssociationState { src.mStartUptime = nowUptime; } if (src.mActiveStartUptime > 0) { src.mActiveDuration += nowUptime - src.mActiveStartUptime; final long duration = src.mActiveDuration + nowUptime - src.mActiveStartUptime; if (src.mDurations != null) { src.mDurations.addDuration(src.mActiveProcState, duration); } else { src.mActiveDuration = duration; } src.mActiveStartUptime = nowUptime; } } Loading @@ -359,7 +443,7 @@ public final class AssociationState { } public void dumpStats(PrintWriter pw, String prefix, String prefixInner, String headerPrefix, long now, long totalTime, boolean dumpSummary, boolean dumpAll) { long now, long totalTime, boolean dumpDetails, boolean dumpAll) { if (dumpAll) { pw.print(prefix); pw.print("mNumActive="); Loading @@ -376,18 +460,18 @@ public final class AssociationState { UserHandle.formatUid(pw, key.mUid); pw.println(":"); pw.print(prefixInner); pw.print(" Count "); pw.print(" Total count "); pw.print(src.mCount); long duration = src.mDuration; if (src.mNesting > 0) { duration += now - src.mStartUptime; } if (dumpAll) { pw.print(" / Duration "); pw.print(": Duration "); TimeUtils.formatDuration(duration, pw); pw.print(" / "); } else { pw.print(" / time "); pw.print(": time "); } DumpUtils.printPercent(pw, (double)duration/(double)totalTime); if (src.mNesting > 0) { Loading @@ -401,20 +485,53 @@ public final class AssociationState { pw.print(")"); } pw.println(); if (src.mActiveCount > 0) { if (src.mActiveCount > 0 || src.mDurations != null || src.mActiveDuration != 0 || src.mActiveStartUptime != 0) { pw.print(prefixInner); pw.print(" Active count "); pw.print(src.mActiveCount); duration = src.mActiveDuration; if (src.mActiveStartUptime > 0) { duration += now - src.mActiveStartUptime; if (dumpDetails) { if (dumpAll) { pw.print(src.mDurations != null ? " (multi-field)" : " (inline)"); } pw.println(":"); dumpTime(pw, prefixInner, src, totalTime, now, dumpDetails, dumpAll); } else { pw.print(": "); dumpActiveDurationSummary(pw, src, totalTime, now, dumpAll); pw.println(); } } if (dumpAll) { pw.print(" / Duration "); if (src.mInTrackingList) { pw.print(prefixInner); pw.print(" mInTrackingList="); pw.println(src.mInTrackingList); } if (src.mProcState != ProcessStats.STATE_NOTHING) { pw.print(prefixInner); pw.print(" mProcState="); pw.print(DumpUtils.STATE_NAMES[src.mProcState]); pw.print(" mProcStateSeq="); pw.println(src.mProcStateSeq); } } } } void dumpActiveDurationSummary(PrintWriter pw, final SourceState src, long totalTime, long now, boolean dumpAll) { long duration = dumpTime(null, null, src, totalTime, now, false, false); final boolean isRunning = duration < 0; if (isRunning) { duration = -duration; } if (dumpAll) { pw.print("Duration "); TimeUtils.formatDuration(duration, pw); pw.print(" / "); } else { pw.print(" / time "); pw.print("time "); } DumpUtils.printPercent(pw, (double) duration / (double) totalTime); if (src.mActiveStartUptime > 0) { Loading @@ -422,7 +539,64 @@ public final class AssociationState { } pw.println(); } long dumpTime(PrintWriter pw, String prefix, final SourceState src, long overallTime, long now, boolean dumpDetails, boolean dumpAll) { long totalTime = 0; boolean isRunning = false; for (int iprocstate = 0; iprocstate < ProcessStats.STATE_COUNT; iprocstate++) { long time; if (src.mDurations != null) { time = src.mDurations.getValueForId((byte)iprocstate); } else { time = src.mActiveProcState == iprocstate ? src.mDuration : 0; } final String running; if (src.mActiveStartUptime != 0 && src.mActiveProcState == iprocstate) { running = " (running)"; isRunning = true; time += now - src.mActiveStartUptime; } else { running = null; } if (time != 0) { if (pw != null) { pw.print(prefix); pw.print(" "); pw.print(DumpUtils.STATE_LABELS[iprocstate]); pw.print(": "); if (dumpAll) { pw.print("Duration "); TimeUtils.formatDuration(time, pw); pw.print(" / "); } else { pw.print("time "); } DumpUtils.printPercent(pw, (double) time / (double) overallTime); if (running != null) { pw.print(running); } pw.println(); } totalTime += time; } } if (totalTime != 0 && pw != null) { pw.print(prefix); pw.print(" "); pw.print(DumpUtils.STATE_LABEL_TOTAL); pw.print(": "); if (dumpAll) { pw.print("Duration "); TimeUtils.formatDuration(totalTime, pw); pw.print(" / "); } else { pw.print("time "); } DumpUtils.printPercent(pw, (double) totalTime / (double) overallTime); pw.println(); } return isRunning ? -totalTime : totalTime; } public void dumpTimesCheckin(PrintWriter pw, String pkgName, int uid, long vers, Loading Loading @@ -454,12 +628,30 @@ public final class AssociationState { pw.print(duration); pw.print(","); pw.print(src.mActiveCount); duration = src.mActiveDuration; if (src.mActiveStartUptime > 0) { duration += now - src.mActiveStartUptime; final long timeNow = src.mActiveStartUptime != 0 ? (now-src.mActiveStartUptime) : 0; if (src.mDurations != null) { final int N = src.mDurations.getKeyCount(); for (int i=0; i<N; i++) { final int dkey = src.mDurations.getKeyAt(i); duration = src.mDurations.getValue(dkey); if (dkey == src.mActiveProcState) { duration += timeNow; } final int procState = SparseMappingTable.getIdFromKey(dkey); pw.print(","); DumpUtils.printArrayEntry(pw, DumpUtils.STATE_TAGS, procState, 1); pw.print(':'); pw.print(duration); } } else { duration = src.mActiveDuration + timeNow; if (duration != 0) { pw.print(","); DumpUtils.printArrayEntry(pw, DumpUtils.STATE_TAGS, src.mActiveProcState, 1); pw.print(':'); pw.print(duration); } } pw.println(); } } Loading core/java/com/android/internal/app/procstats/DumpUtils.java +66 −45 Original line number Diff line number Diff line Loading @@ -48,6 +48,9 @@ import java.util.Objects; */ public final class DumpUtils { public static final String[] STATE_NAMES; public static final String[] STATE_LABELS; public static final String STATE_LABEL_TOTAL; public static final String STATE_LABEL_CACHED; public static final String[] STATE_NAMES_CSV; static final String[] STATE_TAGS; static final int[] STATE_PROTO_ENUMS; Loading @@ -70,6 +73,24 @@ public final class DumpUtils { STATE_NAMES[STATE_CACHED_ACTIVITY_CLIENT] = "CchCAct"; STATE_NAMES[STATE_CACHED_EMPTY] = "CchEmty"; STATE_LABELS = new String[STATE_COUNT]; STATE_LABELS[STATE_PERSISTENT] = "Persistent"; STATE_LABELS[STATE_TOP] = " Top"; STATE_LABELS[STATE_IMPORTANT_FOREGROUND] = " Imp Fg"; STATE_LABELS[STATE_IMPORTANT_BACKGROUND] = " Imp Bg"; STATE_LABELS[STATE_BACKUP] = " Backup"; STATE_LABELS[STATE_SERVICE] = " Service"; STATE_LABELS[STATE_SERVICE_RESTARTING] = "Service Rs"; STATE_LABELS[STATE_RECEIVER] = " Receiver"; STATE_LABELS[STATE_HEAVY_WEIGHT] = " Heavy Wgt"; STATE_LABELS[STATE_HOME] = " (Home)"; STATE_LABELS[STATE_LAST_ACTIVITY] = "(Last Act)"; STATE_LABELS[STATE_CACHED_ACTIVITY] = " (Cch Act)"; STATE_LABELS[STATE_CACHED_ACTIVITY_CLIENT] = "(Cch CAct)"; STATE_LABELS[STATE_CACHED_EMPTY] = "(Cch Emty)"; STATE_LABEL_CACHED = " (Cached)"; STATE_LABEL_TOTAL = " TOTAL"; STATE_NAMES_CSV = new String[STATE_COUNT]; STATE_NAMES_CSV[STATE_PERSISTENT] = "pers"; STATE_NAMES_CSV[STATE_TOP] = "top"; Loading core/java/com/android/internal/app/procstats/ProcessState.java +36 −32 File changed.Preview size limit exceeded, changes collapsed. Show changes core/java/com/android/internal/app/procstats/ProcessStats.java +11 −20 Original line number Diff line number Diff line Loading @@ -158,7 +158,7 @@ public final class ProcessStats implements Parcelable { }; // Current version of the parcel format. private static final int PARCEL_VERSION = 32; private static final int PARCEL_VERSION = 33; // In-memory Parcel magic number, used to detect attempts to unmarshall bad data private static final int MAGIC = 0x50535454; Loading Loading @@ -1380,9 +1380,13 @@ public final class ProcessStats implements Parcelable { final int NUM = mTrackingAssociations.size(); for (int i = NUM - 1; i >= 0; i--) { final AssociationState.SourceState act = mTrackingAssociations.get(i); if (act.mProcStateSeq != curSeq) { if (act.mProcStateSeq != curSeq || act.mProcState >= ProcessStats.STATE_HOME) { // If this association did not get touched the last time we computed // process states, or its state ended up down in cached, then we no // longer have a reason to track it at all. act.stopActive(now); act.mInTrackingList = false; act.mProcState = STATE_NOTHING; act.mProcState = ProcessStats.STATE_NOTHING; mTrackingAssociations.remove(i); } else { final ProcessState proc = act.getAssociationState().getProcess(); Loading @@ -1407,7 +1411,7 @@ public final class ProcessStats implements Parcelable { } public void dumpLocked(PrintWriter pw, String reqPackage, long now, boolean dumpSummary, boolean dumpAll, boolean activeOnly) { boolean dumpDetails, boolean dumpAll, boolean activeOnly) { long totalTime = DumpUtils.dumpSingleTime(null, null, mMemFactorDurations, mMemFactor, mStartTime, now); boolean sepNeeded = false; Loading Loading @@ -1538,7 +1542,7 @@ public final class ProcessStats implements Parcelable { pw.println(":"); pw.print(" Process: "); pw.println(asc.getProcessName()); asc.dumpStats(pw, " ", " ", " ", now, totalTime, dumpSummary, dumpAll); now, totalTime, dumpDetails, dumpAll); } } } Loading Loading @@ -1632,21 +1636,8 @@ public final class ProcessStats implements Parcelable { if (src.mActiveCount > 0) { pw.print(" Active count "); pw.print(src.mActiveCount); long duration = src.mActiveDuration; if (src.mActiveStartUptime > 0) { duration += now - src.mActiveStartUptime; } if (dumpAll) { pw.print(" / Duration "); TimeUtils.formatDuration(duration, pw); pw.print(" / "); } else { pw.print(" / time "); } DumpUtils.printPercent(pw, (double)duration/(double)totalTime); if (src.mActiveStartUptime > 0) { pw.print(" (running)"); } pw.print(": "); asc.dumpActiveDurationSummary(pw, src, totalTime, now, dumpAll); pw.println(); } } Loading services/core/java/com/android/server/am/ProcessStatsService.java +7 −6 Original line number Diff line number Diff line Loading @@ -612,7 +612,8 @@ public final class ProcessStatsService extends IProcessStats.Stub { stats.dumpCheckinLocked(pw, reqPackage); } else { if (dumpDetails || dumpFullDetails) { stats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpAll, activeOnly); stats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpDetails, dumpAll, activeOnly); } else { stats.dumpSummaryLocked(pw, reqPackage, now, activeOnly); } Loading Loading @@ -974,8 +975,8 @@ public final class ProcessStatsService extends IProcessStats.Stub { if (checkedIn) pw.print(" (checked in)"); pw.println(":"); if (dumpDetails || dumpFullDetails) { processStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpAll, activeOnly); processStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpDetails, dumpAll, activeOnly); if (dumpAll) { pw.print(" mFile="); pw.println(mFile.getBaseFile()); } Loading Loading @@ -1030,7 +1031,7 @@ public final class ProcessStatsService extends IProcessStats.Stub { // much crud. if (dumpFullDetails) { processStats.dumpLocked(pw, reqPackage, now, false, false, activeOnly); false, activeOnly); } else { processStats.dumpSummaryLocked(pw, reqPackage, now, activeOnly); } Loading Loading @@ -1060,8 +1061,8 @@ public final class ProcessStatsService extends IProcessStats.Stub { } pw.println("CURRENT STATS:"); if (dumpDetails || dumpFullDetails) { mProcessStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpAll, activeOnly); mProcessStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpDetails, dumpAll, activeOnly); if (dumpAll) { pw.print(" mFile="); pw.println(mFile.getBaseFile()); } Loading Loading
core/java/com/android/internal/app/procstats/AssociationState.java +230 −38 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ public final class AssociationState { private final ProcessStats.PackageState mPackageState; private final String mProcessName; private final String mName; private final DurationsTable mDurations; public final class SourceState { final SourceKey mKey; Loading @@ -49,8 +48,10 @@ public final class AssociationState { long mDuration; long mTrackingUptime; int mActiveCount; int mActiveProcState = ProcessStats.STATE_NOTHING; long mActiveStartUptime; long mActiveDuration; DurationsTable mDurations; SourceState(SourceKey key) { mKey = key; Loading @@ -77,13 +78,15 @@ public final class AssociationState { mProcState = procState; } if (procState < ProcessStats.STATE_HOME) { // If the proc state has become better than cached, then we want to // start tracking it to count when it is actually active. If it drops // down to cached, we will clean it up when we later evaluate all currently // tracked associations in ProcessStats.updateTrackingAssociationsLocked(). if (!mInTrackingList) { mInTrackingList = true; mTrackingUptime = now; mProcessStats.mTrackingAssociations.add(this); } } else { stopTracking(now); } } Loading @@ -102,6 +105,22 @@ public final class AssociationState { mActiveStartUptime = now; mActiveCount++; } if (mActiveProcState != mProcState) { if (mActiveProcState != ProcessStats.STATE_NOTHING) { // Currently active proc state changed, need to store the duration // so far and switch tracking to the new proc state. final long duration = mActiveDuration + now - mActiveStartUptime; if (duration != 0) { if (mDurations == null) { makeDurations(); } mDurations.addDuration(mActiveProcState, duration); mActiveDuration = 0; } mActiveStartUptime = now; } mActiveProcState = mProcState; } } else { Slog.wtf(TAG, "startActive while not tracking: " + this); } Loading @@ -112,15 +131,25 @@ public final class AssociationState { if (!mInTrackingList) { Slog.wtf(TAG, "stopActive while not tracking: " + this); } mActiveDuration += now - mActiveStartUptime; final long duration = mActiveDuration + now - mActiveStartUptime; if (mDurations != null) { mDurations.addDuration(mActiveProcState, duration); } else { mActiveDuration = duration; } mActiveStartUptime = 0; } } void makeDurations() { mDurations = new DurationsTable(mProcessStats.mTableData); } void stopTracking(long now) { stopActive(now); if (mInTrackingList) { mInTrackingList = false; mProcState = ProcessStats.STATE_NOTHING; // Do a manual search for where to remove, since these objects will typically // be towards the end of the array. final ArrayList<SourceState> list = mProcessStats.mTrackingAssociations; Loading Loading @@ -207,7 +236,6 @@ public final class AssociationState { mPackageState = packageState; mName = name; mProcessName = processName; mDurations = new DurationsTable(processStats.mTableData); mProc = proc; } Loading Loading @@ -254,7 +282,6 @@ public final class AssociationState { } public void add(AssociationState other) { mDurations.addDurations(other.mDurations); for (int isrc = other.mSources.size() - 1; isrc >= 0; isrc--) { final SourceKey key = other.mSources.keyAt(isrc); final SourceState otherSrc = other.mSources.valueAt(isrc); Loading @@ -266,7 +293,48 @@ public final class AssociationState { mySrc.mCount += otherSrc.mCount; mySrc.mDuration += otherSrc.mDuration; mySrc.mActiveCount += otherSrc.mActiveCount; mySrc.mActiveDuration += otherSrc.mActiveDuration; if (otherSrc.mActiveDuration != 0 || otherSrc.mDurations != null) { // Only need to do anything if the other one has some duration data. if (mySrc.mDurations != null) { // If the target already has multiple durations, just add in whatever // we have in the other. if (otherSrc.mDurations != null) { mySrc.mDurations.addDurations(otherSrc.mDurations); } else { mySrc.mDurations.addDuration(otherSrc.mActiveProcState, otherSrc.mActiveDuration); } } else if (otherSrc.mDurations != null) { // The other one has multiple durations, but we don't. Expand to // multiple durations and copy over. mySrc.makeDurations(); mySrc.mDurations.addDurations(otherSrc.mDurations); if (mySrc.mActiveDuration != 0) { mySrc.mDurations.addDuration(mySrc.mActiveProcState, mySrc.mActiveDuration); mySrc.mActiveDuration = 0; mySrc.mActiveProcState = ProcessStats.STATE_NOTHING; } } else if (mySrc.mActiveDuration != 0) { // Both have a single inline duration... we can either add them together, // or need to expand to multiple durations. if (mySrc.mActiveProcState == otherSrc.mActiveProcState) { mySrc.mDuration += otherSrc.mDuration; } else { // The two have durations with different proc states, need to turn // in to multiple durations. mySrc.makeDurations(); mySrc.mDurations.addDuration(mySrc.mActiveProcState, mySrc.mActiveDuration); mySrc.mDurations.addDuration(otherSrc.mActiveProcState, otherSrc.mActiveDuration); mySrc.mActiveDuration = 0; mySrc.mActiveProcState = ProcessStats.STATE_NOTHING; } } else { // The other one has a duration, and we know the target doesn't. Copy over. mySrc.mActiveProcState = otherSrc.mActiveProcState; mySrc.mActiveDuration = otherSrc.mActiveDuration; } } } } Loading @@ -275,7 +343,6 @@ public final class AssociationState { } public void resetSafely(long now) { mDurations.resetTable(); if (!isInUse()) { mSources.clear(); } else { Loading @@ -293,6 +360,7 @@ public final class AssociationState { src.mActiveCount = 0; } src.mActiveDuration = 0; src.mDurations = null; } else { mSources.removeAt(isrc); } Loading @@ -301,7 +369,6 @@ public final class AssociationState { } public void writeToParcel(ProcessStats stats, Parcel out, long nowUptime) { mDurations.writeToParcel(out); final int NSRC = mSources.size(); out.writeInt(NSRC); for (int isrc = 0; isrc < NSRC; isrc++) { Loading @@ -312,18 +379,22 @@ public final class AssociationState { out.writeInt(src.mCount); out.writeLong(src.mDuration); out.writeInt(src.mActiveCount); if (src.mDurations != null) { out.writeInt(1); src.mDurations.writeToParcel(out); } else { out.writeInt(0); out.writeInt(src.mActiveProcState); out.writeLong(src.mActiveDuration); } } } /** * Returns non-null if all else fine, else a String that describes the error that * caused it to fail. */ public String readFromParcel(ProcessStats stats, Parcel in, int parcelVersion) { if (!mDurations.readFromParcel(in)) { return "Duration table corrupt"; } final int NSRC = in.readInt(); if (NSRC < 0 || NSRC > 100000) { return "Association with bad src count: " + NSRC; Loading @@ -336,7 +407,15 @@ public final class AssociationState { src.mCount = in.readInt(); src.mDuration = in.readLong(); src.mActiveCount = in.readInt(); if (in.readInt() != 0) { src.makeDurations(); if (!src.mDurations.readFromParcel(in)) { return "Duration table corrupt: " + key + " <- " + src; } } else { src.mActiveProcState = in.readInt(); src.mActiveDuration = in.readLong(); } mSources.put(key, src); } return null; Loading @@ -351,7 +430,12 @@ public final class AssociationState { src.mStartUptime = nowUptime; } if (src.mActiveStartUptime > 0) { src.mActiveDuration += nowUptime - src.mActiveStartUptime; final long duration = src.mActiveDuration + nowUptime - src.mActiveStartUptime; if (src.mDurations != null) { src.mDurations.addDuration(src.mActiveProcState, duration); } else { src.mActiveDuration = duration; } src.mActiveStartUptime = nowUptime; } } Loading @@ -359,7 +443,7 @@ public final class AssociationState { } public void dumpStats(PrintWriter pw, String prefix, String prefixInner, String headerPrefix, long now, long totalTime, boolean dumpSummary, boolean dumpAll) { long now, long totalTime, boolean dumpDetails, boolean dumpAll) { if (dumpAll) { pw.print(prefix); pw.print("mNumActive="); Loading @@ -376,18 +460,18 @@ public final class AssociationState { UserHandle.formatUid(pw, key.mUid); pw.println(":"); pw.print(prefixInner); pw.print(" Count "); pw.print(" Total count "); pw.print(src.mCount); long duration = src.mDuration; if (src.mNesting > 0) { duration += now - src.mStartUptime; } if (dumpAll) { pw.print(" / Duration "); pw.print(": Duration "); TimeUtils.formatDuration(duration, pw); pw.print(" / "); } else { pw.print(" / time "); pw.print(": time "); } DumpUtils.printPercent(pw, (double)duration/(double)totalTime); if (src.mNesting > 0) { Loading @@ -401,20 +485,53 @@ public final class AssociationState { pw.print(")"); } pw.println(); if (src.mActiveCount > 0) { if (src.mActiveCount > 0 || src.mDurations != null || src.mActiveDuration != 0 || src.mActiveStartUptime != 0) { pw.print(prefixInner); pw.print(" Active count "); pw.print(src.mActiveCount); duration = src.mActiveDuration; if (src.mActiveStartUptime > 0) { duration += now - src.mActiveStartUptime; if (dumpDetails) { if (dumpAll) { pw.print(src.mDurations != null ? " (multi-field)" : " (inline)"); } pw.println(":"); dumpTime(pw, prefixInner, src, totalTime, now, dumpDetails, dumpAll); } else { pw.print(": "); dumpActiveDurationSummary(pw, src, totalTime, now, dumpAll); pw.println(); } } if (dumpAll) { pw.print(" / Duration "); if (src.mInTrackingList) { pw.print(prefixInner); pw.print(" mInTrackingList="); pw.println(src.mInTrackingList); } if (src.mProcState != ProcessStats.STATE_NOTHING) { pw.print(prefixInner); pw.print(" mProcState="); pw.print(DumpUtils.STATE_NAMES[src.mProcState]); pw.print(" mProcStateSeq="); pw.println(src.mProcStateSeq); } } } } void dumpActiveDurationSummary(PrintWriter pw, final SourceState src, long totalTime, long now, boolean dumpAll) { long duration = dumpTime(null, null, src, totalTime, now, false, false); final boolean isRunning = duration < 0; if (isRunning) { duration = -duration; } if (dumpAll) { pw.print("Duration "); TimeUtils.formatDuration(duration, pw); pw.print(" / "); } else { pw.print(" / time "); pw.print("time "); } DumpUtils.printPercent(pw, (double) duration / (double) totalTime); if (src.mActiveStartUptime > 0) { Loading @@ -422,7 +539,64 @@ public final class AssociationState { } pw.println(); } long dumpTime(PrintWriter pw, String prefix, final SourceState src, long overallTime, long now, boolean dumpDetails, boolean dumpAll) { long totalTime = 0; boolean isRunning = false; for (int iprocstate = 0; iprocstate < ProcessStats.STATE_COUNT; iprocstate++) { long time; if (src.mDurations != null) { time = src.mDurations.getValueForId((byte)iprocstate); } else { time = src.mActiveProcState == iprocstate ? src.mDuration : 0; } final String running; if (src.mActiveStartUptime != 0 && src.mActiveProcState == iprocstate) { running = " (running)"; isRunning = true; time += now - src.mActiveStartUptime; } else { running = null; } if (time != 0) { if (pw != null) { pw.print(prefix); pw.print(" "); pw.print(DumpUtils.STATE_LABELS[iprocstate]); pw.print(": "); if (dumpAll) { pw.print("Duration "); TimeUtils.formatDuration(time, pw); pw.print(" / "); } else { pw.print("time "); } DumpUtils.printPercent(pw, (double) time / (double) overallTime); if (running != null) { pw.print(running); } pw.println(); } totalTime += time; } } if (totalTime != 0 && pw != null) { pw.print(prefix); pw.print(" "); pw.print(DumpUtils.STATE_LABEL_TOTAL); pw.print(": "); if (dumpAll) { pw.print("Duration "); TimeUtils.formatDuration(totalTime, pw); pw.print(" / "); } else { pw.print("time "); } DumpUtils.printPercent(pw, (double) totalTime / (double) overallTime); pw.println(); } return isRunning ? -totalTime : totalTime; } public void dumpTimesCheckin(PrintWriter pw, String pkgName, int uid, long vers, Loading Loading @@ -454,12 +628,30 @@ public final class AssociationState { pw.print(duration); pw.print(","); pw.print(src.mActiveCount); duration = src.mActiveDuration; if (src.mActiveStartUptime > 0) { duration += now - src.mActiveStartUptime; final long timeNow = src.mActiveStartUptime != 0 ? (now-src.mActiveStartUptime) : 0; if (src.mDurations != null) { final int N = src.mDurations.getKeyCount(); for (int i=0; i<N; i++) { final int dkey = src.mDurations.getKeyAt(i); duration = src.mDurations.getValue(dkey); if (dkey == src.mActiveProcState) { duration += timeNow; } final int procState = SparseMappingTable.getIdFromKey(dkey); pw.print(","); DumpUtils.printArrayEntry(pw, DumpUtils.STATE_TAGS, procState, 1); pw.print(':'); pw.print(duration); } } else { duration = src.mActiveDuration + timeNow; if (duration != 0) { pw.print(","); DumpUtils.printArrayEntry(pw, DumpUtils.STATE_TAGS, src.mActiveProcState, 1); pw.print(':'); pw.print(duration); } } pw.println(); } } Loading
core/java/com/android/internal/app/procstats/DumpUtils.java +66 −45 Original line number Diff line number Diff line Loading @@ -48,6 +48,9 @@ import java.util.Objects; */ public final class DumpUtils { public static final String[] STATE_NAMES; public static final String[] STATE_LABELS; public static final String STATE_LABEL_TOTAL; public static final String STATE_LABEL_CACHED; public static final String[] STATE_NAMES_CSV; static final String[] STATE_TAGS; static final int[] STATE_PROTO_ENUMS; Loading @@ -70,6 +73,24 @@ public final class DumpUtils { STATE_NAMES[STATE_CACHED_ACTIVITY_CLIENT] = "CchCAct"; STATE_NAMES[STATE_CACHED_EMPTY] = "CchEmty"; STATE_LABELS = new String[STATE_COUNT]; STATE_LABELS[STATE_PERSISTENT] = "Persistent"; STATE_LABELS[STATE_TOP] = " Top"; STATE_LABELS[STATE_IMPORTANT_FOREGROUND] = " Imp Fg"; STATE_LABELS[STATE_IMPORTANT_BACKGROUND] = " Imp Bg"; STATE_LABELS[STATE_BACKUP] = " Backup"; STATE_LABELS[STATE_SERVICE] = " Service"; STATE_LABELS[STATE_SERVICE_RESTARTING] = "Service Rs"; STATE_LABELS[STATE_RECEIVER] = " Receiver"; STATE_LABELS[STATE_HEAVY_WEIGHT] = " Heavy Wgt"; STATE_LABELS[STATE_HOME] = " (Home)"; STATE_LABELS[STATE_LAST_ACTIVITY] = "(Last Act)"; STATE_LABELS[STATE_CACHED_ACTIVITY] = " (Cch Act)"; STATE_LABELS[STATE_CACHED_ACTIVITY_CLIENT] = "(Cch CAct)"; STATE_LABELS[STATE_CACHED_EMPTY] = "(Cch Emty)"; STATE_LABEL_CACHED = " (Cached)"; STATE_LABEL_TOTAL = " TOTAL"; STATE_NAMES_CSV = new String[STATE_COUNT]; STATE_NAMES_CSV[STATE_PERSISTENT] = "pers"; STATE_NAMES_CSV[STATE_TOP] = "top"; Loading
core/java/com/android/internal/app/procstats/ProcessState.java +36 −32 File changed.Preview size limit exceeded, changes collapsed. Show changes
core/java/com/android/internal/app/procstats/ProcessStats.java +11 −20 Original line number Diff line number Diff line Loading @@ -158,7 +158,7 @@ public final class ProcessStats implements Parcelable { }; // Current version of the parcel format. private static final int PARCEL_VERSION = 32; private static final int PARCEL_VERSION = 33; // In-memory Parcel magic number, used to detect attempts to unmarshall bad data private static final int MAGIC = 0x50535454; Loading Loading @@ -1380,9 +1380,13 @@ public final class ProcessStats implements Parcelable { final int NUM = mTrackingAssociations.size(); for (int i = NUM - 1; i >= 0; i--) { final AssociationState.SourceState act = mTrackingAssociations.get(i); if (act.mProcStateSeq != curSeq) { if (act.mProcStateSeq != curSeq || act.mProcState >= ProcessStats.STATE_HOME) { // If this association did not get touched the last time we computed // process states, or its state ended up down in cached, then we no // longer have a reason to track it at all. act.stopActive(now); act.mInTrackingList = false; act.mProcState = STATE_NOTHING; act.mProcState = ProcessStats.STATE_NOTHING; mTrackingAssociations.remove(i); } else { final ProcessState proc = act.getAssociationState().getProcess(); Loading @@ -1407,7 +1411,7 @@ public final class ProcessStats implements Parcelable { } public void dumpLocked(PrintWriter pw, String reqPackage, long now, boolean dumpSummary, boolean dumpAll, boolean activeOnly) { boolean dumpDetails, boolean dumpAll, boolean activeOnly) { long totalTime = DumpUtils.dumpSingleTime(null, null, mMemFactorDurations, mMemFactor, mStartTime, now); boolean sepNeeded = false; Loading Loading @@ -1538,7 +1542,7 @@ public final class ProcessStats implements Parcelable { pw.println(":"); pw.print(" Process: "); pw.println(asc.getProcessName()); asc.dumpStats(pw, " ", " ", " ", now, totalTime, dumpSummary, dumpAll); now, totalTime, dumpDetails, dumpAll); } } } Loading Loading @@ -1632,21 +1636,8 @@ public final class ProcessStats implements Parcelable { if (src.mActiveCount > 0) { pw.print(" Active count "); pw.print(src.mActiveCount); long duration = src.mActiveDuration; if (src.mActiveStartUptime > 0) { duration += now - src.mActiveStartUptime; } if (dumpAll) { pw.print(" / Duration "); TimeUtils.formatDuration(duration, pw); pw.print(" / "); } else { pw.print(" / time "); } DumpUtils.printPercent(pw, (double)duration/(double)totalTime); if (src.mActiveStartUptime > 0) { pw.print(" (running)"); } pw.print(": "); asc.dumpActiveDurationSummary(pw, src, totalTime, now, dumpAll); pw.println(); } } Loading
services/core/java/com/android/server/am/ProcessStatsService.java +7 −6 Original line number Diff line number Diff line Loading @@ -612,7 +612,8 @@ public final class ProcessStatsService extends IProcessStats.Stub { stats.dumpCheckinLocked(pw, reqPackage); } else { if (dumpDetails || dumpFullDetails) { stats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpAll, activeOnly); stats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpDetails, dumpAll, activeOnly); } else { stats.dumpSummaryLocked(pw, reqPackage, now, activeOnly); } Loading Loading @@ -974,8 +975,8 @@ public final class ProcessStatsService extends IProcessStats.Stub { if (checkedIn) pw.print(" (checked in)"); pw.println(":"); if (dumpDetails || dumpFullDetails) { processStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpAll, activeOnly); processStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpDetails, dumpAll, activeOnly); if (dumpAll) { pw.print(" mFile="); pw.println(mFile.getBaseFile()); } Loading Loading @@ -1030,7 +1031,7 @@ public final class ProcessStatsService extends IProcessStats.Stub { // much crud. if (dumpFullDetails) { processStats.dumpLocked(pw, reqPackage, now, false, false, activeOnly); false, activeOnly); } else { processStats.dumpSummaryLocked(pw, reqPackage, now, activeOnly); } Loading Loading @@ -1060,8 +1061,8 @@ public final class ProcessStatsService extends IProcessStats.Stub { } pw.println("CURRENT STATS:"); if (dumpDetails || dumpFullDetails) { mProcessStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpAll, activeOnly); mProcessStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpDetails, dumpAll, activeOnly); if (dumpAll) { pw.print(" mFile="); pw.println(mFile.getBaseFile()); } Loading