blob: 9bdbdc70d74d96212290ea7f23e298e46c243f71 [file] [log] [blame]
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.app.procstats;
18
Richard Gaywood9efa35f2020-02-20 16:06:57 +000019import static com.android.internal.app.procstats.ProcessStats.ADJ_COUNT;
20import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_COUNT;
21import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_LOW;
23import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_MODERATE;
24import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_NORMAL;
25import static com.android.internal.app.procstats.ProcessStats.ADJ_NOTHING;
26import static com.android.internal.app.procstats.ProcessStats.ADJ_SCREEN_MOD;
27import static com.android.internal.app.procstats.ProcessStats.ADJ_SCREEN_OFF;
28import static com.android.internal.app.procstats.ProcessStats.ADJ_SCREEN_ON;
29import static com.android.internal.app.procstats.ProcessStats.STATE_BACKUP;
30import static com.android.internal.app.procstats.ProcessStats.STATE_CACHED_ACTIVITY;
31import static com.android.internal.app.procstats.ProcessStats.STATE_CACHED_ACTIVITY_CLIENT;
32import static com.android.internal.app.procstats.ProcessStats.STATE_CACHED_EMPTY;
33import static com.android.internal.app.procstats.ProcessStats.STATE_COUNT;
34import static com.android.internal.app.procstats.ProcessStats.STATE_HEAVY_WEIGHT;
35import static com.android.internal.app.procstats.ProcessStats.STATE_HOME;
36import static com.android.internal.app.procstats.ProcessStats.STATE_IMPORTANT_BACKGROUND;
37import static com.android.internal.app.procstats.ProcessStats.STATE_IMPORTANT_FOREGROUND;
38import static com.android.internal.app.procstats.ProcessStats.STATE_LAST_ACTIVITY;
39import static com.android.internal.app.procstats.ProcessStats.STATE_NOTHING;
40import static com.android.internal.app.procstats.ProcessStats.STATE_PERSISTENT;
41import static com.android.internal.app.procstats.ProcessStats.STATE_RECEIVER;
42import static com.android.internal.app.procstats.ProcessStats.STATE_SERVICE;
43import static com.android.internal.app.procstats.ProcessStats.STATE_SERVICE_RESTARTING;
44import static com.android.internal.app.procstats.ProcessStats.STATE_TOP;
45
Joe Onorato4eb64fd2016-03-21 15:30:09 -070046import android.os.UserHandle;
Yangster-macbac82322018-08-23 14:45:10 -070047import android.service.procstats.ProcessStatsEnums;
Dianne Hackborneaed0ba2018-08-08 17:10:17 -070048import android.service.procstats.ProcessStatsStateProto;
Joe Onorato4eb64fd2016-03-21 15:30:09 -070049import android.util.TimeUtils;
Yi Jin9680cfa2017-09-15 15:14:43 -070050import android.util.proto.ProtoOutputStream;
Joe Onorato4eb64fd2016-03-21 15:30:09 -070051
Joe Onorato4eb64fd2016-03-21 15:30:09 -070052import java.io.PrintWriter;
53import java.util.ArrayList;
Joe Onorato4eb64fd2016-03-21 15:30:09 -070054
55/**
56 * Utilities for dumping.
57 */
58public final class DumpUtils {
Yi Jin676d1ac2018-01-25 15:40:28 -080059 public static final String[] STATE_NAMES;
Dianne Hackborn7aea7a42018-07-25 08:58:47 -070060 public static final String[] STATE_LABELS;
61 public static final String STATE_LABEL_TOTAL;
62 public static final String STATE_LABEL_CACHED;
Yi Jin676d1ac2018-01-25 15:40:28 -080063 public static final String[] STATE_NAMES_CSV;
64 static final String[] STATE_TAGS;
65 static final int[] STATE_PROTO_ENUMS;
Richard Gaywood9efa35f2020-02-20 16:06:57 +000066 private static final int[] PROCESS_STATS_STATE_TO_AGGREGATED_STATE;
Yi Jin676d1ac2018-01-25 15:40:28 -080067
68 // Make the mapping easy to update.
69 static {
70 STATE_NAMES = new String[STATE_COUNT];
Dianne Hackborn7aea7a42018-07-25 08:58:47 -070071 STATE_NAMES[STATE_PERSISTENT] = "Persist";
72 STATE_NAMES[STATE_TOP] = "Top";
73 STATE_NAMES[STATE_IMPORTANT_FOREGROUND] = "ImpFg";
74 STATE_NAMES[STATE_IMPORTANT_BACKGROUND] = "ImpBg";
75 STATE_NAMES[STATE_BACKUP] = "Backup";
76 STATE_NAMES[STATE_SERVICE] = "Service";
77 STATE_NAMES[STATE_SERVICE_RESTARTING] = "ServRst";
78 STATE_NAMES[STATE_RECEIVER] = "Receivr";
79 STATE_NAMES[STATE_HEAVY_WEIGHT] = "HeavyWt";
80 STATE_NAMES[STATE_HOME] = "Home";
81 STATE_NAMES[STATE_LAST_ACTIVITY] = "LastAct";
82 STATE_NAMES[STATE_CACHED_ACTIVITY] = "CchAct";
83 STATE_NAMES[STATE_CACHED_ACTIVITY_CLIENT] = "CchCAct";
84 STATE_NAMES[STATE_CACHED_EMPTY] = "CchEmty";
85
86 STATE_LABELS = new String[STATE_COUNT];
87 STATE_LABELS[STATE_PERSISTENT] = "Persistent";
88 STATE_LABELS[STATE_TOP] = " Top";
89 STATE_LABELS[STATE_IMPORTANT_FOREGROUND] = " Imp Fg";
90 STATE_LABELS[STATE_IMPORTANT_BACKGROUND] = " Imp Bg";
91 STATE_LABELS[STATE_BACKUP] = " Backup";
92 STATE_LABELS[STATE_SERVICE] = " Service";
93 STATE_LABELS[STATE_SERVICE_RESTARTING] = "Service Rs";
94 STATE_LABELS[STATE_RECEIVER] = " Receiver";
95 STATE_LABELS[STATE_HEAVY_WEIGHT] = " Heavy Wgt";
96 STATE_LABELS[STATE_HOME] = " (Home)";
97 STATE_LABELS[STATE_LAST_ACTIVITY] = "(Last Act)";
98 STATE_LABELS[STATE_CACHED_ACTIVITY] = " (Cch Act)";
99 STATE_LABELS[STATE_CACHED_ACTIVITY_CLIENT] = "(Cch CAct)";
100 STATE_LABELS[STATE_CACHED_EMPTY] = "(Cch Emty)";
101 STATE_LABEL_CACHED = " (Cached)";
102 STATE_LABEL_TOTAL = " TOTAL";
Yi Jin676d1ac2018-01-25 15:40:28 -0800103
104 STATE_NAMES_CSV = new String[STATE_COUNT];
Dianne Hackborn7aea7a42018-07-25 08:58:47 -0700105 STATE_NAMES_CSV[STATE_PERSISTENT] = "pers";
106 STATE_NAMES_CSV[STATE_TOP] = "top";
107 STATE_NAMES_CSV[STATE_IMPORTANT_FOREGROUND] = "impfg";
108 STATE_NAMES_CSV[STATE_IMPORTANT_BACKGROUND] = "impbg";
109 STATE_NAMES_CSV[STATE_BACKUP] = "backup";
110 STATE_NAMES_CSV[STATE_SERVICE] = "service";
111 STATE_NAMES_CSV[STATE_SERVICE_RESTARTING] = "service-rs";
112 STATE_NAMES_CSV[STATE_RECEIVER] = "receiver";
113 STATE_NAMES_CSV[STATE_HEAVY_WEIGHT] = "heavy";
114 STATE_NAMES_CSV[STATE_HOME] = "home";
115 STATE_NAMES_CSV[STATE_LAST_ACTIVITY] = "lastact";
116 STATE_NAMES_CSV[STATE_CACHED_ACTIVITY] = "cch-activity";
117 STATE_NAMES_CSV[STATE_CACHED_ACTIVITY_CLIENT] = "cch-aclient";
118 STATE_NAMES_CSV[STATE_CACHED_EMPTY] = "cch-empty";
Yi Jin676d1ac2018-01-25 15:40:28 -0800119
120 STATE_TAGS = new String[STATE_COUNT];
Dianne Hackborn7aea7a42018-07-25 08:58:47 -0700121 STATE_TAGS[STATE_PERSISTENT] = "p";
122 STATE_TAGS[STATE_TOP] = "t";
123 STATE_TAGS[STATE_IMPORTANT_FOREGROUND] = "f";
124 STATE_TAGS[STATE_IMPORTANT_BACKGROUND] = "b";
125 STATE_TAGS[STATE_BACKUP] = "u";
126 STATE_TAGS[STATE_SERVICE] = "s";
127 STATE_TAGS[STATE_SERVICE_RESTARTING] = "x";
128 STATE_TAGS[STATE_RECEIVER] = "r";
129 STATE_TAGS[STATE_HEAVY_WEIGHT] = "w";
130 STATE_TAGS[STATE_HOME] = "h";
131 STATE_TAGS[STATE_LAST_ACTIVITY] = "l";
132 STATE_TAGS[STATE_CACHED_ACTIVITY] = "a";
133 STATE_TAGS[STATE_CACHED_ACTIVITY_CLIENT] = "c";
134 STATE_TAGS[STATE_CACHED_EMPTY] = "e";
Yi Jin676d1ac2018-01-25 15:40:28 -0800135
136 STATE_PROTO_ENUMS = new int[STATE_COUNT];
Yangster-macbac82322018-08-23 14:45:10 -0700137 STATE_PROTO_ENUMS[STATE_PERSISTENT] = ProcessStatsEnums.PROCESS_STATE_PERSISTENT;
138 STATE_PROTO_ENUMS[STATE_TOP] = ProcessStatsEnums.PROCESS_STATE_TOP;
139 STATE_PROTO_ENUMS[STATE_IMPORTANT_FOREGROUND] =
140 ProcessStatsEnums.PROCESS_STATE_IMPORTANT_FOREGROUND;
141 STATE_PROTO_ENUMS[STATE_IMPORTANT_BACKGROUND] =
142 ProcessStatsEnums.PROCESS_STATE_IMPORTANT_BACKGROUND;
143 STATE_PROTO_ENUMS[STATE_BACKUP] = ProcessStatsEnums.PROCESS_STATE_BACKUP;
144 STATE_PROTO_ENUMS[STATE_SERVICE] = ProcessStatsEnums.PROCESS_STATE_SERVICE;
145 STATE_PROTO_ENUMS[STATE_SERVICE_RESTARTING] =
146 ProcessStatsEnums.PROCESS_STATE_SERVICE_RESTARTING;
147 STATE_PROTO_ENUMS[STATE_RECEIVER] = ProcessStatsEnums.PROCESS_STATE_RECEIVER;
148 STATE_PROTO_ENUMS[STATE_HEAVY_WEIGHT] = ProcessStatsEnums.PROCESS_STATE_HEAVY_WEIGHT;
149 STATE_PROTO_ENUMS[STATE_HOME] = ProcessStatsEnums.PROCESS_STATE_HOME;
150 STATE_PROTO_ENUMS[STATE_LAST_ACTIVITY] = ProcessStatsEnums.PROCESS_STATE_LAST_ACTIVITY;
151 STATE_PROTO_ENUMS[STATE_CACHED_ACTIVITY] = ProcessStatsEnums.PROCESS_STATE_CACHED_ACTIVITY;
152 STATE_PROTO_ENUMS[STATE_CACHED_ACTIVITY_CLIENT] =
153 ProcessStatsEnums.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
154 STATE_PROTO_ENUMS[STATE_CACHED_EMPTY] = ProcessStatsEnums.PROCESS_STATE_CACHED_EMPTY;
Richard Gaywood9efa35f2020-02-20 16:06:57 +0000155
156 // Remap states, as defined by ProcessStats.java, to a reduced subset of states for data
157 // aggregation / size reduction purposes.
158 PROCESS_STATS_STATE_TO_AGGREGATED_STATE = new int[STATE_COUNT];
159 PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_PERSISTENT] =
160 ProcessStatsEnums.AGGREGATED_PROCESS_STATE_PERSISTENT;
161 PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_TOP] =
162 ProcessStatsEnums.AGGREGATED_PROCESS_STATE_TOP;
163 PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_IMPORTANT_FOREGROUND] =
164 ProcessStatsEnums.AGGREGATED_PROCESS_STATE_IMPORTANT_FOREGROUND;
165 PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_IMPORTANT_BACKGROUND] =
166 ProcessStatsEnums.AGGREGATED_PROCESS_STATE_BACKGROUND;
167 PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_BACKUP] =
168 ProcessStatsEnums.AGGREGATED_PROCESS_STATE_BACKGROUND;
169 PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_SERVICE] =
170 ProcessStatsEnums.AGGREGATED_PROCESS_STATE_BACKGROUND;
171 // "Restarting" is not a real state, so this shouldn't exist.
172 PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_SERVICE_RESTARTING] =
173 ProcessStatsEnums.AGGREGATED_PROCESS_STATE_UNKNOWN;
174 PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_RECEIVER] =
175 ProcessStatsEnums.AGGREGATED_PROCESS_STATE_RECEIVER;
176 PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_HEAVY_WEIGHT] =
177 ProcessStatsEnums.AGGREGATED_PROCESS_STATE_BACKGROUND;
178 PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_HOME] =
179 ProcessStatsEnums.AGGREGATED_PROCESS_STATE_CACHED;
180 PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_LAST_ACTIVITY] =
181 ProcessStatsEnums.AGGREGATED_PROCESS_STATE_CACHED;
182 PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_CACHED_ACTIVITY] =
183 ProcessStatsEnums.AGGREGATED_PROCESS_STATE_CACHED;
184 PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_CACHED_ACTIVITY_CLIENT] =
185 ProcessStatsEnums.AGGREGATED_PROCESS_STATE_CACHED;
186 PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_CACHED_EMPTY] =
187 ProcessStatsEnums.AGGREGATED_PROCESS_STATE_CACHED;
Yi Jin676d1ac2018-01-25 15:40:28 -0800188 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700189
190 public static final String[] ADJ_SCREEN_NAMES_CSV = new String[] {
191 "off", "on"
192 };
193
194 public static final String[] ADJ_MEM_NAMES_CSV = new String[] {
195 "norm", "mod", "low", "crit"
196 };
197
Yi Jin9680cfa2017-09-15 15:14:43 -0700198 // State enum is defined in frameworks/base/core/proto/android/service/procstats.proto
199 // Update states must sync enum definition as well, the ordering must not be changed.
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700200 static final String[] ADJ_SCREEN_TAGS = new String[] {
201 "0", "1"
202 };
203
Yi Jin676d1ac2018-01-25 15:40:28 -0800204 static final int[] ADJ_SCREEN_PROTO_ENUMS = new int[] {
Yangster-macbac82322018-08-23 14:45:10 -0700205 ProcessStatsEnums.SCREEN_STATE_OFF,
206 ProcessStatsEnums.SCREEN_STATE_ON
Yi Jin676d1ac2018-01-25 15:40:28 -0800207 };
208
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700209 static final String[] ADJ_MEM_TAGS = new String[] {
210 "n", "m", "l", "c"
211 };
212
Yi Jin676d1ac2018-01-25 15:40:28 -0800213 static final int[] ADJ_MEM_PROTO_ENUMS = new int[] {
Yangster-macbac82322018-08-23 14:45:10 -0700214 ProcessStatsEnums.MEMORY_STATE_NORMAL,
215 ProcessStatsEnums.MEMORY_STATE_MODERATE,
216 ProcessStatsEnums.MEMORY_STATE_LOW,
217 ProcessStatsEnums.MEMORY_STATE_CRITICAL
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700218 };
219
220 static final String CSV_SEP = "\t";
221
222 /**
223 * No instantiate
224 */
225 private DumpUtils() {
226 }
227
228 public static void printScreenLabel(PrintWriter pw, int offset) {
229 switch (offset) {
230 case ADJ_NOTHING:
231 pw.print(" ");
232 break;
233 case ADJ_SCREEN_OFF:
234 pw.print("SOff/");
235 break;
236 case ADJ_SCREEN_ON:
Dianne Hackborn7aea7a42018-07-25 08:58:47 -0700237 pw.print(" SOn/");
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700238 break;
239 default:
240 pw.print("????/");
241 break;
242 }
243 }
244
245 public static void printScreenLabelCsv(PrintWriter pw, int offset) {
246 switch (offset) {
247 case ADJ_NOTHING:
248 break;
249 case ADJ_SCREEN_OFF:
250 pw.print(ADJ_SCREEN_NAMES_CSV[0]);
251 break;
252 case ADJ_SCREEN_ON:
253 pw.print(ADJ_SCREEN_NAMES_CSV[1]);
254 break;
255 default:
256 pw.print("???");
257 break;
258 }
259 }
260
261 public static void printMemLabel(PrintWriter pw, int offset, char sep) {
262 switch (offset) {
263 case ADJ_NOTHING:
264 pw.print(" ");
265 if (sep != 0) pw.print(' ');
266 break;
267 case ADJ_MEM_FACTOR_NORMAL:
268 pw.print("Norm");
269 if (sep != 0) pw.print(sep);
270 break;
271 case ADJ_MEM_FACTOR_MODERATE:
Dianne Hackborn7aea7a42018-07-25 08:58:47 -0700272 pw.print(" Mod");
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700273 if (sep != 0) pw.print(sep);
274 break;
275 case ADJ_MEM_FACTOR_LOW:
Dianne Hackborn7aea7a42018-07-25 08:58:47 -0700276 pw.print(" Low");
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700277 if (sep != 0) pw.print(sep);
278 break;
279 case ADJ_MEM_FACTOR_CRITICAL:
280 pw.print("Crit");
281 if (sep != 0) pw.print(sep);
282 break;
283 default:
284 pw.print("????");
285 if (sep != 0) pw.print(sep);
286 break;
287 }
288 }
289
290 public static void printMemLabelCsv(PrintWriter pw, int offset) {
291 if (offset >= ADJ_MEM_FACTOR_NORMAL) {
292 if (offset <= ADJ_MEM_FACTOR_CRITICAL) {
293 pw.print(ADJ_MEM_NAMES_CSV[offset]);
294 } else {
295 pw.print("???");
296 }
297 }
298 }
299
300 public static void printPercent(PrintWriter pw, double fraction) {
301 fraction *= 100;
302 if (fraction < 1) {
303 pw.print(String.format("%.2f", fraction));
304 } else if (fraction < 10) {
305 pw.print(String.format("%.1f", fraction));
306 } else {
307 pw.print(String.format("%.0f", fraction));
308 }
309 pw.print("%");
310 }
311
312 public static void printProcStateTag(PrintWriter pw, int state) {
313 state = printArrayEntry(pw, ADJ_SCREEN_TAGS, state, ADJ_SCREEN_MOD*STATE_COUNT);
314 state = printArrayEntry(pw, ADJ_MEM_TAGS, state, STATE_COUNT);
315 printArrayEntry(pw, STATE_TAGS, state, 1);
316 }
317
Yi Jin9680cfa2017-09-15 15:14:43 -0700318 public static void printProcStateTagProto(ProtoOutputStream proto, long screenId, long memId,
319 long stateId, int state) {
Yi Jin676d1ac2018-01-25 15:40:28 -0800320 state = printProto(proto, screenId, ADJ_SCREEN_PROTO_ENUMS,
321 state, ADJ_SCREEN_MOD * STATE_COUNT);
322 state = printProto(proto, memId, ADJ_MEM_PROTO_ENUMS, state, STATE_COUNT);
323 printProto(proto, stateId, STATE_PROTO_ENUMS, state, 1);
Yi Jin9680cfa2017-09-15 15:14:43 -0700324 }
325
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700326 public static void printAdjTag(PrintWriter pw, int state) {
327 state = printArrayEntry(pw, ADJ_SCREEN_TAGS, state, ADJ_SCREEN_MOD);
328 printArrayEntry(pw, ADJ_MEM_TAGS, state, 1);
329 }
330
Dianne Hackborneaed0ba2018-08-08 17:10:17 -0700331 public static void printProcStateAdjTagProto(ProtoOutputStream proto, long screenId, long memId,
332 int state) {
333 state = printProto(proto, screenId, ADJ_SCREEN_PROTO_ENUMS,
334 state, ADJ_SCREEN_MOD * STATE_COUNT);
335 printProto(proto, memId, ADJ_MEM_PROTO_ENUMS, state, STATE_COUNT);
336 }
337
338 public static void printProcStateDurationProto(ProtoOutputStream proto, long fieldId,
339 int procState, long duration) {
340 final long stateToken = proto.start(fieldId);
341 DumpUtils.printProto(proto, ProcessStatsStateProto.PROCESS_STATE,
342 DumpUtils.STATE_PROTO_ENUMS, procState, 1);
343 proto.write(ProcessStatsStateProto.DURATION_MS, duration);
344 proto.end(stateToken);
Dianne Hackborneaed0ba2018-08-08 17:10:17 -0700345 }
346
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700347 public static void printProcStateTagAndValue(PrintWriter pw, int state, long value) {
348 pw.print(',');
349 printProcStateTag(pw, state);
350 pw.print(':');
351 pw.print(value);
352 }
353
354 public static void printAdjTagAndValue(PrintWriter pw, int state, long value) {
355 pw.print(',');
356 printAdjTag(pw, state);
357 pw.print(':');
358 pw.print(value);
359 }
360
361 public static long dumpSingleTime(PrintWriter pw, String prefix, long[] durations,
362 int curState, long curStartTime, long now) {
363 long totalTime = 0;
364 int printedScreen = -1;
365 for (int iscreen=0; iscreen<ADJ_COUNT; iscreen+=ADJ_SCREEN_MOD) {
366 int printedMem = -1;
367 for (int imem=0; imem<ADJ_MEM_FACTOR_COUNT; imem++) {
368 int state = imem+iscreen;
369 long time = durations[state];
370 String running = "";
371 if (curState == state) {
372 time += now - curStartTime;
373 if (pw != null) {
374 running = " (running)";
375 }
376 }
377 if (time != 0) {
378 if (pw != null) {
379 pw.print(prefix);
380 printScreenLabel(pw, printedScreen != iscreen
381 ? iscreen : STATE_NOTHING);
382 printedScreen = iscreen;
383 printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING, (char)0);
384 printedMem = imem;
385 pw.print(": ");
386 TimeUtils.formatDuration(time, pw); pw.println(running);
387 }
388 totalTime += time;
389 }
390 }
391 }
392 if (totalTime != 0 && pw != null) {
393 pw.print(prefix);
394 pw.print(" TOTAL: ");
395 TimeUtils.formatDuration(totalTime, pw);
396 pw.println();
397 }
398 return totalTime;
399 }
400
401 public static void dumpAdjTimesCheckin(PrintWriter pw, String sep, long[] durations,
402 int curState, long curStartTime, long now) {
403 for (int iscreen=0; iscreen<ADJ_COUNT; iscreen+=ADJ_SCREEN_MOD) {
404 for (int imem=0; imem<ADJ_MEM_FACTOR_COUNT; imem++) {
405 int state = imem+iscreen;
406 long time = durations[state];
407 if (curState == state) {
408 time += now - curStartTime;
409 }
410 if (time != 0) {
411 printAdjTagAndValue(pw, state, time);
412 }
413 }
414 }
415 }
416
417 private static void dumpStateHeadersCsv(PrintWriter pw, String sep, int[] screenStates,
418 int[] memStates, int[] procStates) {
419 final int NS = screenStates != null ? screenStates.length : 1;
420 final int NM = memStates != null ? memStates.length : 1;
421 final int NP = procStates != null ? procStates.length : 1;
422 for (int is=0; is<NS; is++) {
423 for (int im=0; im<NM; im++) {
424 for (int ip=0; ip<NP; ip++) {
425 pw.print(sep);
426 boolean printed = false;
427 if (screenStates != null && screenStates.length > 1) {
428 printScreenLabelCsv(pw, screenStates[is]);
429 printed = true;
430 }
431 if (memStates != null && memStates.length > 1) {
432 if (printed) {
433 pw.print("-");
434 }
435 printMemLabelCsv(pw, memStates[im]);
436 printed = true;
437 }
438 if (procStates != null && procStates.length > 1) {
439 if (printed) {
440 pw.print("-");
441 }
442 pw.print(STATE_NAMES_CSV[procStates[ip]]);
443 }
444 }
445 }
446 }
447 }
448
Dianne Hackborn2aec55a2018-06-26 10:35:35 -0700449 public static void dumpProcessSummaryLocked(PrintWriter pw, String prefix, String header,
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700450 ArrayList<ProcessState> procs, int[] screenStates, int[] memStates, int[] procStates,
451 long now, long totalTime) {
452 for (int i=procs.size()-1; i>=0; i--) {
453 final ProcessState proc = procs.get(i);
Dianne Hackborn2aec55a2018-06-26 10:35:35 -0700454 proc.dumpSummary(pw, prefix, header, screenStates, memStates, procStates, now,
455 totalTime);
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700456 }
457 }
458
459 public static void dumpProcessListCsv(PrintWriter pw, ArrayList<ProcessState> procs,
460 boolean sepScreenStates, int[] screenStates, boolean sepMemStates, int[] memStates,
461 boolean sepProcStates, int[] procStates, long now) {
462 pw.print("process");
463 pw.print(CSV_SEP);
464 pw.print("uid");
465 pw.print(CSV_SEP);
466 pw.print("vers");
467 dumpStateHeadersCsv(pw, CSV_SEP, sepScreenStates ? screenStates : null,
468 sepMemStates ? memStates : null,
469 sepProcStates ? procStates : null);
470 pw.println();
471 for (int i=procs.size()-1; i>=0; i--) {
472 ProcessState proc = procs.get(i);
473 pw.print(proc.getName());
474 pw.print(CSV_SEP);
475 UserHandle.formatUid(pw, proc.getUid());
476 pw.print(CSV_SEP);
477 pw.print(proc.getVersion());
478 proc.dumpCsv(pw, sepScreenStates, screenStates, sepMemStates,
479 memStates, sepProcStates, procStates, now);
480 pw.println();
481 }
482 }
483
484 public static int printArrayEntry(PrintWriter pw, String[] array, int value, int mod) {
485 int index = value/mod;
486 if (index >= 0 && index < array.length) {
487 pw.print(array[index]);
488 } else {
489 pw.print('?');
490 }
491 return value - index*mod;
492 }
493
Yi Jin676d1ac2018-01-25 15:40:28 -0800494 public static int printProto(ProtoOutputStream proto, long fieldId,
495 int[] enums, int value, int mod) {
Yi Jin9680cfa2017-09-15 15:14:43 -0700496 int index = value/mod;
Yi Jin676d1ac2018-01-25 15:40:28 -0800497 if (index >= 0 && index < enums.length) {
498 proto.write(fieldId, enums[index]);
Yi Jin9680cfa2017-09-15 15:14:43 -0700499 } // else enum default is always zero in proto3
500 return value - index*mod;
501 }
502
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700503 public static String collapseString(String pkgName, String itemName) {
504 if (itemName.startsWith(pkgName)) {
505 final int ITEMLEN = itemName.length();
506 final int PKGLEN = pkgName.length();
507 if (ITEMLEN == PKGLEN) {
508 return "";
509 } else if (ITEMLEN >= PKGLEN) {
510 if (itemName.charAt(PKGLEN) == '.') {
511 return itemName.substring(PKGLEN);
512 }
513 }
514 }
515 return itemName;
516 }
Richard Gaywood9efa35f2020-02-20 16:06:57 +0000517
518 /**
519 * Aggregate process states to reduce size of statistics logs.
520 *
521 * <p>Involves unpacking the three parts of state (process state / device memory state /
522 * screen state), manipulating the elements, then re-packing the new values into a single
523 * int. This integer is guaranteed to be unique for any given combination of state elements.
524 *
525 * @param curState current state as used in mCurState in {@class ProcessState} ie. a value
526 * combined from the process's state, the device's memory pressure state, and
527 * the device's screen on/off state.
528 * @return an integer representing the combination of screen state and process state, where
529 * process state has been aggregated.
530 */
531 public static int aggregateCurrentProcessState(int curState) {
532 int screenStateIndex = curState / (ADJ_SCREEN_MOD * STATE_COUNT);
533 // extract process state from the compound state variable (discarding memory state)
534 int procStateIndex = curState % STATE_COUNT;
535
536 // Remap process state per array above.
Richard Gaywood863a7212020-03-16 17:49:54 +0000537 try {
538 procStateIndex = PROCESS_STATS_STATE_TO_AGGREGATED_STATE[procStateIndex];
539 } catch (IndexOutOfBoundsException e) {
540 procStateIndex = ProcessStatsEnums.AGGREGATED_PROCESS_STATE_UNKNOWN;
541 }
Richard Gaywood9efa35f2020-02-20 16:06:57 +0000542
543 // Pack screen & process state using bit shifting
Richard Gaywood863a7212020-03-16 17:49:54 +0000544 return (procStateIndex << 0xf) | screenStateIndex;
Richard Gaywood9efa35f2020-02-20 16:06:57 +0000545 }
Richard Gaywood57dc86a2020-03-12 17:57:10 +0000546
547 /** Print aggregated tags generated via {@code #aggregateCurrentProcessState}. */
548 public static void printAggregatedProcStateTagProto(ProtoOutputStream proto, long screenId,
549 long stateId, int state) {
Richard Gaywood863a7212020-03-16 17:49:54 +0000550 // screen state is in lowest 0xf bits, process state is in next 0xf bits up
551
552 try {
553 proto.write(stateId, STATE_PROTO_ENUMS[state >> 0xf]);
554 } catch (IndexOutOfBoundsException e) {
555 proto.write(stateId, ProcessStatsEnums.PROCESS_STATE_UNKNOWN);
556 }
557
558 try {
559 proto.write(screenId, ADJ_SCREEN_PROTO_ENUMS[state & 0xf]);
560 } catch (IndexOutOfBoundsException e) {
561 proto.write(screenId, ProcessStatsEnums.SCREEN_STATE_UNKNOWN);
562 }
Richard Gaywood57dc86a2020-03-12 17:57:10 +0000563 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700564}