diff --git a/core/java/com/android/internal/app/procstats/DumpUtils.java b/core/java/com/android/internal/app/procstats/DumpUtils.java index fc5381e13dd29..9bdbdc70d74d9 100644 --- a/core/java/com/android/internal/app/procstats/DumpUtils.java +++ b/core/java/com/android/internal/app/procstats/DumpUtils.java @@ -534,16 +534,31 @@ public final class DumpUtils { int procStateIndex = curState % STATE_COUNT; // Remap process state per array above. - procStateIndex = PROCESS_STATS_STATE_TO_AGGREGATED_STATE[procStateIndex]; + try { + procStateIndex = PROCESS_STATS_STATE_TO_AGGREGATED_STATE[procStateIndex]; + } catch (IndexOutOfBoundsException e) { + procStateIndex = ProcessStatsEnums.AGGREGATED_PROCESS_STATE_UNKNOWN; + } // Pack screen & process state using bit shifting - return (procStateIndex << 8) | screenStateIndex; + return (procStateIndex << 0xf) | 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]); + // screen state is in lowest 0xf bits, process state is in next 0xf bits up + + try { + proto.write(stateId, STATE_PROTO_ENUMS[state >> 0xf]); + } catch (IndexOutOfBoundsException e) { + proto.write(stateId, ProcessStatsEnums.PROCESS_STATE_UNKNOWN); + } + + try { + proto.write(screenId, ADJ_SCREEN_PROTO_ENUMS[state & 0xf]); + } catch (IndexOutOfBoundsException e) { + proto.write(screenId, ProcessStatsEnums.SCREEN_STATE_UNKNOWN); + } } } diff --git a/core/java/com/android/internal/app/procstats/ProcessState.java b/core/java/com/android/internal/app/procstats/ProcessState.java index fa9785c6a21eb..79ff5948f32b5 100644 --- a/core/java/com/android/internal/app/procstats/ProcessState.java +++ b/core/java/com/android/internal/app/procstats/ProcessState.java @@ -1436,7 +1436,7 @@ public final class ProcessState { } int index = durationByState.indexOfKey(aggregatedType); if (index >= 0) { - durationByState.put(aggregatedType, time + durationByState.valueAt(aggregatedType)); + durationByState.put(aggregatedType, time + durationByState.valueAt(index)); } else { durationByState.put(aggregatedType, time); } @@ -1502,14 +1502,15 @@ public final class ProcessState { 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); + + final int aggregatedKey = durationByState.keyAt(i); + DumpUtils.printAggregatedProcStateTagProto(proto, ProcessStatsStateProto.SCREEN_STATE, ProcessStatsStateProto.PROCESS_STATE, - durationByState.keyAt(i)); - proto.write(ProcessStatsStateProto.DURATION_MS, durationByState.valueAt(i)); + aggregatedKey); + proto.write(ProcessStatsStateProto.DURATION_MS, durationByState.get(aggregatedKey)); ProtoUtils.toAggStatsProto(proto, ProcessStatsStateProto.RSS, 0, /* do not output a minimum value */ diff --git a/core/java/com/android/internal/app/procstats/ProcessStats.java b/core/java/com/android/internal/app/procstats/ProcessStats.java index 009b1e0fa829d..80f6272794d10 100644 --- a/core/java/com/android/internal/app/procstats/ProcessStats.java +++ b/core/java/com/android/internal/app/procstats/ProcessStats.java @@ -2178,29 +2178,7 @@ public final class ProcessStats implements Parcelable { * Writes to ProtoOutputStream. */ public void dumpDebug(ProtoOutputStream proto, long now, int section) { - proto.write(ProcessStatsSectionProto.START_REALTIME_MS, mTimePeriodStartRealtime); - proto.write(ProcessStatsSectionProto.END_REALTIME_MS, - mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime); - proto.write(ProcessStatsSectionProto.START_UPTIME_MS, mTimePeriodStartUptime); - proto.write(ProcessStatsSectionProto.END_UPTIME_MS, mTimePeriodEndUptime); - proto.write(ProcessStatsSectionProto.RUNTIME, mRuntime); - proto.write(ProcessStatsSectionProto.HAS_SWAPPED_PSS, mHasSwappedOutPss); - boolean partial = true; - if ((mFlags & FLAG_SHUTDOWN) != 0) { - proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SHUTDOWN); - partial = false; - } - if ((mFlags & FLAG_SYSPROPS) != 0) { - proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SYSPROPS); - partial = false; - } - if ((mFlags & FLAG_COMPLETE) != 0) { - proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_COMPLETE); - partial = false; - } - if (partial) { - proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_PARTIAL); - } + dumpProtoPreamble(proto); final int NPAGETYPES = mPageTypeLabels.size(); for (int i = 0; i < NPAGETYPES; i++) { @@ -2247,6 +2225,49 @@ public final class ProcessStats implements Parcelable { } } + /** Similar to {@code #dumpDebug}, but with a reduced/aggregated subset of states. */ + public void dumpAggregatedProtoForStatsd(ProtoOutputStream proto) { + dumpProtoPreamble(proto); + final ArrayMap> procMap = mProcesses.getMap(); + for (int ip = 0; ip < procMap.size(); ip++) { + final String procName = procMap.keyAt(ip); + final SparseArray uids = procMap.valueAt(ip); + for (int iu = 0; iu < uids.size(); iu++) { + final int uid = uids.keyAt(iu); + final ProcessState procState = uids.valueAt(iu); + procState.dumpAggregatedProtoForStatsd(proto, + ProcessStatsSectionProto.PROCESS_STATS, + procName, uid, mTimePeriodEndRealtime); + } + } + } + + private void dumpProtoPreamble(ProtoOutputStream proto) { + proto.write(ProcessStatsSectionProto.START_REALTIME_MS, mTimePeriodStartRealtime); + proto.write(ProcessStatsSectionProto.END_REALTIME_MS, + mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime); + proto.write(ProcessStatsSectionProto.START_UPTIME_MS, mTimePeriodStartUptime); + proto.write(ProcessStatsSectionProto.END_UPTIME_MS, mTimePeriodEndUptime); + proto.write(ProcessStatsSectionProto.RUNTIME, mRuntime); + proto.write(ProcessStatsSectionProto.HAS_SWAPPED_PSS, mHasSwappedOutPss); + boolean partial = true; + if ((mFlags & FLAG_SHUTDOWN) != 0) { + proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SHUTDOWN); + partial = false; + } + if ((mFlags & FLAG_SYSPROPS) != 0) { + proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SYSPROPS); + partial = false; + } + if ((mFlags & FLAG_COMPLETE) != 0) { + proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_COMPLETE); + partial = false; + } + if (partial) { + proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_PARTIAL); + } + } + final public static class ProcessStateHolder { public final long appVersion; public ProcessState state; diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java index 155b2e09284ae..a33896300f1c6 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -2041,32 +2041,35 @@ public class StatsPullAtomService extends SystemService { synchronized (mProcessStatsLock) { final long token = Binder.clearCallingIdentity(); try { + // force procstats to flush & combine old files into one store long lastHighWaterMark = readProcStatsHighWaterMark(section); List statsFiles = new ArrayList<>(); - long highWaterMark = processStatsService.getCommittedStats( - lastHighWaterMark, section, true, statsFiles); - if (statsFiles.size() != 1) { - return StatsManager.PULL_SKIP; - } - unpackStreamedData(atomTag, pulledData, statsFiles); + + ProcessStats procStats = new ProcessStats(false); + long highWaterMark = processStatsService.getCommittedStatsMerged( + lastHighWaterMark, section, true, statsFiles, procStats); + + // aggregate the data together for westworld consumption + ProtoOutputStream proto = new ProtoOutputStream(); + procStats.dumpAggregatedProtoForStatsd(proto); + + StatsEvent e = StatsEvent.newBuilder() + .setAtomId(atomTag) + .writeByteArray(proto.getBytes()) + .build(); + pulledData.add(e); + new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + lastHighWaterMark) .delete(); new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + highWaterMark) .createNewFile(); - } catch (IOException e) { - Slog.e(TAG, "Getting procstats failed: ", e); - return StatsManager.PULL_SKIP; - } catch (RemoteException e) { - Slog.e(TAG, "Getting procstats failed: ", e); - return StatsManager.PULL_SKIP; - } catch (SecurityException e) { + } catch (RemoteException | IOException e) { Slog.e(TAG, "Getting procstats failed: ", e); return StatsManager.PULL_SKIP; } finally { Binder.restoreCallingIdentity(token); } } - return StatsManager.PULL_SUCCESS; }