blob: 009b1e0fa829d1d25f9876c2a325378c22f496cc [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
Dianne Hackborn95031ef2018-07-09 09:09:05 -070019import android.content.ComponentName;
Dianne Hackbornef0a4022016-05-11 14:21:07 -070020import android.os.Debug;
Joe Onorato4eb64fd2016-03-21 15:30:09 -070021import android.os.Parcel;
22import android.os.Parcelable;
23import android.os.SystemClock;
24import android.os.SystemProperties;
25import android.os.UserHandle;
Dianne Hackborn9f669bf2019-01-14 16:21:25 -080026import android.service.procstats.ProcessStatsAvailablePagesProto;
Dianne Hackborneaed0ba2018-08-08 17:10:17 -070027import android.service.procstats.ProcessStatsPackageProto;
Yi Jin9680cfa2017-09-15 15:14:43 -070028import android.service.procstats.ProcessStatsSectionProto;
Joe Onorato4eb64fd2016-03-21 15:30:09 -070029import android.text.format.DateFormat;
30import android.util.ArrayMap;
31import android.util.ArraySet;
32import android.util.DebugUtils;
Dianne Hackborn3accca02013-09-20 09:32:11 -070033import android.util.LongSparseArray;
Dianne Hackborn442e9fa2019-08-07 10:28:59 -070034import android.util.Pair;
Joe Onorato4eb64fd2016-03-21 15:30:09 -070035import android.util.Slog;
36import android.util.SparseArray;
37import android.util.TimeUtils;
Yi Jin9680cfa2017-09-15 15:14:43 -070038import android.util.proto.ProtoOutputStream;
Joe Onorato4eb64fd2016-03-21 15:30:09 -070039
40import com.android.internal.app.ProcessMap;
Joe Onorato4eb64fd2016-03-21 15:30:09 -070041
42import dalvik.system.VMRuntime;
Joe Onorato4eb64fd2016-03-21 15:30:09 -070043
Joe Onoratoc23befa2016-05-19 15:46:00 -070044import java.io.BufferedReader;
45import java.io.FileReader;
Joe Onorato4eb64fd2016-03-21 15:30:09 -070046import java.io.IOException;
47import java.io.InputStream;
48import java.io.PrintWriter;
49import java.util.ArrayList;
50import java.util.Arrays;
51import java.util.Collections;
Dianne Hackborn442e9fa2019-08-07 10:28:59 -070052import java.util.Comparator;
Joe Onorato4eb64fd2016-03-21 15:30:09 -070053import java.util.Objects;
Joe Onoratoc23befa2016-05-19 15:46:00 -070054import java.util.regex.Matcher;
Rafal Slawik91b9e0b2018-08-10 15:36:31 +010055import java.util.regex.Pattern;
Joe Onorato4eb64fd2016-03-21 15:30:09 -070056
57public final class ProcessStats implements Parcelable {
58 public static final String TAG = "ProcessStats";
59 static final boolean DEBUG = false;
60 static final boolean DEBUG_PARCEL = false;
61
62 public static final String SERVICE_NAME = "procstats";
63
64 // How often the service commits its data, giving the minimum batching
65 // that is done.
66 public static long COMMIT_PERIOD = 3*60*60*1000; // Commit current stats every 3 hours
67
68 // Minimum uptime period before committing. If the COMMIT_PERIOD has elapsed but
69 // the total uptime has not exceeded this amount, then the commit will be held until
70 // it is reached.
71 public static long COMMIT_UPTIME_PERIOD = 60*60*1000; // Must have at least 1 hour elapsed
72
73 public static final int STATE_NOTHING = -1;
74 public static final int STATE_PERSISTENT = 0;
75 public static final int STATE_TOP = 1;
76 public static final int STATE_IMPORTANT_FOREGROUND = 2;
77 public static final int STATE_IMPORTANT_BACKGROUND = 3;
78 public static final int STATE_BACKUP = 4;
Dianne Hackbornf097d422017-12-15 16:32:19 -080079 public static final int STATE_SERVICE = 5;
80 public static final int STATE_SERVICE_RESTARTING = 6;
81 public static final int STATE_RECEIVER = 7;
82 public static final int STATE_HEAVY_WEIGHT = 8;
Joe Onorato4eb64fd2016-03-21 15:30:09 -070083 public static final int STATE_HOME = 9;
84 public static final int STATE_LAST_ACTIVITY = 10;
85 public static final int STATE_CACHED_ACTIVITY = 11;
86 public static final int STATE_CACHED_ACTIVITY_CLIENT = 12;
87 public static final int STATE_CACHED_EMPTY = 13;
88 public static final int STATE_COUNT = STATE_CACHED_EMPTY+1;
89
90 public static final int PSS_SAMPLE_COUNT = 0;
91 public static final int PSS_MINIMUM = 1;
92 public static final int PSS_AVERAGE = 2;
93 public static final int PSS_MAXIMUM = 3;
94 public static final int PSS_USS_MINIMUM = 4;
95 public static final int PSS_USS_AVERAGE = 5;
96 public static final int PSS_USS_MAXIMUM = 6;
Dianne Hackborne17b4452018-01-10 13:15:40 -080097 public static final int PSS_RSS_MINIMUM = 7;
98 public static final int PSS_RSS_AVERAGE = 8;
99 public static final int PSS_RSS_MAXIMUM = 9;
100 public static final int PSS_COUNT = PSS_RSS_MAXIMUM+1;
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700101
102 public static final int SYS_MEM_USAGE_SAMPLE_COUNT = 0;
103 public static final int SYS_MEM_USAGE_CACHED_MINIMUM = 1;
104 public static final int SYS_MEM_USAGE_CACHED_AVERAGE = 2;
105 public static final int SYS_MEM_USAGE_CACHED_MAXIMUM = 3;
106 public static final int SYS_MEM_USAGE_FREE_MINIMUM = 4;
107 public static final int SYS_MEM_USAGE_FREE_AVERAGE = 5;
108 public static final int SYS_MEM_USAGE_FREE_MAXIMUM = 6;
109 public static final int SYS_MEM_USAGE_ZRAM_MINIMUM = 7;
110 public static final int SYS_MEM_USAGE_ZRAM_AVERAGE = 8;
111 public static final int SYS_MEM_USAGE_ZRAM_MAXIMUM = 9;
112 public static final int SYS_MEM_USAGE_KERNEL_MINIMUM = 10;
113 public static final int SYS_MEM_USAGE_KERNEL_AVERAGE = 11;
114 public static final int SYS_MEM_USAGE_KERNEL_MAXIMUM = 12;
115 public static final int SYS_MEM_USAGE_NATIVE_MINIMUM = 13;
116 public static final int SYS_MEM_USAGE_NATIVE_AVERAGE = 14;
117 public static final int SYS_MEM_USAGE_NATIVE_MAXIMUM = 15;
118 public static final int SYS_MEM_USAGE_COUNT = SYS_MEM_USAGE_NATIVE_MAXIMUM+1;
119
120 public static final int ADJ_NOTHING = -1;
121 public static final int ADJ_MEM_FACTOR_NORMAL = 0;
122 public static final int ADJ_MEM_FACTOR_MODERATE = 1;
123 public static final int ADJ_MEM_FACTOR_LOW = 2;
124 public static final int ADJ_MEM_FACTOR_CRITICAL = 3;
125 public static final int ADJ_MEM_FACTOR_COUNT = ADJ_MEM_FACTOR_CRITICAL+1;
126 public static final int ADJ_SCREEN_MOD = ADJ_MEM_FACTOR_COUNT;
127 public static final int ADJ_SCREEN_OFF = 0;
128 public static final int ADJ_SCREEN_ON = ADJ_SCREEN_MOD;
129 public static final int ADJ_COUNT = ADJ_SCREEN_ON*2;
130
131 public static final int FLAG_COMPLETE = 1<<0;
132 public static final int FLAG_SHUTDOWN = 1<<1;
133 public static final int FLAG_SYSPROPS = 1<<2;
134
Dianne Hackborne17b4452018-01-10 13:15:40 -0800135 public static final int ADD_PSS_INTERNAL_SINGLE = 0;
136 public static final int ADD_PSS_INTERNAL_ALL_MEM = 1;
137 public static final int ADD_PSS_INTERNAL_ALL_POLL = 2;
138 public static final int ADD_PSS_EXTERNAL = 3;
139 public static final int ADD_PSS_EXTERNAL_SLOW = 4;
Dianne Hackborn052e3142017-12-19 16:08:30 -0800140
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700141 public static final int[] ALL_MEM_ADJ = new int[] { ADJ_MEM_FACTOR_NORMAL,
142 ADJ_MEM_FACTOR_MODERATE, ADJ_MEM_FACTOR_LOW, ADJ_MEM_FACTOR_CRITICAL };
143
144 public static final int[] ALL_SCREEN_ADJ = new int[] { ADJ_SCREEN_OFF, ADJ_SCREEN_ON };
145
146 public static final int[] NON_CACHED_PROC_STATES = new int[] {
147 STATE_PERSISTENT, STATE_TOP, STATE_IMPORTANT_FOREGROUND,
Dianne Hackbornf097d422017-12-15 16:32:19 -0800148 STATE_IMPORTANT_BACKGROUND, STATE_BACKUP,
149 STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER, STATE_HEAVY_WEIGHT
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700150 };
151
152 public static final int[] BACKGROUND_PROC_STATES = new int[] {
153 STATE_IMPORTANT_FOREGROUND, STATE_IMPORTANT_BACKGROUND, STATE_BACKUP,
154 STATE_HEAVY_WEIGHT, STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER
155 };
156
157 public static final int[] ALL_PROC_STATES = new int[] { STATE_PERSISTENT,
158 STATE_TOP, STATE_IMPORTANT_FOREGROUND, STATE_IMPORTANT_BACKGROUND, STATE_BACKUP,
Dianne Hackbornf097d422017-12-15 16:32:19 -0800159 STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER,
160 STATE_HEAVY_WEIGHT, STATE_HOME, STATE_LAST_ACTIVITY, STATE_CACHED_ACTIVITY,
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700161 STATE_CACHED_ACTIVITY_CLIENT, STATE_CACHED_EMPTY
162 };
163
Chenjie Yu4e028d02018-09-14 16:24:26 -0700164 // Should report process stats.
165 public static final int REPORT_PROC_STATS = 0x01;
166 // Should report package process stats.
167 public static final int REPORT_PKG_PROC_STATS = 0x02;
168 // Should report package service stats.
169 public static final int REPORT_PKG_SVC_STATS = 0x04;
170 // Should report package association stats.
171 public static final int REPORT_PKG_ASC_STATS = 0x08;
172 // Should report package stats.
173 public static final int REPORT_PKG_STATS = 0x0E;
174 // Should report all stats.
175 public static final int REPORT_ALL = 0x0F;
176
177 public static final int[] OPTIONS =
178 {REPORT_PROC_STATS, REPORT_PKG_PROC_STATS, REPORT_PKG_SVC_STATS, REPORT_PKG_ASC_STATS,
179 REPORT_PKG_STATS, REPORT_ALL};
180 public static final String[] OPTIONS_STR =
181 {"proc", "pkg-proc", "pkg-svc", "pkg-asc", "pkg-all", "all"};
182
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700183 // Current version of the parcel format.
Dianne Hackborn442e9fa2019-08-07 10:28:59 -0700184 private static final int PARCEL_VERSION = 38;
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700185 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
186 private static final int MAGIC = 0x50535454;
187
188 public String mReadError;
189 public String mTimePeriodStartClockStr;
190 public int mFlags;
191
Dianne Hackborn3accca02013-09-20 09:32:11 -0700192 public final ProcessMap<LongSparseArray<PackageState>> mPackages = new ProcessMap<>();
193 public final ProcessMap<ProcessState> mProcesses = new ProcessMap<>();
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700194
Dianne Hackborn95031ef2018-07-09 09:09:05 -0700195 public final ArrayList<AssociationState.SourceState> mTrackingAssociations = new ArrayList<>();
196
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700197 public final long[] mMemFactorDurations = new long[ADJ_COUNT];
198 public int mMemFactor = STATE_NOTHING;
199 public long mStartTime;
200
Dianne Hackborn442e9fa2019-08-07 10:28:59 -0700201 // Number of individual stats that have been aggregated to create this one.
202 public int mNumAggregated = 1;
203
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700204 public long mTimePeriodStartClock;
205 public long mTimePeriodStartRealtime;
206 public long mTimePeriodEndRealtime;
207 public long mTimePeriodStartUptime;
208 public long mTimePeriodEndUptime;
209 String mRuntime;
210 boolean mRunning;
211
Dianne Hackbornef0a4022016-05-11 14:21:07 -0700212 boolean mHasSwappedOutPss;
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700213
Dianne Hackborne17b4452018-01-10 13:15:40 -0800214 // Count and total time expended doing "quick" single pss computations for internal use.
215 public long mInternalSinglePssCount;
216 public long mInternalSinglePssTime;
217
218 // Count and total time expended doing "quick" all mem pss computations for internal use.
219 public long mInternalAllMemPssCount;
220 public long mInternalAllMemPssTime;
221
222 // Count and total time expended doing "quick" all poll pss computations for internal use.
223 public long mInternalAllPollPssCount;
224 public long mInternalAllPollPssTime;
Dianne Hackborn052e3142017-12-19 16:08:30 -0800225
226 // Count and total time expended doing "quick" pss computations due to external requests.
227 public long mExternalPssCount;
228 public long mExternalPssTime;
229
230 // Count and total time expended doing full/slow pss computations due to external requests.
231 public long mExternalSlowPssCount;
232 public long mExternalSlowPssTime;
233
Dianne Hackbornef0a4022016-05-11 14:21:07 -0700234 public final SparseMappingTable mTableData = new SparseMappingTable();
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700235
236 public final long[] mSysMemUsageArgs = new long[SYS_MEM_USAGE_COUNT];
237 public final SysMemUsageTable mSysMemUsage = new SysMemUsageTable(mTableData);
238
239 // For writing parcels.
240 ArrayMap<String, Integer> mCommonStringToIndex;
241
242 // For reading parcels.
243 ArrayList<String> mIndexToCommonString;
244
Joe Onoratoc23befa2016-05-19 15:46:00 -0700245 private static final Pattern sPageTypeRegex = Pattern.compile(
Dianne Hackborn9f669bf2019-01-14 16:21:25 -0800246 "^Node\\s+(\\d+),.* zone\\s+(\\w+),.* type\\s+(\\w+)\\s+([\\s\\d]+?)\\s*$");
247 private final ArrayList<Integer> mPageTypeNodes = new ArrayList<>();
248 private final ArrayList<String> mPageTypeZones = new ArrayList<>();
249 private final ArrayList<String> mPageTypeLabels = new ArrayList<>();
250 private final ArrayList<int[]> mPageTypeSizes = new ArrayList<>();
Joe Onoratoc23befa2016-05-19 15:46:00 -0700251
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700252 public ProcessStats(boolean running) {
253 mRunning = running;
254 reset();
Dianne Hackbornef0a4022016-05-11 14:21:07 -0700255 if (running) {
256 // If we are actively running, we need to determine whether the system is
257 // collecting swap pss data.
258 Debug.MemoryInfo info = new Debug.MemoryInfo();
259 Debug.getMemoryInfo(android.os.Process.myPid(), info);
260 mHasSwappedOutPss = info.hasSwappedOutPss();
261 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700262 }
263
264 public ProcessStats(Parcel in) {
265 reset();
266 readFromParcel(in);
267 }
268
Richard Gaywood3ee75572020-02-18 15:59:06 +0000269 /**
270 * No-arg constructor is for use in AIDL-derived stubs.
271 *
272 * <p>This defaults to the non-running state, so is equivalent to ProcessStats(false).
273 */
274 public ProcessStats() {
275 this(false);
276 }
277
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700278 public void add(ProcessStats other) {
Dianne Hackborn3accca02013-09-20 09:32:11 -0700279 ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap =
280 other.mPackages.getMap();
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700281 for (int ip=0; ip<pkgMap.size(); ip++) {
282 final String pkgName = pkgMap.keyAt(ip);
Dianne Hackborn3accca02013-09-20 09:32:11 -0700283 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700284 for (int iu=0; iu<uids.size(); iu++) {
285 final int uid = uids.keyAt(iu);
Dianne Hackborn3accca02013-09-20 09:32:11 -0700286 final LongSparseArray<PackageState> versions = uids.valueAt(iu);
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700287 for (int iv=0; iv<versions.size(); iv++) {
Dianne Hackborn3accca02013-09-20 09:32:11 -0700288 final long vers = versions.keyAt(iv);
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700289 final PackageState otherState = versions.valueAt(iv);
290 final int NPROCS = otherState.mProcesses.size();
291 final int NSRVS = otherState.mServices.size();
Dianne Hackborn2aec55a2018-06-26 10:35:35 -0700292 final int NASCS = otherState.mAssociations.size();
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700293 for (int iproc=0; iproc<NPROCS; iproc++) {
294 ProcessState otherProc = otherState.mProcesses.valueAt(iproc);
295 if (otherProc.getCommonProcess() != otherProc) {
296 if (DEBUG) Slog.d(TAG, "Adding pkg " + pkgName + " uid " + uid
297 + " vers " + vers + " proc " + otherProc.getName());
298 ProcessState thisProc = getProcessStateLocked(pkgName, uid, vers,
299 otherProc.getName());
300 if (thisProc.getCommonProcess() == thisProc) {
301 if (DEBUG) Slog.d(TAG, "Existing process is single-package, splitting");
302 thisProc.setMultiPackage(true);
303 long now = SystemClock.uptimeMillis();
304 final PackageState pkgState = getPackageStateLocked(pkgName, uid,
305 vers);
306 thisProc = thisProc.clone(now);
307 pkgState.mProcesses.put(thisProc.getName(), thisProc);
308 }
309 thisProc.add(otherProc);
310 }
311 }
312 for (int isvc=0; isvc<NSRVS; isvc++) {
313 ServiceState otherSvc = otherState.mServices.valueAt(isvc);
314 if (DEBUG) Slog.d(TAG, "Adding pkg " + pkgName + " uid " + uid
315 + " service " + otherSvc.getName());
316 ServiceState thisSvc = getServiceStateLocked(pkgName, uid, vers,
317 otherSvc.getProcessName(), otherSvc.getName());
318 thisSvc.add(otherSvc);
319 }
Dianne Hackborn2aec55a2018-06-26 10:35:35 -0700320 for (int iasc=0; iasc<NASCS; iasc++) {
321 AssociationState otherAsc = otherState.mAssociations.valueAt(iasc);
322 if (DEBUG) Slog.d(TAG, "Adding pkg " + pkgName + " uid " + uid
323 + " association " + otherAsc.getName());
324 AssociationState thisAsc = getAssociationStateLocked(pkgName, uid, vers,
325 otherAsc.getProcessName(), otherAsc.getName());
326 thisAsc.add(otherAsc);
327 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700328 }
329 }
330 }
331
332 ArrayMap<String, SparseArray<ProcessState>> procMap = other.mProcesses.getMap();
333 for (int ip=0; ip<procMap.size(); ip++) {
334 SparseArray<ProcessState> uids = procMap.valueAt(ip);
335 for (int iu=0; iu<uids.size(); iu++) {
336 int uid = uids.keyAt(iu);
337 ProcessState otherProc = uids.valueAt(iu);
338 final String name = otherProc.getName();
339 final String pkg = otherProc.getPackage();
Dianne Hackborn3accca02013-09-20 09:32:11 -0700340 final long vers = otherProc.getVersion();
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700341 ProcessState thisProc = mProcesses.get(name, uid);
342 if (DEBUG) Slog.d(TAG, "Adding uid " + uid + " proc " + name);
343 if (thisProc == null) {
344 if (DEBUG) Slog.d(TAG, "Creating new process!");
345 thisProc = new ProcessState(this, pkg, uid, vers, name);
346 mProcesses.put(name, uid, thisProc);
347 PackageState thisState = getPackageStateLocked(pkg, uid, vers);
348 if (!thisState.mProcesses.containsKey(name)) {
349 thisState.mProcesses.put(name, thisProc);
350 }
351 }
352 thisProc.add(otherProc);
353 }
354 }
355
356 for (int i=0; i<ADJ_COUNT; i++) {
357 if (DEBUG) Slog.d(TAG, "Total duration #" + i + " inc by "
358 + other.mMemFactorDurations[i] + " from "
359 + mMemFactorDurations[i]);
360 mMemFactorDurations[i] += other.mMemFactorDurations[i];
361 }
362
363 mSysMemUsage.mergeStats(other.mSysMemUsage);
364
Dianne Hackborn442e9fa2019-08-07 10:28:59 -0700365 mNumAggregated += other.mNumAggregated;
366
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700367 if (other.mTimePeriodStartClock < mTimePeriodStartClock) {
368 mTimePeriodStartClock = other.mTimePeriodStartClock;
369 mTimePeriodStartClockStr = other.mTimePeriodStartClockStr;
370 }
371 mTimePeriodEndRealtime += other.mTimePeriodEndRealtime - other.mTimePeriodStartRealtime;
372 mTimePeriodEndUptime += other.mTimePeriodEndUptime - other.mTimePeriodStartUptime;
Dianne Hackbornef0a4022016-05-11 14:21:07 -0700373
Dianne Hackborne17b4452018-01-10 13:15:40 -0800374 mInternalSinglePssCount += other.mInternalSinglePssCount;
375 mInternalSinglePssTime += other.mInternalSinglePssTime;
376 mInternalAllMemPssCount += other.mInternalAllMemPssCount;
377 mInternalAllMemPssTime += other.mInternalAllMemPssTime;
378 mInternalAllPollPssCount += other.mInternalAllPollPssCount;
379 mInternalAllPollPssTime += other.mInternalAllPollPssTime;
Dianne Hackborn052e3142017-12-19 16:08:30 -0800380 mExternalPssCount += other.mExternalPssCount;
381 mExternalPssTime += other.mExternalPssTime;
382 mExternalSlowPssCount += other.mExternalSlowPssCount;
383 mExternalSlowPssTime += other.mExternalSlowPssTime;
384
Dianne Hackbornef0a4022016-05-11 14:21:07 -0700385 mHasSwappedOutPss |= other.mHasSwappedOutPss;
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700386 }
387
388 public void addSysMemUsage(long cachedMem, long freeMem, long zramMem, long kernelMem,
389 long nativeMem) {
390 if (mMemFactor != STATE_NOTHING) {
391 int state = mMemFactor * STATE_COUNT;
392 mSysMemUsageArgs[SYS_MEM_USAGE_SAMPLE_COUNT] = 1;
393 for (int i=0; i<3; i++) {
394 mSysMemUsageArgs[SYS_MEM_USAGE_CACHED_MINIMUM + i] = cachedMem;
395 mSysMemUsageArgs[SYS_MEM_USAGE_FREE_MINIMUM + i] = freeMem;
396 mSysMemUsageArgs[SYS_MEM_USAGE_ZRAM_MINIMUM + i] = zramMem;
397 mSysMemUsageArgs[SYS_MEM_USAGE_KERNEL_MINIMUM + i] = kernelMem;
398 mSysMemUsageArgs[SYS_MEM_USAGE_NATIVE_MINIMUM + i] = nativeMem;
399 }
400 mSysMemUsage.mergeStats(state, mSysMemUsageArgs, 0);
401 }
402 }
403
404 public static final Parcelable.Creator<ProcessStats> CREATOR
405 = new Parcelable.Creator<ProcessStats>() {
406 public ProcessStats createFromParcel(Parcel in) {
407 return new ProcessStats(in);
408 }
409
410 public ProcessStats[] newArray(int size) {
411 return new ProcessStats[size];
412 }
413 };
414
415 public void computeTotalMemoryUse(TotalMemoryUseCollection data, long now) {
416 data.totalTime = 0;
417 for (int i=0; i<STATE_COUNT; i++) {
418 data.processStateWeight[i] = 0;
419 data.processStatePss[i] = 0;
420 data.processStateTime[i] = 0;
421 data.processStateSamples[i] = 0;
422 }
423 for (int i=0; i<SYS_MEM_USAGE_COUNT; i++) {
424 data.sysMemUsage[i] = 0;
425 }
426 data.sysMemCachedWeight = 0;
427 data.sysMemFreeWeight = 0;
428 data.sysMemZRamWeight = 0;
429 data.sysMemKernelWeight = 0;
430 data.sysMemNativeWeight = 0;
431 data.sysMemSamples = 0;
432 final long[] totalMemUsage = mSysMemUsage.getTotalMemUsage();
433 for (int is=0; is<data.screenStates.length; is++) {
434 for (int im=0; im<data.memStates.length; im++) {
435 int memBucket = data.screenStates[is] + data.memStates[im];
436 int stateBucket = memBucket * STATE_COUNT;
437 long memTime = mMemFactorDurations[memBucket];
438 if (mMemFactor == memBucket) {
439 memTime += now - mStartTime;
440 }
441 data.totalTime += memTime;
442 final int sysKey = mSysMemUsage.getKey((byte)stateBucket);
443 long[] longs = totalMemUsage;
444 int idx = 0;
445 if (sysKey != SparseMappingTable.INVALID_KEY) {
446 final long[] tmpLongs = mSysMemUsage.getArrayForKey(sysKey);
447 final int tmpIndex = SparseMappingTable.getIndexFromKey(sysKey);
448 if (tmpLongs[tmpIndex+SYS_MEM_USAGE_SAMPLE_COUNT] >= 3) {
449 SysMemUsageTable.mergeSysMemUsage(data.sysMemUsage, 0, longs, idx);
450 longs = tmpLongs;
451 idx = tmpIndex;
452 }
453 }
454 data.sysMemCachedWeight += longs[idx+SYS_MEM_USAGE_CACHED_AVERAGE]
455 * (double)memTime;
456 data.sysMemFreeWeight += longs[idx+SYS_MEM_USAGE_FREE_AVERAGE]
457 * (double)memTime;
Dianne Hackbornef0a4022016-05-11 14:21:07 -0700458 data.sysMemZRamWeight += longs[idx + SYS_MEM_USAGE_ZRAM_AVERAGE]
459 * (double) memTime;
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700460 data.sysMemKernelWeight += longs[idx+SYS_MEM_USAGE_KERNEL_AVERAGE]
461 * (double)memTime;
462 data.sysMemNativeWeight += longs[idx+SYS_MEM_USAGE_NATIVE_AVERAGE]
463 * (double)memTime;
464 data.sysMemSamples += longs[idx+SYS_MEM_USAGE_SAMPLE_COUNT];
465 }
466 }
Dianne Hackbornef0a4022016-05-11 14:21:07 -0700467 data.hasSwappedOutPss = mHasSwappedOutPss;
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700468 ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
469 for (int iproc=0; iproc<procMap.size(); iproc++) {
470 SparseArray<ProcessState> uids = procMap.valueAt(iproc);
471 for (int iu=0; iu<uids.size(); iu++) {
472 final ProcessState proc = uids.valueAt(iu);
473 proc.aggregatePss(data, now);
474 }
475 }
476 }
477
478 public void reset() {
479 if (DEBUG) Slog.d(TAG, "Resetting state of " + mTimePeriodStartClockStr);
480 resetCommon();
481 mPackages.getMap().clear();
482 mProcesses.getMap().clear();
483 mMemFactor = STATE_NOTHING;
484 mStartTime = 0;
485 if (DEBUG) Slog.d(TAG, "State reset; now " + mTimePeriodStartClockStr);
486 }
487
488 public void resetSafely() {
489 if (DEBUG) Slog.d(TAG, "Safely resetting state of " + mTimePeriodStartClockStr);
490 resetCommon();
491
492 // First initialize use count of all common processes.
493 final long now = SystemClock.uptimeMillis();
494 final ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
495 for (int ip=procMap.size()-1; ip>=0; ip--) {
496 final SparseArray<ProcessState> uids = procMap.valueAt(ip);
497 for (int iu=uids.size()-1; iu>=0; iu--) {
498 uids.valueAt(iu).tmpNumInUse = 0;
499 }
500 }
501
502 // Next reset or prune all per-package processes, and for the ones that are reset
503 // track this back to the common processes.
Dianne Hackborn3accca02013-09-20 09:32:11 -0700504 final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap =
505 mPackages.getMap();
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700506 for (int ip=pkgMap.size()-1; ip>=0; ip--) {
Dianne Hackborn3accca02013-09-20 09:32:11 -0700507 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700508 for (int iu=uids.size()-1; iu>=0; iu--) {
Dianne Hackborn3accca02013-09-20 09:32:11 -0700509 final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu);
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700510 for (int iv=vpkgs.size()-1; iv>=0; iv--) {
511 final PackageState pkgState = vpkgs.valueAt(iv);
512 for (int iproc=pkgState.mProcesses.size()-1; iproc>=0; iproc--) {
513 final ProcessState ps = pkgState.mProcesses.valueAt(iproc);
514 if (ps.isInUse()) {
515 ps.resetSafely(now);
516 ps.getCommonProcess().tmpNumInUse++;
517 ps.getCommonProcess().tmpFoundSubProc = ps;
518 } else {
519 pkgState.mProcesses.valueAt(iproc).makeDead();
520 pkgState.mProcesses.removeAt(iproc);
521 }
522 }
523 for (int isvc=pkgState.mServices.size()-1; isvc>=0; isvc--) {
524 final ServiceState ss = pkgState.mServices.valueAt(isvc);
525 if (ss.isInUse()) {
526 ss.resetSafely(now);
527 } else {
528 pkgState.mServices.removeAt(isvc);
529 }
530 }
Dianne Hackborn2aec55a2018-06-26 10:35:35 -0700531 for (int iasc=pkgState.mAssociations.size()-1; iasc>=0; iasc--) {
532 final AssociationState as = pkgState.mAssociations.valueAt(iasc);
533 if (as.isInUse()) {
534 as.resetSafely(now);
535 } else {
536 pkgState.mAssociations.removeAt(iasc);
537 }
538 }
539 if (pkgState.mProcesses.size() <= 0 && pkgState.mServices.size() <= 0
540 && pkgState.mAssociations.size() <= 0) {
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700541 vpkgs.removeAt(iv);
542 }
543 }
544 if (vpkgs.size() <= 0) {
545 uids.removeAt(iu);
546 }
547 }
548 if (uids.size() <= 0) {
549 pkgMap.removeAt(ip);
550 }
551 }
552
553 // Finally prune out any common processes that are no longer in use.
554 for (int ip=procMap.size()-1; ip>=0; ip--) {
555 final SparseArray<ProcessState> uids = procMap.valueAt(ip);
556 for (int iu=uids.size()-1; iu>=0; iu--) {
557 ProcessState ps = uids.valueAt(iu);
558 if (ps.isInUse() || ps.tmpNumInUse > 0) {
559 // If this is a process for multiple packages, we could at this point
560 // be back down to one package. In that case, we want to revert back
561 // to a single shared ProcessState. We can do this by converting the
562 // current package-specific ProcessState up to the shared ProcessState,
563 // throwing away the current one we have here (because nobody else is
564 // using it).
565 if (!ps.isActive() && ps.isMultiPackage() && ps.tmpNumInUse == 1) {
566 // Here we go...
567 ps = ps.tmpFoundSubProc;
568 ps.makeStandalone();
569 uids.setValueAt(iu, ps);
570 } else {
571 ps.resetSafely(now);
572 }
573 } else {
574 ps.makeDead();
575 uids.removeAt(iu);
576 }
577 }
578 if (uids.size() <= 0) {
579 procMap.removeAt(ip);
580 }
581 }
582
583 mStartTime = now;
584 if (DEBUG) Slog.d(TAG, "State reset; now " + mTimePeriodStartClockStr);
585 }
586
587 private void resetCommon() {
Dianne Hackborn442e9fa2019-08-07 10:28:59 -0700588 mNumAggregated = 1;
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700589 mTimePeriodStartClock = System.currentTimeMillis();
590 buildTimePeriodStartClockStr();
591 mTimePeriodStartRealtime = mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
592 mTimePeriodStartUptime = mTimePeriodEndUptime = SystemClock.uptimeMillis();
Dianne Hackborne17b4452018-01-10 13:15:40 -0800593 mInternalSinglePssCount = 0;
594 mInternalSinglePssTime = 0;
595 mInternalAllMemPssCount = 0;
596 mInternalAllMemPssTime = 0;
597 mInternalAllPollPssCount = 0;
598 mInternalAllPollPssTime = 0;
Dianne Hackborn052e3142017-12-19 16:08:30 -0800599 mExternalPssCount = 0;
600 mExternalPssTime = 0;
601 mExternalSlowPssCount = 0;
602 mExternalSlowPssTime = 0;
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700603 mTableData.reset();
604 Arrays.fill(mMemFactorDurations, 0);
605 mSysMemUsage.resetTable();
606 mStartTime = 0;
607 mReadError = null;
608 mFlags = 0;
609 evaluateSystemProperties(true);
Joe Onoratoc23befa2016-05-19 15:46:00 -0700610 updateFragmentation();
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700611 }
612
613 public boolean evaluateSystemProperties(boolean update) {
614 boolean changed = false;
615 String runtime = SystemProperties.get("persist.sys.dalvik.vm.lib.2",
616 VMRuntime.getRuntime().vmLibrary());
617 if (!Objects.equals(runtime, mRuntime)) {
618 changed = true;
619 if (update) {
620 mRuntime = runtime;
621 }
622 }
623 return changed;
624 }
625
626 private void buildTimePeriodStartClockStr() {
627 mTimePeriodStartClockStr = DateFormat.format("yyyy-MM-dd-HH-mm-ss",
628 mTimePeriodStartClock).toString();
629 }
630
631 static final int[] BAD_TABLE = new int[0];
632
Joe Onoratoc23befa2016-05-19 15:46:00 -0700633
634 /**
635 * Load the system's memory fragmentation info.
636 */
637 public void updateFragmentation() {
638 // Parse /proc/pagetypeinfo and store the values.
639 BufferedReader reader = null;
640 try {
641 reader = new BufferedReader(new FileReader("/proc/pagetypeinfo"));
642 final Matcher matcher = sPageTypeRegex.matcher("");
Dianne Hackborn9f669bf2019-01-14 16:21:25 -0800643 mPageTypeNodes.clear();
Joe Onoratoc23befa2016-05-19 15:46:00 -0700644 mPageTypeZones.clear();
645 mPageTypeLabels.clear();
646 mPageTypeSizes.clear();
647 while (true) {
648 final String line = reader.readLine();
649 if (line == null) {
650 break;
651 }
652 matcher.reset(line);
653 if (matcher.matches()) {
Dianne Hackborn9f669bf2019-01-14 16:21:25 -0800654 final Integer node = Integer.valueOf(matcher.group(1), 10);
655 if (node == null) {
Joe Onoratoc23befa2016-05-19 15:46:00 -0700656 continue;
657 }
Dianne Hackborn9f669bf2019-01-14 16:21:25 -0800658 mPageTypeNodes.add(node);
659 mPageTypeZones.add(matcher.group(2));
660 mPageTypeLabels.add(matcher.group(3));
661 mPageTypeSizes.add(splitAndParseNumbers(matcher.group(4)));
Joe Onoratoc23befa2016-05-19 15:46:00 -0700662 }
663 }
664 } catch (IOException ex) {
Dianne Hackborn9f669bf2019-01-14 16:21:25 -0800665 mPageTypeNodes.clear();
Joe Onoratoc23befa2016-05-19 15:46:00 -0700666 mPageTypeZones.clear();
667 mPageTypeLabels.clear();
668 mPageTypeSizes.clear();
669 return;
670 } finally {
671 if (reader != null) {
672 try {
673 reader.close();
674 } catch (IOException allHopeIsLost) {
675 }
676 }
677 }
678 }
679
680 /**
681 * Split the string of digits separaed by spaces. There must be no
682 * leading or trailing spaces. The format is ensured by the regex
683 * above.
684 */
685 private static int[] splitAndParseNumbers(String s) {
686 // These are always positive and the numbers can't be so big that we'll overflow
687 // so just do the parsing inline.
688 boolean digit = false;
689 int count = 0;
690 final int N = s.length();
691 // Count the numbers
692 for (int i=0; i<N; i++) {
693 final char c = s.charAt(i);
694 if (c >= '0' && c <= '9') {
695 if (!digit) {
696 digit = true;
697 count++;
698 }
699 } else {
700 digit = false;
701 }
702 }
703 // Parse the numbers
704 final int[] result = new int[count];
705 int p = 0;
706 int val = 0;
707 for (int i=0; i<N; i++) {
708 final char c = s.charAt(i);
709 if (c >= '0' && c <= '9') {
710 if (!digit) {
711 digit = true;
712 val = c - '0';
713 } else {
714 val *= 10;
715 val += c - '0';
716 }
717 } else {
718 if (digit) {
719 digit = false;
720 result[p++] = val;
721 }
722 }
723 }
724 if (count > 0) {
725 result[count-1] = val;
726 }
727 return result;
728 }
729
730
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700731 private void writeCompactedLongArray(Parcel out, long[] array, int num) {
732 for (int i=0; i<num; i++) {
733 long val = array[i];
734 if (val < 0) {
735 Slog.w(TAG, "Time val negative: " + val);
736 val = 0;
737 }
738 if (val <= Integer.MAX_VALUE) {
739 out.writeInt((int)val);
740 } else {
741 int top = ~((int)((val>>32)&0x7fffffff));
Joe Onorato65adfee2016-04-07 16:59:59 -0700742 int bottom = (int)(val&0x0ffffffffL);
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700743 out.writeInt(top);
744 out.writeInt(bottom);
745 }
746 }
747 }
748
749 private void readCompactedLongArray(Parcel in, int version, long[] array, int num) {
750 if (version <= 10) {
751 in.readLongArray(array);
752 return;
753 }
754 final int alen = array.length;
755 if (num > alen) {
756 throw new RuntimeException("bad array lengths: got " + num + " array is " + alen);
757 }
758 int i;
759 for (i=0; i<num; i++) {
760 int val = in.readInt();
761 if (val >= 0) {
762 array[i] = val;
763 } else {
764 int bottom = in.readInt();
765 array[i] = (((long)~val)<<32) | bottom;
766 }
767 }
768 while (i < alen) {
769 array[i] = 0;
770 i++;
771 }
772 }
773
Dianne Hackborn2aec55a2018-06-26 10:35:35 -0700774 void writeCommonString(Parcel out, String name) {
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700775 Integer index = mCommonStringToIndex.get(name);
776 if (index != null) {
777 out.writeInt(index);
778 return;
779 }
780 index = mCommonStringToIndex.size();
781 mCommonStringToIndex.put(name, index);
782 out.writeInt(~index);
783 out.writeString(name);
784 }
785
Dianne Hackborn2aec55a2018-06-26 10:35:35 -0700786 String readCommonString(Parcel in, int version) {
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700787 if (version <= 9) {
788 return in.readString();
789 }
790 int index = in.readInt();
791 if (index >= 0) {
792 return mIndexToCommonString.get(index);
793 }
794 index = ~index;
795 String name = in.readString();
796 while (mIndexToCommonString.size() <= index) {
797 mIndexToCommonString.add(null);
798 }
799 mIndexToCommonString.set(index, name);
800 return name;
801 }
802
803 @Override
804 public int describeContents() {
805 return 0;
806 }
807
808 @Override
809 public void writeToParcel(Parcel out, int flags) {
810 writeToParcel(out, SystemClock.uptimeMillis(), flags);
811 }
812
813 /** @hide */
814 public void writeToParcel(Parcel out, long now, int flags) {
815 out.writeInt(MAGIC);
816 out.writeInt(PARCEL_VERSION);
817 out.writeInt(STATE_COUNT);
818 out.writeInt(ADJ_COUNT);
819 out.writeInt(PSS_COUNT);
820 out.writeInt(SYS_MEM_USAGE_COUNT);
821 out.writeInt(SparseMappingTable.ARRAY_SIZE);
822
823 mCommonStringToIndex = new ArrayMap<String, Integer>(mProcesses.size());
824
825 // First commit all running times.
826 ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
827 final int NPROC = procMap.size();
828 for (int ip=0; ip<NPROC; ip++) {
829 SparseArray<ProcessState> uids = procMap.valueAt(ip);
830 final int NUID = uids.size();
831 for (int iu=0; iu<NUID; iu++) {
832 uids.valueAt(iu).commitStateTime(now);
833 }
834 }
Dianne Hackborn3accca02013-09-20 09:32:11 -0700835 final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap =
836 mPackages.getMap();
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700837 final int NPKG = pkgMap.size();
838 for (int ip=0; ip<NPKG; ip++) {
Dianne Hackborn3accca02013-09-20 09:32:11 -0700839 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700840 final int NUID = uids.size();
841 for (int iu=0; iu<NUID; iu++) {
Dianne Hackborn3accca02013-09-20 09:32:11 -0700842 final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu);
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700843 final int NVERS = vpkgs.size();
844 for (int iv=0; iv<NVERS; iv++) {
845 PackageState pkgState = vpkgs.valueAt(iv);
846 final int NPROCS = pkgState.mProcesses.size();
847 for (int iproc=0; iproc<NPROCS; iproc++) {
848 ProcessState proc = pkgState.mProcesses.valueAt(iproc);
849 if (proc.getCommonProcess() != proc) {
850 proc.commitStateTime(now);
851 }
852 }
853 final int NSRVS = pkgState.mServices.size();
854 for (int isvc=0; isvc<NSRVS; isvc++) {
855 pkgState.mServices.valueAt(isvc).commitStateTime(now);
856 }
Dianne Hackborn2aec55a2018-06-26 10:35:35 -0700857 final int NASCS = pkgState.mAssociations.size();
858 for (int iasc=0; iasc<NASCS; iasc++) {
859 pkgState.mAssociations.valueAt(iasc).commitStateTime(now);
860 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700861 }
862 }
863 }
864
Dianne Hackborn442e9fa2019-08-07 10:28:59 -0700865 out.writeInt(mNumAggregated);
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700866 out.writeLong(mTimePeriodStartClock);
867 out.writeLong(mTimePeriodStartRealtime);
868 out.writeLong(mTimePeriodEndRealtime);
869 out.writeLong(mTimePeriodStartUptime);
870 out.writeLong(mTimePeriodEndUptime);
Dianne Hackborne17b4452018-01-10 13:15:40 -0800871 out.writeLong(mInternalSinglePssCount);
872 out.writeLong(mInternalSinglePssTime);
873 out.writeLong(mInternalAllMemPssCount);
874 out.writeLong(mInternalAllMemPssTime);
875 out.writeLong(mInternalAllPollPssCount);
876 out.writeLong(mInternalAllPollPssTime);
Dianne Hackborn052e3142017-12-19 16:08:30 -0800877 out.writeLong(mExternalPssCount);
878 out.writeLong(mExternalPssTime);
879 out.writeLong(mExternalSlowPssCount);
880 out.writeLong(mExternalSlowPssTime);
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700881 out.writeString(mRuntime);
Dianne Hackbornef0a4022016-05-11 14:21:07 -0700882 out.writeInt(mHasSwappedOutPss ? 1 : 0);
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700883 out.writeInt(mFlags);
884
885 mTableData.writeToParcel(out);
886
887 if (mMemFactor != STATE_NOTHING) {
888 mMemFactorDurations[mMemFactor] += now - mStartTime;
889 mStartTime = now;
890 }
891 writeCompactedLongArray(out, mMemFactorDurations, mMemFactorDurations.length);
892
893 mSysMemUsage.writeToParcel(out);
894
895 out.writeInt(NPROC);
896 for (int ip=0; ip<NPROC; ip++) {
897 writeCommonString(out, procMap.keyAt(ip));
898 final SparseArray<ProcessState> uids = procMap.valueAt(ip);
899 final int NUID = uids.size();
900 out.writeInt(NUID);
901 for (int iu=0; iu<NUID; iu++) {
902 out.writeInt(uids.keyAt(iu));
903 final ProcessState proc = uids.valueAt(iu);
904 writeCommonString(out, proc.getPackage());
Dianne Hackborn3accca02013-09-20 09:32:11 -0700905 out.writeLong(proc.getVersion());
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700906 proc.writeToParcel(out, now);
907 }
908 }
909 out.writeInt(NPKG);
910 for (int ip=0; ip<NPKG; ip++) {
911 writeCommonString(out, pkgMap.keyAt(ip));
Dianne Hackborn3accca02013-09-20 09:32:11 -0700912 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700913 final int NUID = uids.size();
914 out.writeInt(NUID);
915 for (int iu=0; iu<NUID; iu++) {
916 out.writeInt(uids.keyAt(iu));
Dianne Hackborn3accca02013-09-20 09:32:11 -0700917 final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu);
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700918 final int NVERS = vpkgs.size();
919 out.writeInt(NVERS);
920 for (int iv=0; iv<NVERS; iv++) {
Dianne Hackborn3accca02013-09-20 09:32:11 -0700921 out.writeLong(vpkgs.keyAt(iv));
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700922 final PackageState pkgState = vpkgs.valueAt(iv);
923 final int NPROCS = pkgState.mProcesses.size();
924 out.writeInt(NPROCS);
925 for (int iproc=0; iproc<NPROCS; iproc++) {
926 writeCommonString(out, pkgState.mProcesses.keyAt(iproc));
927 final ProcessState proc = pkgState.mProcesses.valueAt(iproc);
928 if (proc.getCommonProcess() == proc) {
929 // This is the same as the common process we wrote above.
930 out.writeInt(0);
931 } else {
932 // There is separate data for this package's process.
933 out.writeInt(1);
934 proc.writeToParcel(out, now);
935 }
936 }
937 final int NSRVS = pkgState.mServices.size();
938 out.writeInt(NSRVS);
939 for (int isvc=0; isvc<NSRVS; isvc++) {
940 out.writeString(pkgState.mServices.keyAt(isvc));
941 final ServiceState svc = pkgState.mServices.valueAt(isvc);
942 writeCommonString(out, svc.getProcessName());
943 svc.writeToParcel(out, now);
944 }
Dianne Hackborn2aec55a2018-06-26 10:35:35 -0700945 final int NASCS = pkgState.mAssociations.size();
946 out.writeInt(NASCS);
947 for (int iasc=0; iasc<NASCS; iasc++) {
948 writeCommonString(out, pkgState.mAssociations.keyAt(iasc));
949 final AssociationState asc = pkgState.mAssociations.valueAt(iasc);
950 writeCommonString(out, asc.getProcessName());
951 asc.writeToParcel(this, out, now);
952 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700953 }
954 }
955 }
956
Joe Onoratoc23befa2016-05-19 15:46:00 -0700957 // Fragmentation info (/proc/pagetypeinfo)
958 final int NPAGETYPES = mPageTypeLabels.size();
959 out.writeInt(NPAGETYPES);
960 for (int i=0; i<NPAGETYPES; i++) {
Dianne Hackborn9f669bf2019-01-14 16:21:25 -0800961 out.writeInt(mPageTypeNodes.get(i));
962 out.writeString(mPageTypeZones.get(i));
Joe Onoratoc23befa2016-05-19 15:46:00 -0700963 out.writeString(mPageTypeLabels.get(i));
964 out.writeIntArray(mPageTypeSizes.get(i));
965 }
966
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700967 mCommonStringToIndex = null;
968 }
969
970 private boolean readCheckedInt(Parcel in, int val, String what) {
971 int got;
972 if ((got=in.readInt()) != val) {
973 mReadError = "bad " + what + ": " + got;
974 return false;
975 }
976 return true;
977 }
978
979 static byte[] readFully(InputStream stream, int[] outLen) throws IOException {
980 int pos = 0;
981 final int initialAvail = stream.available();
982 byte[] data = new byte[initialAvail > 0 ? (initialAvail+1) : 16384];
983 while (true) {
984 int amt = stream.read(data, pos, data.length-pos);
985 if (DEBUG_PARCEL) Slog.i("foo", "Read " + amt + " bytes at " + pos
986 + " of avail " + data.length);
987 if (amt < 0) {
988 if (DEBUG_PARCEL) Slog.i("foo", "**** FINISHED READING: pos=" + pos
989 + " len=" + data.length);
990 outLen[0] = pos;
991 return data;
992 }
993 pos += amt;
994 if (pos >= data.length) {
995 byte[] newData = new byte[pos+16384];
996 if (DEBUG_PARCEL) Slog.i(TAG, "Copying " + pos + " bytes to new array len "
997 + newData.length);
998 System.arraycopy(data, 0, newData, 0, pos);
999 data = newData;
1000 }
1001 }
1002 }
1003
1004 public void read(InputStream stream) {
1005 try {
1006 int[] len = new int[1];
1007 byte[] raw = readFully(stream, len);
1008 Parcel in = Parcel.obtain();
1009 in.unmarshall(raw, 0, len[0]);
1010 in.setDataPosition(0);
1011 stream.close();
1012
1013 readFromParcel(in);
1014 } catch (IOException e) {
1015 mReadError = "caught exception: " + e;
1016 }
1017 }
1018
1019 public void readFromParcel(Parcel in) {
1020 final boolean hadData = mPackages.getMap().size() > 0
1021 || mProcesses.getMap().size() > 0;
1022 if (hadData) {
1023 resetSafely();
1024 }
1025
1026 if (!readCheckedInt(in, MAGIC, "magic number")) {
1027 return;
1028 }
1029 int version = in.readInt();
1030 if (version != PARCEL_VERSION) {
1031 mReadError = "bad version: " + version;
1032 return;
1033 }
1034 if (!readCheckedInt(in, STATE_COUNT, "state count")) {
1035 return;
1036 }
1037 if (!readCheckedInt(in, ADJ_COUNT, "adj count")) {
1038 return;
1039 }
1040 if (!readCheckedInt(in, PSS_COUNT, "pss count")) {
1041 return;
1042 }
1043 if (!readCheckedInt(in, SYS_MEM_USAGE_COUNT, "sys mem usage count")) {
1044 return;
1045 }
1046 if (!readCheckedInt(in, SparseMappingTable.ARRAY_SIZE, "longs size")) {
1047 return;
1048 }
1049
1050 mIndexToCommonString = new ArrayList<String>();
1051
Dianne Hackborn442e9fa2019-08-07 10:28:59 -07001052 mNumAggregated = in.readInt();
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001053 mTimePeriodStartClock = in.readLong();
1054 buildTimePeriodStartClockStr();
1055 mTimePeriodStartRealtime = in.readLong();
1056 mTimePeriodEndRealtime = in.readLong();
1057 mTimePeriodStartUptime = in.readLong();
1058 mTimePeriodEndUptime = in.readLong();
Dianne Hackborne17b4452018-01-10 13:15:40 -08001059 mInternalSinglePssCount = in.readLong();
1060 mInternalSinglePssTime = in.readLong();
1061 mInternalAllMemPssCount = in.readLong();
1062 mInternalAllMemPssTime = in.readLong();
1063 mInternalAllPollPssCount = in.readLong();
1064 mInternalAllPollPssTime = in.readLong();
Dianne Hackborn052e3142017-12-19 16:08:30 -08001065 mExternalPssCount = in.readLong();
1066 mExternalPssTime = in.readLong();
1067 mExternalSlowPssCount = in.readLong();
1068 mExternalSlowPssTime = in.readLong();
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001069 mRuntime = in.readString();
Dianne Hackbornef0a4022016-05-11 14:21:07 -07001070 mHasSwappedOutPss = in.readInt() != 0;
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001071 mFlags = in.readInt();
1072 mTableData.readFromParcel(in);
1073 readCompactedLongArray(in, version, mMemFactorDurations, mMemFactorDurations.length);
1074 if (!mSysMemUsage.readFromParcel(in)) {
1075 return;
1076 }
1077
1078 int NPROC = in.readInt();
1079 if (NPROC < 0) {
1080 mReadError = "bad process count: " + NPROC;
1081 return;
1082 }
1083 while (NPROC > 0) {
1084 NPROC--;
1085 final String procName = readCommonString(in, version);
1086 if (procName == null) {
1087 mReadError = "bad process name";
1088 return;
1089 }
1090 int NUID = in.readInt();
1091 if (NUID < 0) {
1092 mReadError = "bad uid count: " + NUID;
1093 return;
1094 }
1095 while (NUID > 0) {
1096 NUID--;
1097 final int uid = in.readInt();
1098 if (uid < 0) {
1099 mReadError = "bad uid: " + uid;
1100 return;
1101 }
1102 final String pkgName = readCommonString(in, version);
1103 if (pkgName == null) {
1104 mReadError = "bad process package name";
1105 return;
1106 }
Dianne Hackborn3accca02013-09-20 09:32:11 -07001107 final long vers = in.readLong();
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001108 ProcessState proc = hadData ? mProcesses.get(procName, uid) : null;
1109 if (proc != null) {
1110 if (!proc.readFromParcel(in, false)) {
1111 return;
1112 }
1113 } else {
1114 proc = new ProcessState(this, pkgName, uid, vers, procName);
1115 if (!proc.readFromParcel(in, true)) {
1116 return;
1117 }
1118 }
1119 if (DEBUG_PARCEL) Slog.d(TAG, "Adding process: " + procName + " " + uid
1120 + " " + proc);
1121 mProcesses.put(procName, uid, proc);
1122 }
1123 }
1124
1125 if (DEBUG_PARCEL) Slog.d(TAG, "Read " + mProcesses.getMap().size() + " processes");
1126
1127 int NPKG = in.readInt();
1128 if (NPKG < 0) {
1129 mReadError = "bad package count: " + NPKG;
1130 return;
1131 }
1132 while (NPKG > 0) {
1133 NPKG--;
1134 final String pkgName = readCommonString(in, version);
1135 if (pkgName == null) {
1136 mReadError = "bad package name";
1137 return;
1138 }
1139 int NUID = in.readInt();
1140 if (NUID < 0) {
1141 mReadError = "bad uid count: " + NUID;
1142 return;
1143 }
1144 while (NUID > 0) {
1145 NUID--;
1146 final int uid = in.readInt();
1147 if (uid < 0) {
1148 mReadError = "bad uid: " + uid;
1149 return;
1150 }
1151 int NVERS = in.readInt();
1152 if (NVERS < 0) {
1153 mReadError = "bad versions count: " + NVERS;
1154 return;
1155 }
1156 while (NVERS > 0) {
1157 NVERS--;
Dianne Hackborn3accca02013-09-20 09:32:11 -07001158 final long vers = in.readLong();
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001159 PackageState pkgState = new PackageState(this, pkgName, uid, vers);
Dianne Hackborn3accca02013-09-20 09:32:11 -07001160 LongSparseArray<PackageState> vpkg = mPackages.get(pkgName, uid);
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001161 if (vpkg == null) {
Dianne Hackborn3accca02013-09-20 09:32:11 -07001162 vpkg = new LongSparseArray<>();
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001163 mPackages.put(pkgName, uid, vpkg);
1164 }
1165 vpkg.put(vers, pkgState);
1166 int NPROCS = in.readInt();
1167 if (NPROCS < 0) {
1168 mReadError = "bad package process count: " + NPROCS;
1169 return;
1170 }
1171 while (NPROCS > 0) {
1172 NPROCS--;
1173 String procName = readCommonString(in, version);
1174 if (procName == null) {
1175 mReadError = "bad package process name";
1176 return;
1177 }
1178 int hasProc = in.readInt();
1179 if (DEBUG_PARCEL) Slog.d(TAG, "Reading package " + pkgName + " " + uid
1180 + " process " + procName + " hasProc=" + hasProc);
1181 ProcessState commonProc = mProcesses.get(procName, uid);
1182 if (DEBUG_PARCEL) Slog.d(TAG, "Got common proc " + procName + " " + uid
1183 + ": " + commonProc);
1184 if (commonProc == null) {
1185 mReadError = "no common proc: " + procName;
1186 return;
1187 }
1188 if (hasProc != 0) {
1189 // The process for this package is unique to the package; we
1190 // need to load it. We don't need to do anything about it if
1191 // it is not unique because if someone later looks for it
1192 // they will find and use it from the global procs.
1193 ProcessState proc = hadData ? pkgState.mProcesses.get(procName) : null;
1194 if (proc != null) {
1195 if (!proc.readFromParcel(in, false)) {
1196 return;
1197 }
1198 } else {
1199 proc = new ProcessState(commonProc, pkgName, uid, vers, procName,
1200 0);
1201 if (!proc.readFromParcel(in, true)) {
1202 return;
1203 }
1204 }
1205 if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " process: "
1206 + procName + " " + uid + " " + proc);
1207 pkgState.mProcesses.put(procName, proc);
1208 } else {
1209 if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " process: "
1210 + procName + " " + uid + " " + commonProc);
1211 pkgState.mProcesses.put(procName, commonProc);
1212 }
1213 }
1214 int NSRVS = in.readInt();
1215 if (NSRVS < 0) {
1216 mReadError = "bad package service count: " + NSRVS;
1217 return;
1218 }
1219 while (NSRVS > 0) {
1220 NSRVS--;
1221 String serviceName = in.readString();
1222 if (serviceName == null) {
1223 mReadError = "bad package service name";
1224 return;
1225 }
1226 String processName = version > 9 ? readCommonString(in, version) : null;
1227 ServiceState serv = hadData ? pkgState.mServices.get(serviceName) : null;
1228 if (serv == null) {
1229 serv = new ServiceState(this, pkgName, serviceName, processName, null);
1230 }
1231 if (!serv.readFromParcel(in)) {
1232 return;
1233 }
1234 if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " service: "
1235 + serviceName + " " + uid + " " + serv);
1236 pkgState.mServices.put(serviceName, serv);
1237 }
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001238 int NASCS = in.readInt();
1239 if (NASCS < 0) {
1240 mReadError = "bad package association count: " + NASCS;
1241 return;
1242 }
1243 while (NASCS > 0) {
1244 NASCS--;
1245 String associationName = readCommonString(in, version);
1246 if (associationName == null) {
1247 mReadError = "bad package association name";
1248 return;
1249 }
1250 String processName = readCommonString(in, version);
1251 AssociationState asc = hadData
1252 ? pkgState.mAssociations.get(associationName) : null;
1253 if (asc == null) {
Dianne Hackborn95031ef2018-07-09 09:09:05 -07001254 asc = new AssociationState(this, pkgState, associationName,
1255 processName, null);
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001256 }
1257 String errorMsg = asc.readFromParcel(this, in, version);
1258 if (errorMsg != null) {
1259 mReadError = errorMsg;
1260 return;
1261 }
1262 if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " association: "
1263 + associationName + " " + uid + " " + asc);
1264 pkgState.mAssociations.put(associationName, asc);
1265 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001266 }
1267 }
1268 }
1269
Joe Onoratoc23befa2016-05-19 15:46:00 -07001270 // Fragmentation info
1271 final int NPAGETYPES = in.readInt();
Dianne Hackborn9f669bf2019-01-14 16:21:25 -08001272 mPageTypeNodes.clear();
1273 mPageTypeNodes.ensureCapacity(NPAGETYPES);
Joe Onoratoc23befa2016-05-19 15:46:00 -07001274 mPageTypeZones.clear();
1275 mPageTypeZones.ensureCapacity(NPAGETYPES);
1276 mPageTypeLabels.clear();
1277 mPageTypeLabels.ensureCapacity(NPAGETYPES);
1278 mPageTypeSizes.clear();
1279 mPageTypeSizes.ensureCapacity(NPAGETYPES);
1280 for (int i=0; i<NPAGETYPES; i++) {
Dianne Hackborn9f669bf2019-01-14 16:21:25 -08001281 mPageTypeNodes.add(in.readInt());
1282 mPageTypeZones.add(in.readString());
Joe Onoratoc23befa2016-05-19 15:46:00 -07001283 mPageTypeLabels.add(in.readString());
1284 mPageTypeSizes.add(in.createIntArray());
1285 }
1286
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001287 mIndexToCommonString = null;
1288
1289 if (DEBUG_PARCEL) Slog.d(TAG, "Successfully read procstats!");
1290 }
1291
Dianne Hackborn3accca02013-09-20 09:32:11 -07001292 public PackageState getPackageStateLocked(String packageName, int uid, long vers) {
1293 LongSparseArray<PackageState> vpkg = mPackages.get(packageName, uid);
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001294 if (vpkg == null) {
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001295 vpkg = new LongSparseArray<>();
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001296 mPackages.put(packageName, uid, vpkg);
1297 }
1298 PackageState as = vpkg.get(vers);
1299 if (as != null) {
1300 return as;
1301 }
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001302 as = new PackageState(this, packageName, uid, vers);
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001303 vpkg.put(vers, as);
1304 return as;
1305 }
1306
Dianne Hackborn3accca02013-09-20 09:32:11 -07001307 public ProcessState getProcessStateLocked(String packageName, int uid, long vers,
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001308 String processName) {
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001309 return getProcessStateLocked(getPackageStateLocked(packageName, uid, vers), processName);
1310 }
1311
1312 public ProcessState getProcessStateLocked(PackageState pkgState, String processName) {
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001313 ProcessState ps = pkgState.mProcesses.get(processName);
1314 if (ps != null) {
1315 return ps;
1316 }
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001317 ProcessState commonProc = mProcesses.get(processName, pkgState.mUid);
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001318 if (commonProc == null) {
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001319 commonProc = new ProcessState(this, pkgState.mPackageName, pkgState.mUid,
1320 pkgState.mVersionCode, processName);
1321 mProcesses.put(processName, pkgState.mUid, commonProc);
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001322 if (DEBUG) Slog.d(TAG, "GETPROC created new common " + commonProc);
1323 }
1324 if (!commonProc.isMultiPackage()) {
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001325 if (pkgState.mPackageName.equals(commonProc.getPackage())
1326 && pkgState.mVersionCode == commonProc.getVersion()) {
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001327 // This common process is not in use by multiple packages, and
1328 // is for the calling package, so we can just use it directly.
1329 ps = commonProc;
1330 if (DEBUG) Slog.d(TAG, "GETPROC also using for pkg " + commonProc);
1331 } else {
1332 if (DEBUG) Slog.d(TAG, "GETPROC need to split common proc!");
1333 // This common process has not been in use by multiple packages,
1334 // but it was created for a different package than the caller.
1335 // We need to convert it to a multi-package process.
1336 commonProc.setMultiPackage(true);
1337 // To do this, we need to make two new process states, one a copy
1338 // of the current state for the process under the original package
1339 // name, and the second a free new process state for it as the
1340 // new package name.
1341 long now = SystemClock.uptimeMillis();
1342 // First let's make a copy of the current process state and put
1343 // that under the now unique state for its original package name.
1344 final PackageState commonPkgState = getPackageStateLocked(commonProc.getPackage(),
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001345 pkgState.mUid, commonProc.getVersion());
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001346 if (commonPkgState != null) {
1347 ProcessState cloned = commonProc.clone(now);
1348 if (DEBUG) Slog.d(TAG, "GETPROC setting clone to pkg " + commonProc.getPackage()
1349 + ": " + cloned);
1350 commonPkgState.mProcesses.put(commonProc.getName(), cloned);
1351 // If this has active services, we need to update their process pointer
1352 // to point to the new package-specific process state.
1353 for (int i=commonPkgState.mServices.size()-1; i>=0; i--) {
1354 ServiceState ss = commonPkgState.mServices.valueAt(i);
1355 if (ss.getProcess() == commonProc) {
1356 if (DEBUG) Slog.d(TAG, "GETPROC switching service to cloned: " + ss);
1357 ss.setProcess(cloned);
1358 } else if (DEBUG) {
1359 Slog.d(TAG, "GETPROC leaving proc of " + ss);
1360 }
1361 }
Dianne Hackborn95031ef2018-07-09 09:09:05 -07001362 // Also update active associations.
1363 for (int i=commonPkgState.mAssociations.size()-1; i>=0; i--) {
1364 AssociationState as = commonPkgState.mAssociations.valueAt(i);
1365 if (as.getProcess() == commonProc) {
1366 if (DEBUG) Slog.d(TAG, "GETPROC switching association to cloned: "
1367 + as);
1368 as.setProcess(cloned);
1369 } else if (DEBUG) {
1370 Slog.d(TAG, "GETPROC leaving proc of " + as);
1371 }
1372 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001373 } else {
1374 Slog.w(TAG, "Cloning proc state: no package state " + commonProc.getPackage()
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001375 + "/" + pkgState.mUid + " for proc " + commonProc.getName());
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001376 }
1377 // And now make a fresh new process state for the new package name.
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001378 ps = new ProcessState(commonProc, pkgState.mPackageName, pkgState.mUid,
1379 pkgState.mVersionCode, processName, now);
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001380 if (DEBUG) Slog.d(TAG, "GETPROC created new pkg " + ps);
1381 }
1382 } else {
1383 // The common process is for multiple packages, we need to create a
1384 // separate object for the per-package data.
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001385 ps = new ProcessState(commonProc, pkgState.mPackageName, pkgState.mUid,
1386 pkgState.mVersionCode, processName,
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001387 SystemClock.uptimeMillis());
1388 if (DEBUG) Slog.d(TAG, "GETPROC created new pkg " + ps);
1389 }
1390 pkgState.mProcesses.put(processName, ps);
1391 if (DEBUG) Slog.d(TAG, "GETPROC adding new pkg " + ps);
1392 return ps;
1393 }
1394
Dianne Hackborn3accca02013-09-20 09:32:11 -07001395 public ServiceState getServiceStateLocked(String packageName, int uid, long vers,
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001396 String processName, String className) {
1397 final ProcessStats.PackageState as = getPackageStateLocked(packageName, uid, vers);
1398 ServiceState ss = as.mServices.get(className);
1399 if (ss != null) {
1400 if (DEBUG) Slog.d(TAG, "GETSVC: returning existing " + ss);
1401 return ss;
1402 }
1403 final ProcessState ps = processName != null
1404 ? getProcessStateLocked(packageName, uid, vers, processName) : null;
1405 ss = new ServiceState(this, packageName, className, processName, ps);
1406 as.mServices.put(className, ss);
1407 if (DEBUG) Slog.d(TAG, "GETSVC: creating " + ss + " in " + ps);
1408 return ss;
1409 }
1410
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001411 public AssociationState getAssociationStateLocked(String packageName, int uid, long vers,
1412 String processName, String className) {
1413 final ProcessStats.PackageState pkgs = getPackageStateLocked(packageName, uid, vers);
1414 AssociationState as = pkgs.mAssociations.get(className);
1415 if (as != null) {
1416 if (DEBUG) Slog.d(TAG, "GETASC: returning existing " + as);
1417 return as;
1418 }
1419 final ProcessState procs = processName != null
1420 ? getProcessStateLocked(packageName, uid, vers, processName) : null;
Dianne Hackborn95031ef2018-07-09 09:09:05 -07001421 as = new AssociationState(this, pkgs, className, processName, procs);
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001422 pkgs.mAssociations.put(className, as);
1423 if (DEBUG) Slog.d(TAG, "GETASC: creating " + as + " in " + procs);
1424 return as;
1425 }
1426
Makoto Onuki621ed9f2018-12-12 16:36:20 -08001427 // See b/118826162 -- to avoid logspaming, we rate limit the warnings.
1428 private static final long INVERSE_PROC_STATE_WARNING_MIN_INTERVAL_MS = 10_000L;
1429 private long mNextInverseProcStateWarningUptime;
1430 private int mSkippedInverseProcStateWarningCount;
Makoto Onuki3a8e5c52018-11-05 15:53:53 -08001431
Dianne Hackborn95031ef2018-07-09 09:09:05 -07001432 public void updateTrackingAssociationsLocked(int curSeq, long now) {
1433 final int NUM = mTrackingAssociations.size();
1434 for (int i = NUM - 1; i >= 0; i--) {
1435 final AssociationState.SourceState act = mTrackingAssociations.get(i);
Dianne Hackborn7aea7a42018-07-25 08:58:47 -07001436 if (act.mProcStateSeq != curSeq || act.mProcState >= ProcessStats.STATE_HOME) {
1437 // If this association did not get touched the last time we computed
1438 // process states, or its state ended up down in cached, then we no
1439 // longer have a reason to track it at all.
1440 act.stopActive(now);
Dianne Hackborn95031ef2018-07-09 09:09:05 -07001441 act.mInTrackingList = false;
Dianne Hackborn7aea7a42018-07-25 08:58:47 -07001442 act.mProcState = ProcessStats.STATE_NOTHING;
Dianne Hackborn95031ef2018-07-09 09:09:05 -07001443 mTrackingAssociations.remove(i);
1444 } else {
1445 final ProcessState proc = act.getAssociationState().getProcess();
1446 if (proc != null) {
Dianne Hackborn2fd8ce42018-07-12 14:51:54 -07001447 final int procState = proc.getCombinedState() % STATE_COUNT;
1448 if (act.mProcState == procState) {
Dianne Hackborn95031ef2018-07-09 09:09:05 -07001449 act.startActive(now);
1450 } else {
1451 act.stopActive(now);
Dianne Hackborn2fd8ce42018-07-12 14:51:54 -07001452 if (act.mProcState < procState) {
Makoto Onuki3a8e5c52018-11-05 15:53:53 -08001453 final long nowUptime = SystemClock.uptimeMillis();
Makoto Onuki621ed9f2018-12-12 16:36:20 -08001454 if (mNextInverseProcStateWarningUptime > nowUptime) {
1455 mSkippedInverseProcStateWarningCount++;
Makoto Onuki3a8e5c52018-11-05 15:53:53 -08001456 } else {
1457 // TODO We still see it during boot related to GMS-core.
1458 // b/118826162
Makoto Onuki621ed9f2018-12-12 16:36:20 -08001459 Slog.w(TAG, "Tracking association " + act + " whose proc state "
Makoto Onuki3a8e5c52018-11-05 15:53:53 -08001460 + act.mProcState + " is better than process " + proc
1461 + " proc state " + procState
Makoto Onuki621ed9f2018-12-12 16:36:20 -08001462 + " (" + mSkippedInverseProcStateWarningCount
1463 + " skipped)");
1464 mSkippedInverseProcStateWarningCount = 0;
1465 mNextInverseProcStateWarningUptime =
1466 nowUptime + INVERSE_PROC_STATE_WARNING_MIN_INTERVAL_MS;
Makoto Onuki3a8e5c52018-11-05 15:53:53 -08001467 }
Dianne Hackborn95031ef2018-07-09 09:09:05 -07001468 }
1469 }
1470 } else {
Makoto Onuki3a8e5c52018-11-05 15:53:53 -08001471 // Don't need rate limiting on it.
Dianne Hackborn95031ef2018-07-09 09:09:05 -07001472 Slog.wtf(TAG, "Tracking association without process: " + act
1473 + " in " + act.getAssociationState());
1474 }
1475 }
1476 }
1477 }
1478
Dianne Hackborn442e9fa2019-08-07 10:28:59 -07001479 final class AssociationDumpContainer {
1480 final AssociationState mState;
1481 ArrayList<Pair<AssociationState.SourceKey, AssociationState.SourceDumpContainer>> mSources;
1482 long mTotalTime;
1483 long mActiveTime;
1484
1485 AssociationDumpContainer(AssociationState state) {
1486 mState = state;
1487 }
1488 }
1489
1490 static final Comparator<AssociationDumpContainer> ASSOCIATION_COMPARATOR = (o1, o2) -> {
1491 int diff = o1.mState.getProcessName().compareTo(o2.mState.getProcessName());
1492 if (diff != 0) {
1493 return diff;
1494 }
1495 if (o1.mActiveTime != o2.mActiveTime) {
1496 return o1.mActiveTime > o2.mActiveTime ? -1 : 1;
1497 }
1498 if (o1.mTotalTime != o2.mTotalTime) {
1499 return o1.mTotalTime > o2.mTotalTime ? -1 : 1;
1500 }
1501 diff = o1.mState.getName().compareTo(o2.mState.getName());
1502 if (diff != 0) {
1503 return diff;
1504 }
1505 return 0;
1506 };
1507
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001508 public void dumpLocked(PrintWriter pw, String reqPackage, long now, boolean dumpSummary,
Chenjie Yu4e028d02018-09-14 16:24:26 -07001509 boolean dumpDetails, boolean dumpAll, boolean activeOnly, int section) {
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001510 long totalTime = DumpUtils.dumpSingleTime(null, null, mMemFactorDurations, mMemFactor,
1511 mStartTime, now);
Dianne Hackborn442e9fa2019-08-07 10:28:59 -07001512 pw.print(" Start time: ");
1513 pw.print(DateFormat.format("yyyy-MM-dd HH:mm:ss", mTimePeriodStartClock));
1514 pw.println();
1515 pw.print(" Total uptime: ");
1516 TimeUtils.formatDuration(
1517 (mRunning ? SystemClock.uptimeMillis() : mTimePeriodEndUptime)
1518 - mTimePeriodStartUptime, pw);
1519 pw.println();
1520 pw.print(" Total elapsed time: ");
1521 TimeUtils.formatDuration(
1522 (mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime)
1523 - mTimePeriodStartRealtime, pw);
1524 boolean partial = true;
1525 if ((mFlags & FLAG_SHUTDOWN) != 0) {
1526 pw.print(" (shutdown)");
1527 partial = false;
1528 }
1529 if ((mFlags & FLAG_SYSPROPS) != 0) {
1530 pw.print(" (sysprops)");
1531 partial = false;
1532 }
1533 if ((mFlags & FLAG_COMPLETE) != 0) {
1534 pw.print(" (complete)");
1535 partial = false;
1536 }
1537 if (partial) {
1538 pw.print(" (partial)");
1539 }
1540 if (mHasSwappedOutPss) {
1541 pw.print(" (swapped-out-pss)");
1542 }
1543 pw.print(' ');
1544 pw.print(mRuntime);
1545 pw.println();
1546 pw.print(" Aggregated over: ");
1547 pw.println(mNumAggregated);
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001548 if (mSysMemUsage.getKeyCount() > 0) {
Dianne Hackborn442e9fa2019-08-07 10:28:59 -07001549 pw.println();
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001550 pw.println("System memory usage:");
1551 mSysMemUsage.dump(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ);
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001552 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001553 boolean printedHeader = false;
Chenjie Yu4e028d02018-09-14 16:24:26 -07001554 if ((section & REPORT_PKG_STATS) != 0) {
1555 ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap =
1556 mPackages.getMap();
1557 for (int ip = 0; ip < pkgMap.size(); ip++) {
1558 final String pkgName = pkgMap.keyAt(ip);
1559 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
1560 for (int iu = 0; iu < uids.size(); iu++) {
1561 final int uid = uids.keyAt(iu);
1562 final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu);
1563 for (int iv = 0; iv < vpkgs.size(); iv++) {
1564 final long vers = vpkgs.keyAt(iv);
1565 final PackageState pkgState = vpkgs.valueAt(iv);
1566 final int NPROCS = pkgState.mProcesses.size();
1567 final int NSRVS = pkgState.mServices.size();
1568 final int NASCS = pkgState.mAssociations.size();
1569 final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName);
Dianne Hackborn769b2e72018-12-05 08:51:20 -08001570 boolean onlyAssociations = false;
Dianne Hackborn442e9fa2019-08-07 10:28:59 -07001571 boolean procMatch = false;
Chenjie Yu4e028d02018-09-14 16:24:26 -07001572 if (!pkgMatch) {
Chenjie Yu4e028d02018-09-14 16:24:26 -07001573 for (int iproc = 0; iproc < NPROCS; iproc++) {
1574 ProcessState proc = pkgState.mProcesses.valueAt(iproc);
1575 if (reqPackage.equals(proc.getName())) {
1576 procMatch = true;
1577 break;
1578 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001579 }
Chenjie Yu4e028d02018-09-14 16:24:26 -07001580 if (!procMatch) {
Dianne Hackborn769b2e72018-12-05 08:51:20 -08001581 // Check if this app has any associations with the requested
1582 // package, so that if so we print those.
1583 for (int iasc = 0; iasc < NASCS; iasc++) {
1584 AssociationState asc = pkgState.mAssociations.valueAt(iasc);
Dianne Hackborn24bbe582018-12-17 11:58:31 -08001585 if (asc.hasProcessOrPackage(reqPackage)) {
Dianne Hackborn769b2e72018-12-05 08:51:20 -08001586 onlyAssociations = true;
1587 break;
1588 }
1589 }
1590 if (!onlyAssociations) {
1591 continue;
1592 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001593 }
Chenjie Yu4e028d02018-09-14 16:24:26 -07001594 }
1595 if (NPROCS > 0 || NSRVS > 0 || NASCS > 0) {
1596 if (!printedHeader) {
Dianne Hackborn442e9fa2019-08-07 10:28:59 -07001597 pw.println();
Chenjie Yu4e028d02018-09-14 16:24:26 -07001598 pw.println("Per-Package Stats:");
1599 printedHeader = true;
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001600 }
Chenjie Yu4e028d02018-09-14 16:24:26 -07001601 pw.print(" * ");
1602 pw.print(pkgName);
1603 pw.print(" / ");
1604 UserHandle.formatUid(pw, uid);
1605 pw.print(" / v");
1606 pw.print(vers);
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001607 pw.println(":");
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001608 }
Dianne Hackborn769b2e72018-12-05 08:51:20 -08001609 if ((section & REPORT_PKG_PROC_STATS) != 0 && !onlyAssociations) {
Chenjie Yu4e028d02018-09-14 16:24:26 -07001610 if (!dumpSummary || dumpAll) {
1611 for (int iproc = 0; iproc < NPROCS; iproc++) {
1612 ProcessState proc = pkgState.mProcesses.valueAt(iproc);
1613 if (!pkgMatch && !reqPackage.equals(proc.getName())) {
1614 continue;
1615 }
1616 if (activeOnly && !proc.isInUse()) {
1617 pw.print(" (Not active: ");
1618 pw.print(pkgState.mProcesses.keyAt(iproc));
1619 pw.println(")");
1620 continue;
1621 }
1622 pw.print(" Process ");
1623 pw.print(pkgState.mProcesses.keyAt(iproc));
1624 if (proc.getCommonProcess().isMultiPackage()) {
1625 pw.print(" (multi, ");
1626 } else {
1627 pw.print(" (unique, ");
1628 }
1629 pw.print(proc.getDurationsBucketCount());
1630 pw.print(" entries)");
1631 pw.println(":");
1632 proc.dumpProcessState(pw, " ", ALL_SCREEN_ADJ,
1633 ALL_MEM_ADJ,
1634 ALL_PROC_STATES, now);
1635 proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
1636 ALL_PROC_STATES, now);
1637 proc.dumpInternalLocked(pw, " ", dumpAll);
1638 }
1639 } else {
1640 ArrayList<ProcessState> procs = new ArrayList<ProcessState>();
1641 for (int iproc = 0; iproc < NPROCS; iproc++) {
1642 ProcessState proc = pkgState.mProcesses.valueAt(iproc);
1643 if (!pkgMatch && !reqPackage.equals(proc.getName())) {
1644 continue;
1645 }
1646 if (activeOnly && !proc.isInUse()) {
1647 continue;
1648 }
1649 procs.add(proc);
1650 }
1651 DumpUtils.dumpProcessSummaryLocked(pw, " ", "Prc ", procs,
1652 ALL_SCREEN_ADJ, ALL_MEM_ADJ, NON_CACHED_PROC_STATES,
1653 now, totalTime);
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001654 }
Chenjie Yu4e028d02018-09-14 16:24:26 -07001655 }
Dianne Hackborn769b2e72018-12-05 08:51:20 -08001656 if ((section & REPORT_PKG_SVC_STATS) != 0 && !onlyAssociations) {
Chenjie Yu4e028d02018-09-14 16:24:26 -07001657 for (int isvc = 0; isvc < NSRVS; isvc++) {
1658 ServiceState svc = pkgState.mServices.valueAt(isvc);
1659 if (!pkgMatch && !reqPackage.equals(svc.getProcessName())) {
1660 continue;
1661 }
1662 if (activeOnly && !svc.isInUse()) {
1663 pw.print(" (Not active service: ");
1664 pw.print(pkgState.mServices.keyAt(isvc));
1665 pw.println(")");
1666 continue;
1667 }
1668 if (dumpAll) {
1669 pw.print(" Service ");
1670 } else {
1671 pw.print(" * Svc ");
1672 }
1673 pw.print(pkgState.mServices.keyAt(isvc));
1674 pw.println(":");
1675 pw.print(" Process: ");
1676 pw.println(svc.getProcessName());
1677 svc.dumpStats(pw, " ", " ", " ",
1678 now, totalTime, dumpSummary, dumpAll);
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001679 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001680 }
Chenjie Yu4e028d02018-09-14 16:24:26 -07001681 if ((section & REPORT_PKG_ASC_STATS) != 0) {
Dianne Hackborn442e9fa2019-08-07 10:28:59 -07001682 ArrayList<AssociationDumpContainer> associations =
1683 new ArrayList<>(NASCS);
Chenjie Yu4e028d02018-09-14 16:24:26 -07001684 for (int iasc = 0; iasc < NASCS; iasc++) {
1685 AssociationState asc = pkgState.mAssociations.valueAt(iasc);
1686 if (!pkgMatch && !reqPackage.equals(asc.getProcessName())) {
Dianne Hackborn24bbe582018-12-17 11:58:31 -08001687 if (!onlyAssociations || !asc.hasProcessOrPackage(reqPackage)) {
Dianne Hackborn769b2e72018-12-05 08:51:20 -08001688 continue;
1689 }
Chenjie Yu4e028d02018-09-14 16:24:26 -07001690 }
Dianne Hackborn442e9fa2019-08-07 10:28:59 -07001691 final AssociationDumpContainer cont =
1692 new AssociationDumpContainer(asc);
1693 cont.mSources = asc.createSortedAssociations(now, totalTime);
1694 cont.mTotalTime = asc.getTotalDuration(now);
1695 cont.mActiveTime = asc.getActiveDuration(now);
1696 associations.add(cont);
1697 }
1698 Collections.sort(associations, ASSOCIATION_COMPARATOR);
1699 final int NCONT = associations.size();
1700 for (int iasc = 0; iasc < NCONT; iasc++) {
1701 final AssociationDumpContainer cont = associations.get(iasc);
1702 final AssociationState asc = cont.mState;
Chenjie Yu4e028d02018-09-14 16:24:26 -07001703 if (activeOnly && !asc.isInUse()) {
1704 pw.print(" (Not active association: ");
1705 pw.print(pkgState.mAssociations.keyAt(iasc));
1706 pw.println(")");
1707 continue;
1708 }
1709 if (dumpAll) {
1710 pw.print(" Association ");
1711 } else {
1712 pw.print(" * Asc ");
1713 }
Dianne Hackborn442e9fa2019-08-07 10:28:59 -07001714 pw.print(cont.mState.getName());
Chenjie Yu4e028d02018-09-14 16:24:26 -07001715 pw.println(":");
1716 pw.print(" Process: ");
1717 pw.println(asc.getProcessName());
1718 asc.dumpStats(pw, " ", " ", " ",
Dianne Hackborn442e9fa2019-08-07 10:28:59 -07001719 cont.mSources, now, totalTime,
1720 onlyAssociations && !pkgMatch && !procMatch
1721 && !asc.getProcessName().equals(reqPackage)
1722 ? reqPackage : null, dumpDetails, dumpAll);
Chenjie Yu4e028d02018-09-14 16:24:26 -07001723 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001724 }
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001725 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001726 }
1727 }
1728 }
1729
Chenjie Yu4e028d02018-09-14 16:24:26 -07001730 if ((section & REPORT_PROC_STATS) != 0) {
1731 ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
1732 printedHeader = false;
1733 int numShownProcs = 0, numTotalProcs = 0;
1734 for (int ip = 0; ip < procMap.size(); ip++) {
1735 String procName = procMap.keyAt(ip);
1736 SparseArray<ProcessState> uids = procMap.valueAt(ip);
1737 for (int iu = 0; iu < uids.size(); iu++) {
1738 int uid = uids.keyAt(iu);
1739 numTotalProcs++;
1740 final ProcessState proc = uids.valueAt(iu);
1741 if (!proc.hasAnyData()) {
1742 continue;
1743 }
1744 if (!proc.isMultiPackage()) {
1745 continue;
1746 }
1747 if (reqPackage != null && !reqPackage.equals(procName)
1748 && !reqPackage.equals(proc.getPackage())) {
1749 continue;
1750 }
1751 numShownProcs++;
Dianne Hackborn442e9fa2019-08-07 10:28:59 -07001752 pw.println();
Chenjie Yu4e028d02018-09-14 16:24:26 -07001753 if (!printedHeader) {
1754 pw.println("Multi-Package Common Processes:");
1755 printedHeader = true;
1756 }
1757 if (activeOnly && !proc.isInUse()) {
1758 pw.print(" (Not active: ");
1759 pw.print(procName);
1760 pw.println(")");
1761 continue;
1762 }
1763 pw.print(" * ");
1764 pw.print(procName);
1765 pw.print(" / ");
1766 UserHandle.formatUid(pw, uid);
1767 pw.print(" (");
1768 pw.print(proc.getDurationsBucketCount());
1769 pw.print(" entries)");
1770 pw.println(":");
1771 proc.dumpProcessState(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
1772 ALL_PROC_STATES, now);
1773 proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, ALL_PROC_STATES, now);
1774 proc.dumpInternalLocked(pw, " ", dumpAll);
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001775 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001776 }
Chenjie Yu4e028d02018-09-14 16:24:26 -07001777 pw.print(" Total procs: "); pw.print(numShownProcs);
1778 pw.print(" shown of "); pw.print(numTotalProcs); pw.println(" total");
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001779 }
Dianne Hackborn95031ef2018-07-09 09:09:05 -07001780
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001781 if (dumpAll) {
Dianne Hackborn442e9fa2019-08-07 10:28:59 -07001782 pw.println();
Dianne Hackborn95031ef2018-07-09 09:09:05 -07001783 if (mTrackingAssociations.size() > 0) {
1784 pw.println();
1785 pw.println("Tracking associations:");
1786 for (int i = 0; i < mTrackingAssociations.size(); i++) {
1787 final AssociationState.SourceState src = mTrackingAssociations.get(i);
1788 final AssociationState asc = src.getAssociationState();
1789 pw.print(" #");
1790 pw.print(i);
1791 pw.print(": ");
1792 pw.print(asc.getProcessName());
1793 pw.print("/");
1794 UserHandle.formatUid(pw, asc.getUid());
1795 pw.print(" <- ");
1796 pw.print(src.getProcessName());
1797 pw.print("/");
1798 UserHandle.formatUid(pw, src.getUid());
1799 pw.println(":");
1800 pw.print(" Tracking for: ");
1801 TimeUtils.formatDuration(now - src.mTrackingUptime, pw);
1802 pw.println();
1803 pw.print(" Component: ");
1804 pw.print(new ComponentName(asc.getPackage(), asc.getName())
1805 .flattenToShortString());
1806 pw.println();
1807 pw.print(" Proc state: ");
1808 if (src.mProcState != ProcessStats.STATE_NOTHING) {
1809 pw.print(DumpUtils.STATE_NAMES[src.mProcState]);
1810 } else {
1811 pw.print("--");
1812 }
1813 pw.print(" #");
1814 pw.println(src.mProcStateSeq);
1815 pw.print(" Process: ");
1816 pw.println(asc.getProcess());
1817 if (src.mActiveCount > 0) {
1818 pw.print(" Active count ");
1819 pw.print(src.mActiveCount);
Dianne Hackborn7aea7a42018-07-25 08:58:47 -07001820 pw.print(": ");
1821 asc.dumpActiveDurationSummary(pw, src, totalTime, now, dumpAll);
Dianne Hackborn95031ef2018-07-09 09:09:05 -07001822 pw.println();
1823 }
1824 }
1825 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001826 }
1827
Dianne Hackborn442e9fa2019-08-07 10:28:59 -07001828 pw.println();
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001829 if (dumpSummary) {
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001830 pw.println("Process summary:");
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001831 dumpSummaryLocked(pw, reqPackage, now, activeOnly);
1832 } else {
1833 dumpTotalsLocked(pw, now);
1834 }
1835
1836 if (dumpAll) {
1837 pw.println();
1838 pw.println("Internal state:");
1839 /*
1840 pw.print(" Num long arrays: "); pw.println(mLongs.size());
1841 pw.print(" Next long entry: "); pw.println(mNextLong);
1842 */
1843 pw.print(" mRunning="); pw.println(mRunning);
1844 }
Joe Onoratoc23befa2016-05-19 15:46:00 -07001845
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001846 if (reqPackage == null) {
1847 dumpFragmentationLocked(pw);
1848 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001849 }
1850
1851 public void dumpSummaryLocked(PrintWriter pw, String reqPackage, long now, boolean activeOnly) {
1852 long totalTime = DumpUtils.dumpSingleTime(null, null, mMemFactorDurations, mMemFactor,
1853 mStartTime, now);
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001854 dumpFilteredSummaryLocked(pw, null, " ", null, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001855 ALL_PROC_STATES, NON_CACHED_PROC_STATES, now, totalTime, reqPackage, activeOnly);
1856 pw.println();
1857 dumpTotalsLocked(pw, now);
1858 }
1859
Joe Onoratoc23befa2016-05-19 15:46:00 -07001860 private void dumpFragmentationLocked(PrintWriter pw) {
1861 pw.println();
1862 pw.println("Available pages by page size:");
1863 final int NPAGETYPES = mPageTypeLabels.size();
1864 for (int i=0; i<NPAGETYPES; i++) {
Dianne Hackborn9f669bf2019-01-14 16:21:25 -08001865 pw.format("Node %3d Zone %7s %14s ", mPageTypeNodes.get(i), mPageTypeZones.get(i),
1866 mPageTypeLabels.get(i));
Joe Onoratoc23befa2016-05-19 15:46:00 -07001867 final int[] sizes = mPageTypeSizes.get(i);
1868 final int N = sizes == null ? 0 : sizes.length;
1869 for (int j=0; j<N; j++) {
1870 pw.format("%6d", sizes[j]);
1871 }
1872 pw.println();
1873 }
1874 }
1875
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001876 long printMemoryCategory(PrintWriter pw, String prefix, String label, double memWeight,
1877 long totalTime, long curTotalMem, int samples) {
1878 if (memWeight != 0) {
1879 long mem = (long)(memWeight * 1024 / totalTime);
1880 pw.print(prefix);
1881 pw.print(label);
1882 pw.print(": ");
1883 DebugUtils.printSizeValue(pw, mem);
1884 pw.print(" (");
1885 pw.print(samples);
1886 pw.print(" samples)");
1887 pw.println();
1888 return curTotalMem + mem;
1889 }
1890 return curTotalMem;
1891 }
1892
1893 void dumpTotalsLocked(PrintWriter pw, long now) {
1894 pw.println("Run time Stats:");
1895 DumpUtils.dumpSingleTime(pw, " ", mMemFactorDurations, mMemFactor, mStartTime, now);
1896 pw.println();
1897 pw.println("Memory usage:");
1898 TotalMemoryUseCollection totalMem = new TotalMemoryUseCollection(ALL_SCREEN_ADJ,
1899 ALL_MEM_ADJ);
1900 computeTotalMemoryUse(totalMem, now);
1901 long totalPss = 0;
1902 totalPss = printMemoryCategory(pw, " ", "Kernel ", totalMem.sysMemKernelWeight,
1903 totalMem.totalTime, totalPss, totalMem.sysMemSamples);
1904 totalPss = printMemoryCategory(pw, " ", "Native ", totalMem.sysMemNativeWeight,
1905 totalMem.totalTime, totalPss, totalMem.sysMemSamples);
1906 for (int i=0; i<STATE_COUNT; i++) {
1907 // Skip restarting service state -- that is not actually a running process.
1908 if (i != STATE_SERVICE_RESTARTING) {
1909 totalPss = printMemoryCategory(pw, " ", DumpUtils.STATE_NAMES[i],
1910 totalMem.processStateWeight[i], totalMem.totalTime, totalPss,
1911 totalMem.processStateSamples[i]);
1912 }
1913 }
1914 totalPss = printMemoryCategory(pw, " ", "Cached ", totalMem.sysMemCachedWeight,
1915 totalMem.totalTime, totalPss, totalMem.sysMemSamples);
1916 totalPss = printMemoryCategory(pw, " ", "Free ", totalMem.sysMemFreeWeight,
1917 totalMem.totalTime, totalPss, totalMem.sysMemSamples);
1918 totalPss = printMemoryCategory(pw, " ", "Z-Ram ", totalMem.sysMemZRamWeight,
1919 totalMem.totalTime, totalPss, totalMem.sysMemSamples);
1920 pw.print(" TOTAL : ");
1921 DebugUtils.printSizeValue(pw, totalPss);
1922 pw.println();
1923 printMemoryCategory(pw, " ", DumpUtils.STATE_NAMES[STATE_SERVICE_RESTARTING],
1924 totalMem.processStateWeight[STATE_SERVICE_RESTARTING], totalMem.totalTime, totalPss,
1925 totalMem.processStateSamples[STATE_SERVICE_RESTARTING]);
1926 pw.println();
Dianne Hackborn052e3142017-12-19 16:08:30 -08001927 pw.println("PSS collection stats:");
Dianne Hackborne17b4452018-01-10 13:15:40 -08001928 pw.print(" Internal Single: ");
1929 pw.print(mInternalSinglePssCount);
Dianne Hackborn052e3142017-12-19 16:08:30 -08001930 pw.print("x over ");
Dianne Hackborne17b4452018-01-10 13:15:40 -08001931 TimeUtils.formatDuration(mInternalSinglePssTime, pw);
1932 pw.println();
1933 pw.print(" Internal All Procs (Memory Change): ");
1934 pw.print(mInternalAllMemPssCount);
1935 pw.print("x over ");
1936 TimeUtils.formatDuration(mInternalAllMemPssTime, pw);
1937 pw.println();
1938 pw.print(" Internal All Procs (Polling): ");
1939 pw.print(mInternalAllPollPssCount);
1940 pw.print("x over ");
1941 TimeUtils.formatDuration(mInternalAllPollPssTime, pw);
Dianne Hackborn052e3142017-12-19 16:08:30 -08001942 pw.println();
1943 pw.print(" External: ");
1944 pw.print(mExternalPssCount);
1945 pw.print("x over ");
1946 TimeUtils.formatDuration(mExternalPssTime, pw);
1947 pw.println();
1948 pw.print(" External Slow: ");
1949 pw.print(mExternalSlowPssCount);
1950 pw.print("x over ");
1951 TimeUtils.formatDuration(mExternalSlowPssTime, pw);
1952 pw.println();
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001953 }
1954
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001955 void dumpFilteredSummaryLocked(PrintWriter pw, String header, String prefix, String prcLabel,
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001956 int[] screenStates, int[] memStates, int[] procStates,
1957 int[] sortProcStates, long now, long totalTime, String reqPackage, boolean activeOnly) {
1958 ArrayList<ProcessState> procs = collectProcessesLocked(screenStates, memStates,
1959 procStates, sortProcStates, now, reqPackage, activeOnly);
1960 if (procs.size() > 0) {
1961 if (header != null) {
1962 pw.println();
1963 pw.println(header);
1964 }
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07001965 DumpUtils.dumpProcessSummaryLocked(pw, prefix, prcLabel, procs, screenStates, memStates,
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001966 sortProcStates, now, totalTime);
1967 }
1968 }
1969
1970 public ArrayList<ProcessState> collectProcessesLocked(int[] screenStates, int[] memStates,
1971 int[] procStates, int sortProcStates[], long now, String reqPackage,
1972 boolean activeOnly) {
1973 final ArraySet<ProcessState> foundProcs = new ArraySet<ProcessState>();
Dianne Hackborn3accca02013-09-20 09:32:11 -07001974 final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap =
1975 mPackages.getMap();
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001976 for (int ip=0; ip<pkgMap.size(); ip++) {
1977 final String pkgName = pkgMap.keyAt(ip);
Dianne Hackborn3accca02013-09-20 09:32:11 -07001978 final SparseArray<LongSparseArray<PackageState>> procs = pkgMap.valueAt(ip);
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001979 for (int iu=0; iu<procs.size(); iu++) {
Dianne Hackborn3accca02013-09-20 09:32:11 -07001980 final LongSparseArray<PackageState> vpkgs = procs.valueAt(iu);
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001981 final int NVERS = vpkgs.size();
1982 for (int iv=0; iv<NVERS; iv++) {
1983 final PackageState state = vpkgs.valueAt(iv);
1984 final int NPROCS = state.mProcesses.size();
1985 final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName);
1986 for (int iproc=0; iproc<NPROCS; iproc++) {
1987 final ProcessState proc = state.mProcesses.valueAt(iproc);
1988 if (!pkgMatch && !reqPackage.equals(proc.getName())) {
1989 continue;
1990 }
1991 if (activeOnly && !proc.isInUse()) {
1992 continue;
1993 }
1994 foundProcs.add(proc.getCommonProcess());
1995 }
1996 }
1997 }
1998 }
1999 ArrayList<ProcessState> outProcs = new ArrayList<ProcessState>(foundProcs.size());
2000 for (int i=0; i<foundProcs.size(); i++) {
2001 ProcessState proc = foundProcs.valueAt(i);
2002 if (proc.computeProcessTimeLocked(screenStates, memStates, procStates, now) > 0) {
2003 outProcs.add(proc);
2004 if (procStates != sortProcStates) {
2005 proc.computeProcessTimeLocked(screenStates, memStates, sortProcStates, now);
2006 }
2007 }
2008 }
2009 Collections.sort(outProcs, ProcessState.COMPARATOR);
2010 return outProcs;
2011 }
2012
Chenjie Yu4e028d02018-09-14 16:24:26 -07002013 /**
2014 * Prints checkin style stats dump.
2015 */
2016 public void dumpCheckinLocked(PrintWriter pw, String reqPackage, int section) {
Joe Onorato4eb64fd2016-03-21 15:30:09 -07002017 final long now = SystemClock.uptimeMillis();
Dianne Hackborn3accca02013-09-20 09:32:11 -07002018 final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap =
2019 mPackages.getMap();
Joe Onorato4eb64fd2016-03-21 15:30:09 -07002020 pw.println("vers,5");
2021 pw.print("period,"); pw.print(mTimePeriodStartClockStr);
2022 pw.print(","); pw.print(mTimePeriodStartRealtime); pw.print(",");
2023 pw.print(mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime);
2024 boolean partial = true;
2025 if ((mFlags&FLAG_SHUTDOWN) != 0) {
2026 pw.print(",shutdown");
2027 partial = false;
2028 }
2029 if ((mFlags&FLAG_SYSPROPS) != 0) {
2030 pw.print(",sysprops");
2031 partial = false;
2032 }
2033 if ((mFlags&FLAG_COMPLETE) != 0) {
2034 pw.print(",complete");
2035 partial = false;
2036 }
2037 if (partial) {
2038 pw.print(",partial");
2039 }
Dianne Hackbornef0a4022016-05-11 14:21:07 -07002040 if (mHasSwappedOutPss) {
2041 pw.print(",swapped-out-pss");
2042 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -07002043 pw.println();
2044 pw.print("config,"); pw.println(mRuntime);
Chenjie Yu4e028d02018-09-14 16:24:26 -07002045
2046 if ((section & REPORT_PKG_STATS) != 0) {
2047 for (int ip = 0; ip < pkgMap.size(); ip++) {
2048 final String pkgName = pkgMap.keyAt(ip);
2049 if (reqPackage != null && !reqPackage.equals(pkgName)) {
2050 continue;
2051 }
2052 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
2053 for (int iu = 0; iu < uids.size(); iu++) {
2054 final int uid = uids.keyAt(iu);
2055 final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu);
2056 for (int iv = 0; iv < vpkgs.size(); iv++) {
2057 final long vers = vpkgs.keyAt(iv);
2058 final PackageState pkgState = vpkgs.valueAt(iv);
2059 final int NPROCS = pkgState.mProcesses.size();
2060 final int NSRVS = pkgState.mServices.size();
2061 final int NASCS = pkgState.mAssociations.size();
2062 if ((section & REPORT_PKG_PROC_STATS) != 0) {
2063 for (int iproc = 0; iproc < NPROCS; iproc++) {
2064 ProcessState proc = pkgState.mProcesses.valueAt(iproc);
2065 proc.dumpPackageProcCheckin(pw, pkgName, uid, vers,
2066 pkgState.mProcesses.keyAt(iproc), now);
2067 }
2068 }
2069 if ((section & REPORT_PKG_SVC_STATS) != 0) {
2070 for (int isvc = 0; isvc < NSRVS; isvc++) {
2071 final String serviceName = DumpUtils.collapseString(pkgName,
2072 pkgState.mServices.keyAt(isvc));
2073 final ServiceState svc = pkgState.mServices.valueAt(isvc);
2074 svc.dumpTimesCheckin(pw, pkgName, uid, vers, serviceName, now);
2075 }
2076 }
2077 if ((section & REPORT_PKG_ASC_STATS) != 0) {
2078 for (int iasc = 0; iasc < NASCS; iasc++) {
2079 final String associationName = DumpUtils.collapseString(pkgName,
2080 pkgState.mAssociations.keyAt(iasc));
2081 final AssociationState asc = pkgState.mAssociations.valueAt(iasc);
2082 asc.dumpTimesCheckin(pw, pkgName, uid, vers, associationName, now);
2083 }
2084 }
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07002085 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -07002086 }
2087 }
2088 }
2089
Chenjie Yu4e028d02018-09-14 16:24:26 -07002090 if ((section & REPORT_PROC_STATS) != 0) {
2091 ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
2092 for (int ip = 0; ip < procMap.size(); ip++) {
2093 String procName = procMap.keyAt(ip);
2094 SparseArray<ProcessState> uids = procMap.valueAt(ip);
2095 for (int iu = 0; iu < uids.size(); iu++) {
2096 final int uid = uids.keyAt(iu);
2097 final ProcessState procState = uids.valueAt(iu);
2098 procState.dumpProcCheckin(pw, procName, uid, now);
2099 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -07002100 }
2101 }
2102 pw.print("total");
2103 DumpUtils.dumpAdjTimesCheckin(pw, ",", mMemFactorDurations, mMemFactor, mStartTime, now);
2104 pw.println();
2105 final int sysMemUsageCount = mSysMemUsage.getKeyCount();
2106 if (sysMemUsageCount > 0) {
2107 pw.print("sysmemusage");
2108 for (int i=0; i<sysMemUsageCount; i++) {
2109 final int key = mSysMemUsage.getKeyAt(i);
2110 final int type = SparseMappingTable.getIdFromKey(key);
2111 pw.print(",");
2112 DumpUtils.printProcStateTag(pw, type);
2113 for (int j=SYS_MEM_USAGE_SAMPLE_COUNT; j<SYS_MEM_USAGE_COUNT; j++) {
2114 if (j > SYS_MEM_USAGE_CACHED_MINIMUM) {
2115 pw.print(":");
2116 }
2117 pw.print(mSysMemUsage.getValue(key, j));
2118 }
2119 }
2120 }
2121 pw.println();
2122 TotalMemoryUseCollection totalMem = new TotalMemoryUseCollection(ALL_SCREEN_ADJ,
2123 ALL_MEM_ADJ);
2124 computeTotalMemoryUse(totalMem, now);
2125 pw.print("weights,");
2126 pw.print(totalMem.totalTime);
2127 pw.print(",");
2128 pw.print(totalMem.sysMemCachedWeight);
2129 pw.print(":");
2130 pw.print(totalMem.sysMemSamples);
2131 pw.print(",");
2132 pw.print(totalMem.sysMemFreeWeight);
2133 pw.print(":");
2134 pw.print(totalMem.sysMemSamples);
2135 pw.print(",");
2136 pw.print(totalMem.sysMemZRamWeight);
2137 pw.print(":");
2138 pw.print(totalMem.sysMemSamples);
2139 pw.print(",");
2140 pw.print(totalMem.sysMemKernelWeight);
2141 pw.print(":");
2142 pw.print(totalMem.sysMemSamples);
2143 pw.print(",");
2144 pw.print(totalMem.sysMemNativeWeight);
2145 pw.print(":");
2146 pw.print(totalMem.sysMemSamples);
2147 for (int i=0; i<STATE_COUNT; i++) {
2148 pw.print(",");
2149 pw.print(totalMem.processStateWeight[i]);
2150 pw.print(":");
2151 pw.print(totalMem.processStateSamples[i]);
2152 }
2153 pw.println();
Joe Onoratoc23befa2016-05-19 15:46:00 -07002154
2155 final int NPAGETYPES = mPageTypeLabels.size();
2156 for (int i=0; i<NPAGETYPES; i++) {
2157 pw.print("availablepages,");
2158 pw.print(mPageTypeLabels.get(i));
2159 pw.print(",");
2160 pw.print(mPageTypeZones.get(i));
2161 pw.print(",");
Dianne Hackborn9f669bf2019-01-14 16:21:25 -08002162 // Wasn't included in original output.
2163 //pw.print(mPageTypeNodes.get(i));
2164 //pw.print(",");
Joe Onoratoc23befa2016-05-19 15:46:00 -07002165 final int[] sizes = mPageTypeSizes.get(i);
2166 final int N = sizes == null ? 0 : sizes.length;
2167 for (int j=0; j<N; j++) {
2168 if (j != 0) {
2169 pw.print(",");
2170 }
2171 pw.print(sizes[j]);
2172 }
2173 pw.println();
2174 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -07002175 }
2176
Chenjie Yu4e028d02018-09-14 16:24:26 -07002177 /**
2178 * Writes to ProtoOutputStream.
2179 */
Jeffrey Huangcb782852019-12-05 11:28:11 -08002180 public void dumpDebug(ProtoOutputStream proto, long now, int section) {
Yi Jin9680cfa2017-09-15 15:14:43 -07002181 proto.write(ProcessStatsSectionProto.START_REALTIME_MS, mTimePeriodStartRealtime);
2182 proto.write(ProcessStatsSectionProto.END_REALTIME_MS,
2183 mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime);
2184 proto.write(ProcessStatsSectionProto.START_UPTIME_MS, mTimePeriodStartUptime);
2185 proto.write(ProcessStatsSectionProto.END_UPTIME_MS, mTimePeriodEndUptime);
2186 proto.write(ProcessStatsSectionProto.RUNTIME, mRuntime);
2187 proto.write(ProcessStatsSectionProto.HAS_SWAPPED_PSS, mHasSwappedOutPss);
2188 boolean partial = true;
Chenjie Yu4e028d02018-09-14 16:24:26 -07002189 if ((mFlags & FLAG_SHUTDOWN) != 0) {
Yi Jin9680cfa2017-09-15 15:14:43 -07002190 proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SHUTDOWN);
2191 partial = false;
2192 }
Chenjie Yu4e028d02018-09-14 16:24:26 -07002193 if ((mFlags & FLAG_SYSPROPS) != 0) {
Yi Jin9680cfa2017-09-15 15:14:43 -07002194 proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SYSPROPS);
2195 partial = false;
2196 }
Chenjie Yu4e028d02018-09-14 16:24:26 -07002197 if ((mFlags & FLAG_COMPLETE) != 0) {
Yi Jin9680cfa2017-09-15 15:14:43 -07002198 proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_COMPLETE);
2199 partial = false;
2200 }
2201 if (partial) {
2202 proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_PARTIAL);
2203 }
2204
Dianne Hackborn9f669bf2019-01-14 16:21:25 -08002205 final int NPAGETYPES = mPageTypeLabels.size();
2206 for (int i = 0; i < NPAGETYPES; i++) {
2207 final long token = proto.start(ProcessStatsSectionProto.AVAILABLE_PAGES);
2208 proto.write(ProcessStatsAvailablePagesProto.NODE, mPageTypeNodes.get(i));
2209 proto.write(ProcessStatsAvailablePagesProto.ZONE, mPageTypeZones.get(i));
2210 proto.write(ProcessStatsAvailablePagesProto.LABEL, mPageTypeLabels.get(i));
2211 final int[] sizes = mPageTypeSizes.get(i);
2212 final int N = sizes == null ? 0 : sizes.length;
2213 for (int j = 0; j < N; j++) {
2214 proto.write(ProcessStatsAvailablePagesProto.PAGES_PER_ORDER, sizes[j]);
2215 }
2216 proto.end(token);
2217 }
2218
Dianne Hackborneaed0ba2018-08-08 17:10:17 -07002219 final ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
Chenjie Yu4e028d02018-09-14 16:24:26 -07002220 if ((section & REPORT_PROC_STATS) != 0) {
2221 for (int ip = 0; ip < procMap.size(); ip++) {
2222 final String procName = procMap.keyAt(ip);
2223 final SparseArray<ProcessState> uids = procMap.valueAt(ip);
2224 for (int iu = 0; iu < uids.size(); iu++) {
2225 final int uid = uids.keyAt(iu);
2226 final ProcessState procState = uids.valueAt(iu);
Jeffrey Huangcb782852019-12-05 11:28:11 -08002227 procState.dumpDebug(proto, ProcessStatsSectionProto.PROCESS_STATS, procName,
Chenjie Yu4e028d02018-09-14 16:24:26 -07002228 uid, now);
Dianne Hackborneaed0ba2018-08-08 17:10:17 -07002229 }
2230 }
2231 }
2232
Chenjie Yu4e028d02018-09-14 16:24:26 -07002233 if ((section & REPORT_PKG_STATS) != 0) {
2234 final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap =
2235 mPackages.getMap();
2236 for (int ip = 0; ip < pkgMap.size(); ip++) {
2237 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
2238 for (int iu = 0; iu < uids.size(); iu++) {
2239 final LongSparseArray<PackageState> vers = uids.valueAt(iu);
2240 for (int iv = 0; iv < vers.size(); iv++) {
2241 final PackageState pkgState = vers.valueAt(iv);
Jeffrey Huangcb782852019-12-05 11:28:11 -08002242 pkgState.dumpDebug(proto, ProcessStatsSectionProto.PACKAGE_STATS, now,
Chenjie Yu4e028d02018-09-14 16:24:26 -07002243 section);
2244 }
2245 }
2246 }
2247 }
Yi Jin9680cfa2017-09-15 15:14:43 -07002248 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -07002249
2250 final public static class ProcessStateHolder {
Dianne Hackborn3accca02013-09-20 09:32:11 -07002251 public final long appVersion;
Joe Onorato4eb64fd2016-03-21 15:30:09 -07002252 public ProcessState state;
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07002253 public PackageState pkg;
Joe Onorato4eb64fd2016-03-21 15:30:09 -07002254
Dianne Hackborn3accca02013-09-20 09:32:11 -07002255 public ProcessStateHolder(long _appVersion) {
Joe Onorato4eb64fd2016-03-21 15:30:09 -07002256 appVersion = _appVersion;
2257 }
2258 }
2259
2260 public static final class PackageState {
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07002261 public final ProcessStats mProcessStats;
2262 public final ArrayMap<String, ProcessState> mProcesses = new ArrayMap<>();
2263 public final ArrayMap<String, ServiceState> mServices = new ArrayMap<>();
2264 public final ArrayMap<String, AssociationState> mAssociations = new ArrayMap<>();
Joe Onorato4eb64fd2016-03-21 15:30:09 -07002265 public final String mPackageName;
2266 public final int mUid;
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07002267 public final long mVersionCode;
Joe Onorato4eb64fd2016-03-21 15:30:09 -07002268
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07002269 public PackageState(ProcessStats procStats, String packageName, int uid, long versionCode) {
2270 mProcessStats = procStats;
Joe Onorato4eb64fd2016-03-21 15:30:09 -07002271 mUid = uid;
2272 mPackageName = packageName;
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07002273 mVersionCode = versionCode;
2274 }
2275
Dianne Hackborn95031ef2018-07-09 09:09:05 -07002276 public AssociationState getAssociationStateLocked(ProcessState proc, String className) {
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07002277 AssociationState as = mAssociations.get(className);
2278 if (as != null) {
2279 if (DEBUG) Slog.d(TAG, "GETASC: returning existing " + as);
Dianne Hackborn95031ef2018-07-09 09:09:05 -07002280 if (proc != null) {
2281 as.setProcess(proc);
2282 }
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07002283 return as;
2284 }
Dianne Hackborn95031ef2018-07-09 09:09:05 -07002285 as = new AssociationState(mProcessStats, this, className, proc.getName(),
2286 proc);
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07002287 mAssociations.put(className, as);
Dianne Hackborn95031ef2018-07-09 09:09:05 -07002288 if (DEBUG) Slog.d(TAG, "GETASC: creating " + as + " in " + proc.getName());
Dianne Hackborn2aec55a2018-06-26 10:35:35 -07002289 return as;
Joe Onorato4eb64fd2016-03-21 15:30:09 -07002290 }
Dianne Hackborneaed0ba2018-08-08 17:10:17 -07002291
Chenjie Yu4e028d02018-09-14 16:24:26 -07002292 /**
2293 * Writes the containing stats into proto, with options to choose smaller sections.
2294 */
Jeffrey Huangcb782852019-12-05 11:28:11 -08002295 public void dumpDebug(ProtoOutputStream proto, long fieldId, long now, int section) {
Dianne Hackborneaed0ba2018-08-08 17:10:17 -07002296 final long token = proto.start(fieldId);
2297
2298 proto.write(ProcessStatsPackageProto.PACKAGE, mPackageName);
2299 proto.write(ProcessStatsPackageProto.UID, mUid);
2300 proto.write(ProcessStatsPackageProto.VERSION, mVersionCode);
2301
Chenjie Yu4e028d02018-09-14 16:24:26 -07002302 if ((section & ProcessStats.REPORT_PKG_PROC_STATS) != 0) {
2303 for (int ip = 0; ip < mProcesses.size(); ip++) {
2304 final String procName = mProcesses.keyAt(ip);
2305 final ProcessState procState = mProcesses.valueAt(ip);
Jeffrey Huangcb782852019-12-05 11:28:11 -08002306 procState.dumpDebug(proto, ProcessStatsPackageProto.PROCESS_STATS, procName,
Chenjie Yu4e028d02018-09-14 16:24:26 -07002307 mUid, now);
2308 }
Dianne Hackborneaed0ba2018-08-08 17:10:17 -07002309 }
2310
Chenjie Yu4e028d02018-09-14 16:24:26 -07002311 if ((section & ProcessStats.REPORT_PKG_SVC_STATS) != 0) {
2312 for (int is = 0; is < mServices.size(); is++) {
2313 final ServiceState serviceState = mServices.valueAt(is);
Jeffrey Huangcb782852019-12-05 11:28:11 -08002314 serviceState.dumpDebug(proto, ProcessStatsPackageProto.SERVICE_STATS,
Chenjie Yu4e028d02018-09-14 16:24:26 -07002315 now);
2316 }
Dianne Hackborneaed0ba2018-08-08 17:10:17 -07002317 }
2318
Chenjie Yu4e028d02018-09-14 16:24:26 -07002319 if ((section & ProcessStats.REPORT_PKG_ASC_STATS) != 0) {
2320 for (int ia = 0; ia < mAssociations.size(); ia++) {
2321 final AssociationState ascState = mAssociations.valueAt(ia);
Jeffrey Huangcb782852019-12-05 11:28:11 -08002322 ascState.dumpDebug(proto, ProcessStatsPackageProto.ASSOCIATION_STATS,
Chenjie Yu4e028d02018-09-14 16:24:26 -07002323 now);
2324 }
Dianne Hackborneaed0ba2018-08-08 17:10:17 -07002325 }
2326
2327 proto.end(token);
2328 }
Joe Onorato4eb64fd2016-03-21 15:30:09 -07002329 }
2330
2331 public static final class ProcessDataCollection {
2332 final int[] screenStates;
2333 final int[] memStates;
2334 final int[] procStates;
2335
2336 public long totalTime;
2337 public long numPss;
2338 public long minPss;
2339 public long avgPss;
2340 public long maxPss;
2341 public long minUss;
2342 public long avgUss;
2343 public long maxUss;
Dianne Hackborne17b4452018-01-10 13:15:40 -08002344 public long minRss;
2345 public long avgRss;
2346 public long maxRss;
Joe Onorato4eb64fd2016-03-21 15:30:09 -07002347
2348 public ProcessDataCollection(int[] _screenStates, int[] _memStates, int[] _procStates) {
2349 screenStates = _screenStates;
2350 memStates = _memStates;
2351 procStates = _procStates;
2352 }
2353
2354 void print(PrintWriter pw, long overallTime, boolean full) {
2355 if (totalTime > overallTime) {
2356 pw.print("*");
2357 }
2358 DumpUtils.printPercent(pw, (double) totalTime / (double) overallTime);
2359 if (numPss > 0) {
2360 pw.print(" (");
2361 DebugUtils.printSizeValue(pw, minPss * 1024);
2362 pw.print("-");
2363 DebugUtils.printSizeValue(pw, avgPss * 1024);
2364 pw.print("-");
2365 DebugUtils.printSizeValue(pw, maxPss * 1024);
2366 pw.print("/");
2367 DebugUtils.printSizeValue(pw, minUss * 1024);
2368 pw.print("-");
2369 DebugUtils.printSizeValue(pw, avgUss * 1024);
2370 pw.print("-");
2371 DebugUtils.printSizeValue(pw, maxUss * 1024);
Dianne Hackborne17b4452018-01-10 13:15:40 -08002372 pw.print("/");
2373 DebugUtils.printSizeValue(pw, minRss * 1024);
2374 pw.print("-");
2375 DebugUtils.printSizeValue(pw, avgRss * 1024);
2376 pw.print("-");
2377 DebugUtils.printSizeValue(pw, maxRss * 1024);
Joe Onorato4eb64fd2016-03-21 15:30:09 -07002378 if (full) {
2379 pw.print(" over ");
2380 pw.print(numPss);
2381 }
2382 pw.print(")");
2383 }
2384 }
2385 }
2386
2387 public static class TotalMemoryUseCollection {
2388 final int[] screenStates;
2389 final int[] memStates;
2390
2391 public TotalMemoryUseCollection(int[] _screenStates, int[] _memStates) {
2392 screenStates = _screenStates;
2393 memStates = _memStates;
2394 }
2395
2396 public long totalTime;
2397 public long[] processStatePss = new long[STATE_COUNT];
2398 public double[] processStateWeight = new double[STATE_COUNT];
2399 public long[] processStateTime = new long[STATE_COUNT];
2400 public int[] processStateSamples = new int[STATE_COUNT];
2401 public long[] sysMemUsage = new long[SYS_MEM_USAGE_COUNT];
2402 public double sysMemCachedWeight;
2403 public double sysMemFreeWeight;
2404 public double sysMemZRamWeight;
2405 public double sysMemKernelWeight;
2406 public double sysMemNativeWeight;
2407 public int sysMemSamples;
Dianne Hackbornef0a4022016-05-11 14:21:07 -07002408 public boolean hasSwappedOutPss;
Joe Onorato4eb64fd2016-03-21 15:30:09 -07002409 }
2410
2411}