Loading core/java/com/android/internal/app/procstats/DumpUtils.java +7 −0 Original line number Diff line number Diff line Loading @@ -539,4 +539,11 @@ public final class DumpUtils { // Pack screen & process state using bit shifting return (procStateIndex << 8) | screenStateIndex; } /** Print aggregated tags generated via {@code #aggregateCurrentProcessState}. */ public static void printAggregatedProcStateTagProto(ProtoOutputStream proto, long screenId, long stateId, int state) { proto.write(screenId, ADJ_SCREEN_PROTO_ENUMS[state >> 8]); proto.write(stateId, STATE_PROTO_ENUMS[state]); } } core/java/com/android/internal/app/procstats/ProcessState.java +119 −16 Original line number Diff line number Diff line Loading @@ -16,22 +16,6 @@ package com.android.internal.app.procstats; import android.os.Parcel; import android.os.SystemClock; import android.os.UserHandle; import android.service.procstats.ProcessStatsProto; import android.service.procstats.ProcessStatsStateProto; import android.util.ArrayMap; import android.util.DebugUtils; import android.util.Log; import android.util.LongSparseArray; import android.util.Slog; import android.util.SparseLongArray; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoUtils; import static com.android.internal.app.procstats.ProcessStats.PSS_AVERAGE; import static com.android.internal.app.procstats.ProcessStats.PSS_COUNT; import static com.android.internal.app.procstats.ProcessStats.PSS_MAXIMUM; Loading Loading @@ -60,6 +44,21 @@ import static com.android.internal.app.procstats.ProcessStats.STATE_SERVICE; import static com.android.internal.app.procstats.ProcessStats.STATE_SERVICE_RESTARTING; import static com.android.internal.app.procstats.ProcessStats.STATE_TOP; import android.os.Parcel; import android.os.SystemClock; import android.os.UserHandle; import android.service.procstats.ProcessStatsProto; import android.service.procstats.ProcessStatsStateProto; import android.util.ArrayMap; import android.util.DebugUtils; import android.util.Log; import android.util.LongSparseArray; import android.util.Slog; import android.util.SparseLongArray; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoUtils; import com.android.internal.app.procstats.ProcessStats.PackageState; import com.android.internal.app.procstats.ProcessStats.ProcessStateHolder; import com.android.internal.app.procstats.ProcessStats.TotalMemoryUseCollection; Loading Loading @@ -1418,4 +1417,108 @@ public final class ProcessState { proto.end(token); } /** Similar to {@code #dumpDebug}, but with a reduced/aggregated subset of states. */ public void dumpAggregatedProtoForStatsd(ProtoOutputStream proto, long fieldId, String procName, int uid, long now) { // Group proc stats by aggregated type (only screen state + process state) SparseLongArray durationByState = new SparseLongArray(); boolean didCurState = false; for (int i = 0; i < mDurations.getKeyCount(); i++) { final int key = mDurations.getKeyAt(i); final int type = SparseMappingTable.getIdFromKey(key); final int aggregatedType = DumpUtils.aggregateCurrentProcessState(type); long time = mDurations.getValue(key); if (mCurCombinedState == type) { didCurState = true; time += now - mStartTime; } int index = durationByState.indexOfKey(aggregatedType); if (index >= 0) { durationByState.put(aggregatedType, time + durationByState.valueAt(aggregatedType)); } else { durationByState.put(aggregatedType, time); } } if (!didCurState && mCurCombinedState != STATE_NOTHING) { final int aggregatedType = DumpUtils.aggregateCurrentProcessState(mCurCombinedState); int index = durationByState.indexOfKey(aggregatedType); if (index >= 0) { durationByState.put(aggregatedType, (now - mStartTime) + durationByState.valueAt(index)); } else { durationByState.put(aggregatedType, now - mStartTime); } } // Now we have total durations, aggregate the RSS values SparseLongArray meanRssByState = new SparseLongArray(); SparseLongArray maxRssByState = new SparseLongArray(); // compute weighted averages and max-of-max for (int i = 0; i < mPssTable.getKeyCount(); i++) { final int key = mPssTable.getKeyAt(i); final int type = SparseMappingTable.getIdFromKey(key); if (durationByState.indexOfKey(type) < 0) { // state without duration should not have stats! continue; } final int aggregatedType = DumpUtils.aggregateCurrentProcessState(type); long[] rssMeanAndMax = mPssTable.getRssMeanAndMax(key); // compute mean * duration, then store sum of that in meanRssByState long meanTimesDuration = rssMeanAndMax[0] * mDurations.getValue(key); if (meanRssByState.indexOfKey(aggregatedType) >= 0) { meanRssByState.put(aggregatedType, meanTimesDuration + meanRssByState.get(aggregatedType)); } else { meanRssByState.put(aggregatedType, meanTimesDuration); } // accumulate max-of-maxes in maxRssByState if (maxRssByState.indexOfKey(aggregatedType) >= 0 && maxRssByState.get(aggregatedType) < rssMeanAndMax[1]) { maxRssByState.put(aggregatedType, rssMeanAndMax[1]); } else if (maxRssByState.indexOfKey(aggregatedType) < 0) { maxRssByState.put(aggregatedType, rssMeanAndMax[1]); } } // divide the means by the durations to get the weighted mean-of-means for (int i = 0; i < durationByState.size(); i++) { int aggregatedKey = durationByState.keyAt(i); if (meanRssByState.indexOfKey(aggregatedKey) < 0) { // these data structures should be consistent continue; } meanRssByState.put(aggregatedKey, meanRssByState.get(aggregatedKey) / durationByState.get(aggregatedKey)); } // build the output final long token = proto.start(fieldId); proto.write(ProcessStatsProto.PROCESS, procName); proto.write(ProcessStatsProto.UID, uid); for (int i = 0; i < durationByState.size(); i++) { final int aggregatedKey = mPssTable.getKeyAt(i); final long stateToken = proto.start(ProcessStatsProto.STATES); DumpUtils.printAggregatedProcStateTagProto(proto, ProcessStatsStateProto.SCREEN_STATE, ProcessStatsStateProto.PROCESS_STATE, durationByState.keyAt(i)); proto.write(ProcessStatsStateProto.DURATION_MS, durationByState.valueAt(i)); ProtoUtils.toAggStatsProto(proto, ProcessStatsStateProto.RSS, 0, /* do not output a minimum value */ meanRssByState.get(aggregatedKey), maxRssByState.get(aggregatedKey)); proto.end(stateToken); } proto.end(token); } } core/java/com/android/internal/app/procstats/PssTable.java +11 −6 Original line number Diff line number Diff line Loading @@ -16,17 +16,17 @@ package com.android.internal.app.procstats; import static com.android.internal.app.procstats.ProcessStats.PSS_AVERAGE; import static com.android.internal.app.procstats.ProcessStats.PSS_COUNT; import static com.android.internal.app.procstats.ProcessStats.PSS_MAXIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_MINIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_AVERAGE; import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_MAXIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_MINIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_SAMPLE_COUNT; import static com.android.internal.app.procstats.ProcessStats.PSS_MINIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_AVERAGE; import static com.android.internal.app.procstats.ProcessStats.PSS_MAXIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MINIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_USS_AVERAGE; import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MAXIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_COUNT; import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MINIMUM; import android.service.procstats.ProcessStatsStateProto; import android.util.proto.ProtoOutputStream; Loading Loading @@ -133,7 +133,6 @@ public class PssTable extends SparseMappingTable.Table { } if (stats[statsIndex + PSS_RSS_MINIMUM] > minRss) { stats[statsIndex + PSS_RSS_MINIMUM] = minRss; } stats[statsIndex + PSS_RSS_AVERAGE] = (long)(((stats[statsIndex + PSS_RSS_AVERAGE] Loading Loading @@ -167,4 +166,10 @@ public class PssTable extends SparseMappingTable.Table { stats[statsIndex + PSS_RSS_AVERAGE], stats[statsIndex + PSS_RSS_MAXIMUM]); } long[] getRssMeanAndMax(int key) { final long[] stats = getArrayForKey(key); final int statsIndex = SparseMappingTable.getIndexFromKey(key); return new long[]{stats[statsIndex + PSS_RSS_AVERAGE], stats[statsIndex + PSS_RSS_MAXIMUM]}; } } Loading
core/java/com/android/internal/app/procstats/DumpUtils.java +7 −0 Original line number Diff line number Diff line Loading @@ -539,4 +539,11 @@ public final class DumpUtils { // Pack screen & process state using bit shifting return (procStateIndex << 8) | screenStateIndex; } /** Print aggregated tags generated via {@code #aggregateCurrentProcessState}. */ public static void printAggregatedProcStateTagProto(ProtoOutputStream proto, long screenId, long stateId, int state) { proto.write(screenId, ADJ_SCREEN_PROTO_ENUMS[state >> 8]); proto.write(stateId, STATE_PROTO_ENUMS[state]); } }
core/java/com/android/internal/app/procstats/ProcessState.java +119 −16 Original line number Diff line number Diff line Loading @@ -16,22 +16,6 @@ package com.android.internal.app.procstats; import android.os.Parcel; import android.os.SystemClock; import android.os.UserHandle; import android.service.procstats.ProcessStatsProto; import android.service.procstats.ProcessStatsStateProto; import android.util.ArrayMap; import android.util.DebugUtils; import android.util.Log; import android.util.LongSparseArray; import android.util.Slog; import android.util.SparseLongArray; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoUtils; import static com.android.internal.app.procstats.ProcessStats.PSS_AVERAGE; import static com.android.internal.app.procstats.ProcessStats.PSS_COUNT; import static com.android.internal.app.procstats.ProcessStats.PSS_MAXIMUM; Loading Loading @@ -60,6 +44,21 @@ import static com.android.internal.app.procstats.ProcessStats.STATE_SERVICE; import static com.android.internal.app.procstats.ProcessStats.STATE_SERVICE_RESTARTING; import static com.android.internal.app.procstats.ProcessStats.STATE_TOP; import android.os.Parcel; import android.os.SystemClock; import android.os.UserHandle; import android.service.procstats.ProcessStatsProto; import android.service.procstats.ProcessStatsStateProto; import android.util.ArrayMap; import android.util.DebugUtils; import android.util.Log; import android.util.LongSparseArray; import android.util.Slog; import android.util.SparseLongArray; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoUtils; import com.android.internal.app.procstats.ProcessStats.PackageState; import com.android.internal.app.procstats.ProcessStats.ProcessStateHolder; import com.android.internal.app.procstats.ProcessStats.TotalMemoryUseCollection; Loading Loading @@ -1418,4 +1417,108 @@ public final class ProcessState { proto.end(token); } /** Similar to {@code #dumpDebug}, but with a reduced/aggregated subset of states. */ public void dumpAggregatedProtoForStatsd(ProtoOutputStream proto, long fieldId, String procName, int uid, long now) { // Group proc stats by aggregated type (only screen state + process state) SparseLongArray durationByState = new SparseLongArray(); boolean didCurState = false; for (int i = 0; i < mDurations.getKeyCount(); i++) { final int key = mDurations.getKeyAt(i); final int type = SparseMappingTable.getIdFromKey(key); final int aggregatedType = DumpUtils.aggregateCurrentProcessState(type); long time = mDurations.getValue(key); if (mCurCombinedState == type) { didCurState = true; time += now - mStartTime; } int index = durationByState.indexOfKey(aggregatedType); if (index >= 0) { durationByState.put(aggregatedType, time + durationByState.valueAt(aggregatedType)); } else { durationByState.put(aggregatedType, time); } } if (!didCurState && mCurCombinedState != STATE_NOTHING) { final int aggregatedType = DumpUtils.aggregateCurrentProcessState(mCurCombinedState); int index = durationByState.indexOfKey(aggregatedType); if (index >= 0) { durationByState.put(aggregatedType, (now - mStartTime) + durationByState.valueAt(index)); } else { durationByState.put(aggregatedType, now - mStartTime); } } // Now we have total durations, aggregate the RSS values SparseLongArray meanRssByState = new SparseLongArray(); SparseLongArray maxRssByState = new SparseLongArray(); // compute weighted averages and max-of-max for (int i = 0; i < mPssTable.getKeyCount(); i++) { final int key = mPssTable.getKeyAt(i); final int type = SparseMappingTable.getIdFromKey(key); if (durationByState.indexOfKey(type) < 0) { // state without duration should not have stats! continue; } final int aggregatedType = DumpUtils.aggregateCurrentProcessState(type); long[] rssMeanAndMax = mPssTable.getRssMeanAndMax(key); // compute mean * duration, then store sum of that in meanRssByState long meanTimesDuration = rssMeanAndMax[0] * mDurations.getValue(key); if (meanRssByState.indexOfKey(aggregatedType) >= 0) { meanRssByState.put(aggregatedType, meanTimesDuration + meanRssByState.get(aggregatedType)); } else { meanRssByState.put(aggregatedType, meanTimesDuration); } // accumulate max-of-maxes in maxRssByState if (maxRssByState.indexOfKey(aggregatedType) >= 0 && maxRssByState.get(aggregatedType) < rssMeanAndMax[1]) { maxRssByState.put(aggregatedType, rssMeanAndMax[1]); } else if (maxRssByState.indexOfKey(aggregatedType) < 0) { maxRssByState.put(aggregatedType, rssMeanAndMax[1]); } } // divide the means by the durations to get the weighted mean-of-means for (int i = 0; i < durationByState.size(); i++) { int aggregatedKey = durationByState.keyAt(i); if (meanRssByState.indexOfKey(aggregatedKey) < 0) { // these data structures should be consistent continue; } meanRssByState.put(aggregatedKey, meanRssByState.get(aggregatedKey) / durationByState.get(aggregatedKey)); } // build the output final long token = proto.start(fieldId); proto.write(ProcessStatsProto.PROCESS, procName); proto.write(ProcessStatsProto.UID, uid); for (int i = 0; i < durationByState.size(); i++) { final int aggregatedKey = mPssTable.getKeyAt(i); final long stateToken = proto.start(ProcessStatsProto.STATES); DumpUtils.printAggregatedProcStateTagProto(proto, ProcessStatsStateProto.SCREEN_STATE, ProcessStatsStateProto.PROCESS_STATE, durationByState.keyAt(i)); proto.write(ProcessStatsStateProto.DURATION_MS, durationByState.valueAt(i)); ProtoUtils.toAggStatsProto(proto, ProcessStatsStateProto.RSS, 0, /* do not output a minimum value */ meanRssByState.get(aggregatedKey), maxRssByState.get(aggregatedKey)); proto.end(stateToken); } proto.end(token); } }
core/java/com/android/internal/app/procstats/PssTable.java +11 −6 Original line number Diff line number Diff line Loading @@ -16,17 +16,17 @@ package com.android.internal.app.procstats; import static com.android.internal.app.procstats.ProcessStats.PSS_AVERAGE; import static com.android.internal.app.procstats.ProcessStats.PSS_COUNT; import static com.android.internal.app.procstats.ProcessStats.PSS_MAXIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_MINIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_AVERAGE; import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_MAXIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_MINIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_SAMPLE_COUNT; import static com.android.internal.app.procstats.ProcessStats.PSS_MINIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_AVERAGE; import static com.android.internal.app.procstats.ProcessStats.PSS_MAXIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MINIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_USS_AVERAGE; import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MAXIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_COUNT; import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MINIMUM; import android.service.procstats.ProcessStatsStateProto; import android.util.proto.ProtoOutputStream; Loading Loading @@ -133,7 +133,6 @@ public class PssTable extends SparseMappingTable.Table { } if (stats[statsIndex + PSS_RSS_MINIMUM] > minRss) { stats[statsIndex + PSS_RSS_MINIMUM] = minRss; } stats[statsIndex + PSS_RSS_AVERAGE] = (long)(((stats[statsIndex + PSS_RSS_AVERAGE] Loading Loading @@ -167,4 +166,10 @@ public class PssTable extends SparseMappingTable.Table { stats[statsIndex + PSS_RSS_AVERAGE], stats[statsIndex + PSS_RSS_MAXIMUM]); } long[] getRssMeanAndMax(int key) { final long[] stats = getArrayForKey(key); final int statsIndex = SparseMappingTable.getIndexFromKey(key); return new long[]{stats[statsIndex + PSS_RSS_AVERAGE], stats[statsIndex + PSS_RSS_MAXIMUM]}; } }