Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1 | /* |
| 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 | |
| 17 | package com.android.internal.app.procstats; |
| 18 | |
Dianne Hackborn | 95031ef | 2018-07-09 09:09:05 -0700 | [diff] [blame] | 19 | import android.content.ComponentName; |
Dianne Hackborn | ef0a402 | 2016-05-11 14:21:07 -0700 | [diff] [blame] | 20 | import android.os.Debug; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 21 | import android.os.Parcel; |
| 22 | import android.os.Parcelable; |
| 23 | import android.os.SystemClock; |
| 24 | import android.os.SystemProperties; |
| 25 | import android.os.UserHandle; |
Dianne Hackborn | 9f669bf | 2019-01-14 16:21:25 -0800 | [diff] [blame] | 26 | import android.service.procstats.ProcessStatsAvailablePagesProto; |
Dianne Hackborn | eaed0ba | 2018-08-08 17:10:17 -0700 | [diff] [blame] | 27 | import android.service.procstats.ProcessStatsPackageProto; |
Yi Jin | 9680cfa | 2017-09-15 15:14:43 -0700 | [diff] [blame] | 28 | import android.service.procstats.ProcessStatsSectionProto; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 29 | import android.text.format.DateFormat; |
| 30 | import android.util.ArrayMap; |
| 31 | import android.util.ArraySet; |
| 32 | import android.util.DebugUtils; |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 33 | import android.util.LongSparseArray; |
Dianne Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 34 | import android.util.Pair; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 35 | import android.util.Slog; |
| 36 | import android.util.SparseArray; |
| 37 | import android.util.TimeUtils; |
Yi Jin | 9680cfa | 2017-09-15 15:14:43 -0700 | [diff] [blame] | 38 | import android.util.proto.ProtoOutputStream; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 39 | |
| 40 | import com.android.internal.app.ProcessMap; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 41 | |
| 42 | import dalvik.system.VMRuntime; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 43 | |
Joe Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 44 | import java.io.BufferedReader; |
| 45 | import java.io.FileReader; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 46 | import java.io.IOException; |
| 47 | import java.io.InputStream; |
| 48 | import java.io.PrintWriter; |
| 49 | import java.util.ArrayList; |
| 50 | import java.util.Arrays; |
| 51 | import java.util.Collections; |
Dianne Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 52 | import java.util.Comparator; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 53 | import java.util.Objects; |
Joe Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 54 | import java.util.regex.Matcher; |
Rafal Slawik | 91b9e0b | 2018-08-10 15:36:31 +0100 | [diff] [blame] | 55 | import java.util.regex.Pattern; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 56 | |
| 57 | public 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 Hackborn | f097d42 | 2017-12-15 16:32:19 -0800 | [diff] [blame] | 79 | 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 83 | 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 Hackborn | e17b445 | 2018-01-10 13:15:40 -0800 | [diff] [blame] | 97 | 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 101 | |
| 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 Hackborn | e17b445 | 2018-01-10 13:15:40 -0800 | [diff] [blame] | 135 | 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 Hackborn | 052e314 | 2017-12-19 16:08:30 -0800 | [diff] [blame] | 140 | |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 141 | 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 Hackborn | f097d42 | 2017-12-15 16:32:19 -0800 | [diff] [blame] | 148 | STATE_IMPORTANT_BACKGROUND, STATE_BACKUP, |
| 149 | STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER, STATE_HEAVY_WEIGHT |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 150 | }; |
| 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 Hackborn | f097d42 | 2017-12-15 16:32:19 -0800 | [diff] [blame] | 159 | STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER, |
| 160 | STATE_HEAVY_WEIGHT, STATE_HOME, STATE_LAST_ACTIVITY, STATE_CACHED_ACTIVITY, |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 161 | STATE_CACHED_ACTIVITY_CLIENT, STATE_CACHED_EMPTY |
| 162 | }; |
| 163 | |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 164 | // 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 183 | // Current version of the parcel format. |
Dianne Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 184 | private static final int PARCEL_VERSION = 38; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 185 | // 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 Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 192 | public final ProcessMap<LongSparseArray<PackageState>> mPackages = new ProcessMap<>(); |
| 193 | public final ProcessMap<ProcessState> mProcesses = new ProcessMap<>(); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 194 | |
Dianne Hackborn | 95031ef | 2018-07-09 09:09:05 -0700 | [diff] [blame] | 195 | public final ArrayList<AssociationState.SourceState> mTrackingAssociations = new ArrayList<>(); |
| 196 | |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 197 | public final long[] mMemFactorDurations = new long[ADJ_COUNT]; |
| 198 | public int mMemFactor = STATE_NOTHING; |
| 199 | public long mStartTime; |
| 200 | |
Dianne Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 201 | // Number of individual stats that have been aggregated to create this one. |
| 202 | public int mNumAggregated = 1; |
| 203 | |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 204 | 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 Hackborn | ef0a402 | 2016-05-11 14:21:07 -0700 | [diff] [blame] | 212 | boolean mHasSwappedOutPss; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 213 | |
Dianne Hackborn | e17b445 | 2018-01-10 13:15:40 -0800 | [diff] [blame] | 214 | // 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 Hackborn | 052e314 | 2017-12-19 16:08:30 -0800 | [diff] [blame] | 225 | |
| 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 Hackborn | ef0a402 | 2016-05-11 14:21:07 -0700 | [diff] [blame] | 234 | public final SparseMappingTable mTableData = new SparseMappingTable(); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 235 | |
| 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 Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 245 | private static final Pattern sPageTypeRegex = Pattern.compile( |
Dianne Hackborn | 9f669bf | 2019-01-14 16:21:25 -0800 | [diff] [blame] | 246 | "^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 Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 251 | |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 252 | public ProcessStats(boolean running) { |
| 253 | mRunning = running; |
| 254 | reset(); |
Dianne Hackborn | ef0a402 | 2016-05-11 14:21:07 -0700 | [diff] [blame] | 255 | 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 262 | } |
| 263 | |
| 264 | public ProcessStats(Parcel in) { |
| 265 | reset(); |
| 266 | readFromParcel(in); |
| 267 | } |
| 268 | |
Richard Gaywood | 3ee7557 | 2020-02-18 15:59:06 +0000 | [diff] [blame] | 269 | /** |
| 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 278 | public void add(ProcessStats other) { |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 279 | ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = |
| 280 | other.mPackages.getMap(); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 281 | for (int ip=0; ip<pkgMap.size(); ip++) { |
| 282 | final String pkgName = pkgMap.keyAt(ip); |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 283 | final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 284 | for (int iu=0; iu<uids.size(); iu++) { |
| 285 | final int uid = uids.keyAt(iu); |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 286 | final LongSparseArray<PackageState> versions = uids.valueAt(iu); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 287 | for (int iv=0; iv<versions.size(); iv++) { |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 288 | final long vers = versions.keyAt(iv); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 289 | final PackageState otherState = versions.valueAt(iv); |
| 290 | final int NPROCS = otherState.mProcesses.size(); |
| 291 | final int NSRVS = otherState.mServices.size(); |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 292 | final int NASCS = otherState.mAssociations.size(); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 293 | 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 Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 320 | 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 328 | } |
| 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 Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 340 | final long vers = otherProc.getVersion(); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 341 | 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 Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 365 | mNumAggregated += other.mNumAggregated; |
| 366 | |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 367 | 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 Hackborn | ef0a402 | 2016-05-11 14:21:07 -0700 | [diff] [blame] | 373 | |
Dianne Hackborn | e17b445 | 2018-01-10 13:15:40 -0800 | [diff] [blame] | 374 | mInternalSinglePssCount += other.mInternalSinglePssCount; |
| 375 | mInternalSinglePssTime += other.mInternalSinglePssTime; |
| 376 | mInternalAllMemPssCount += other.mInternalAllMemPssCount; |
| 377 | mInternalAllMemPssTime += other.mInternalAllMemPssTime; |
| 378 | mInternalAllPollPssCount += other.mInternalAllPollPssCount; |
| 379 | mInternalAllPollPssTime += other.mInternalAllPollPssTime; |
Dianne Hackborn | 052e314 | 2017-12-19 16:08:30 -0800 | [diff] [blame] | 380 | mExternalPssCount += other.mExternalPssCount; |
| 381 | mExternalPssTime += other.mExternalPssTime; |
| 382 | mExternalSlowPssCount += other.mExternalSlowPssCount; |
| 383 | mExternalSlowPssTime += other.mExternalSlowPssTime; |
| 384 | |
Dianne Hackborn | ef0a402 | 2016-05-11 14:21:07 -0700 | [diff] [blame] | 385 | mHasSwappedOutPss |= other.mHasSwappedOutPss; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 386 | } |
| 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 Hackborn | ef0a402 | 2016-05-11 14:21:07 -0700 | [diff] [blame] | 458 | data.sysMemZRamWeight += longs[idx + SYS_MEM_USAGE_ZRAM_AVERAGE] |
| 459 | * (double) memTime; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 460 | 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 Hackborn | ef0a402 | 2016-05-11 14:21:07 -0700 | [diff] [blame] | 467 | data.hasSwappedOutPss = mHasSwappedOutPss; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 468 | 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 Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 504 | final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = |
| 505 | mPackages.getMap(); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 506 | for (int ip=pkgMap.size()-1; ip>=0; ip--) { |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 507 | final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 508 | for (int iu=uids.size()-1; iu>=0; iu--) { |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 509 | final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 510 | 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 Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 531 | 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 541 | 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 Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 588 | mNumAggregated = 1; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 589 | mTimePeriodStartClock = System.currentTimeMillis(); |
| 590 | buildTimePeriodStartClockStr(); |
| 591 | mTimePeriodStartRealtime = mTimePeriodEndRealtime = SystemClock.elapsedRealtime(); |
| 592 | mTimePeriodStartUptime = mTimePeriodEndUptime = SystemClock.uptimeMillis(); |
Dianne Hackborn | e17b445 | 2018-01-10 13:15:40 -0800 | [diff] [blame] | 593 | mInternalSinglePssCount = 0; |
| 594 | mInternalSinglePssTime = 0; |
| 595 | mInternalAllMemPssCount = 0; |
| 596 | mInternalAllMemPssTime = 0; |
| 597 | mInternalAllPollPssCount = 0; |
| 598 | mInternalAllPollPssTime = 0; |
Dianne Hackborn | 052e314 | 2017-12-19 16:08:30 -0800 | [diff] [blame] | 599 | mExternalPssCount = 0; |
| 600 | mExternalPssTime = 0; |
| 601 | mExternalSlowPssCount = 0; |
| 602 | mExternalSlowPssTime = 0; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 603 | mTableData.reset(); |
| 604 | Arrays.fill(mMemFactorDurations, 0); |
| 605 | mSysMemUsage.resetTable(); |
| 606 | mStartTime = 0; |
| 607 | mReadError = null; |
| 608 | mFlags = 0; |
| 609 | evaluateSystemProperties(true); |
Joe Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 610 | updateFragmentation(); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 611 | } |
| 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 Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 633 | |
| 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 Hackborn | 9f669bf | 2019-01-14 16:21:25 -0800 | [diff] [blame] | 643 | mPageTypeNodes.clear(); |
Joe Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 644 | 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 Hackborn | 9f669bf | 2019-01-14 16:21:25 -0800 | [diff] [blame] | 654 | final Integer node = Integer.valueOf(matcher.group(1), 10); |
| 655 | if (node == null) { |
Joe Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 656 | continue; |
| 657 | } |
Dianne Hackborn | 9f669bf | 2019-01-14 16:21:25 -0800 | [diff] [blame] | 658 | mPageTypeNodes.add(node); |
| 659 | mPageTypeZones.add(matcher.group(2)); |
| 660 | mPageTypeLabels.add(matcher.group(3)); |
| 661 | mPageTypeSizes.add(splitAndParseNumbers(matcher.group(4))); |
Joe Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 662 | } |
| 663 | } |
| 664 | } catch (IOException ex) { |
Dianne Hackborn | 9f669bf | 2019-01-14 16:21:25 -0800 | [diff] [blame] | 665 | mPageTypeNodes.clear(); |
Joe Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 666 | 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 731 | 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 Onorato | 65adfee | 2016-04-07 16:59:59 -0700 | [diff] [blame] | 742 | int bottom = (int)(val&0x0ffffffffL); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 743 | 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 Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 774 | void writeCommonString(Parcel out, String name) { |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 775 | 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 Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 786 | String readCommonString(Parcel in, int version) { |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 787 | 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 Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 835 | final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = |
| 836 | mPackages.getMap(); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 837 | final int NPKG = pkgMap.size(); |
| 838 | for (int ip=0; ip<NPKG; ip++) { |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 839 | final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 840 | final int NUID = uids.size(); |
| 841 | for (int iu=0; iu<NUID; iu++) { |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 842 | final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 843 | 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 Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 857 | final int NASCS = pkgState.mAssociations.size(); |
| 858 | for (int iasc=0; iasc<NASCS; iasc++) { |
| 859 | pkgState.mAssociations.valueAt(iasc).commitStateTime(now); |
| 860 | } |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 861 | } |
| 862 | } |
| 863 | } |
| 864 | |
Dianne Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 865 | out.writeInt(mNumAggregated); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 866 | out.writeLong(mTimePeriodStartClock); |
| 867 | out.writeLong(mTimePeriodStartRealtime); |
| 868 | out.writeLong(mTimePeriodEndRealtime); |
| 869 | out.writeLong(mTimePeriodStartUptime); |
| 870 | out.writeLong(mTimePeriodEndUptime); |
Dianne Hackborn | e17b445 | 2018-01-10 13:15:40 -0800 | [diff] [blame] | 871 | out.writeLong(mInternalSinglePssCount); |
| 872 | out.writeLong(mInternalSinglePssTime); |
| 873 | out.writeLong(mInternalAllMemPssCount); |
| 874 | out.writeLong(mInternalAllMemPssTime); |
| 875 | out.writeLong(mInternalAllPollPssCount); |
| 876 | out.writeLong(mInternalAllPollPssTime); |
Dianne Hackborn | 052e314 | 2017-12-19 16:08:30 -0800 | [diff] [blame] | 877 | out.writeLong(mExternalPssCount); |
| 878 | out.writeLong(mExternalPssTime); |
| 879 | out.writeLong(mExternalSlowPssCount); |
| 880 | out.writeLong(mExternalSlowPssTime); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 881 | out.writeString(mRuntime); |
Dianne Hackborn | ef0a402 | 2016-05-11 14:21:07 -0700 | [diff] [blame] | 882 | out.writeInt(mHasSwappedOutPss ? 1 : 0); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 883 | 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 Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 905 | out.writeLong(proc.getVersion()); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 906 | 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 Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 912 | final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 913 | final int NUID = uids.size(); |
| 914 | out.writeInt(NUID); |
| 915 | for (int iu=0; iu<NUID; iu++) { |
| 916 | out.writeInt(uids.keyAt(iu)); |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 917 | final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 918 | final int NVERS = vpkgs.size(); |
| 919 | out.writeInt(NVERS); |
| 920 | for (int iv=0; iv<NVERS; iv++) { |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 921 | out.writeLong(vpkgs.keyAt(iv)); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 922 | 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 Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 945 | 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 953 | } |
| 954 | } |
| 955 | } |
| 956 | |
Joe Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 957 | // Fragmentation info (/proc/pagetypeinfo) |
| 958 | final int NPAGETYPES = mPageTypeLabels.size(); |
| 959 | out.writeInt(NPAGETYPES); |
| 960 | for (int i=0; i<NPAGETYPES; i++) { |
Dianne Hackborn | 9f669bf | 2019-01-14 16:21:25 -0800 | [diff] [blame] | 961 | out.writeInt(mPageTypeNodes.get(i)); |
| 962 | out.writeString(mPageTypeZones.get(i)); |
Joe Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 963 | out.writeString(mPageTypeLabels.get(i)); |
| 964 | out.writeIntArray(mPageTypeSizes.get(i)); |
| 965 | } |
| 966 | |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 967 | 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 Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 1052 | mNumAggregated = in.readInt(); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1053 | mTimePeriodStartClock = in.readLong(); |
| 1054 | buildTimePeriodStartClockStr(); |
| 1055 | mTimePeriodStartRealtime = in.readLong(); |
| 1056 | mTimePeriodEndRealtime = in.readLong(); |
| 1057 | mTimePeriodStartUptime = in.readLong(); |
| 1058 | mTimePeriodEndUptime = in.readLong(); |
Dianne Hackborn | e17b445 | 2018-01-10 13:15:40 -0800 | [diff] [blame] | 1059 | mInternalSinglePssCount = in.readLong(); |
| 1060 | mInternalSinglePssTime = in.readLong(); |
| 1061 | mInternalAllMemPssCount = in.readLong(); |
| 1062 | mInternalAllMemPssTime = in.readLong(); |
| 1063 | mInternalAllPollPssCount = in.readLong(); |
| 1064 | mInternalAllPollPssTime = in.readLong(); |
Dianne Hackborn | 052e314 | 2017-12-19 16:08:30 -0800 | [diff] [blame] | 1065 | mExternalPssCount = in.readLong(); |
| 1066 | mExternalPssTime = in.readLong(); |
| 1067 | mExternalSlowPssCount = in.readLong(); |
| 1068 | mExternalSlowPssTime = in.readLong(); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1069 | mRuntime = in.readString(); |
Dianne Hackborn | ef0a402 | 2016-05-11 14:21:07 -0700 | [diff] [blame] | 1070 | mHasSwappedOutPss = in.readInt() != 0; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1071 | 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 Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 1107 | final long vers = in.readLong(); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1108 | 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 Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 1158 | final long vers = in.readLong(); |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1159 | PackageState pkgState = new PackageState(this, pkgName, uid, vers); |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 1160 | LongSparseArray<PackageState> vpkg = mPackages.get(pkgName, uid); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1161 | if (vpkg == null) { |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 1162 | vpkg = new LongSparseArray<>(); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1163 | 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 Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1238 | 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 Hackborn | 95031ef | 2018-07-09 09:09:05 -0700 | [diff] [blame] | 1254 | asc = new AssociationState(this, pkgState, associationName, |
| 1255 | processName, null); |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1256 | } |
| 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1266 | } |
| 1267 | } |
| 1268 | } |
| 1269 | |
Joe Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 1270 | // Fragmentation info |
| 1271 | final int NPAGETYPES = in.readInt(); |
Dianne Hackborn | 9f669bf | 2019-01-14 16:21:25 -0800 | [diff] [blame] | 1272 | mPageTypeNodes.clear(); |
| 1273 | mPageTypeNodes.ensureCapacity(NPAGETYPES); |
Joe Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 1274 | 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 Hackborn | 9f669bf | 2019-01-14 16:21:25 -0800 | [diff] [blame] | 1281 | mPageTypeNodes.add(in.readInt()); |
| 1282 | mPageTypeZones.add(in.readString()); |
Joe Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 1283 | mPageTypeLabels.add(in.readString()); |
| 1284 | mPageTypeSizes.add(in.createIntArray()); |
| 1285 | } |
| 1286 | |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1287 | mIndexToCommonString = null; |
| 1288 | |
| 1289 | if (DEBUG_PARCEL) Slog.d(TAG, "Successfully read procstats!"); |
| 1290 | } |
| 1291 | |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 1292 | public PackageState getPackageStateLocked(String packageName, int uid, long vers) { |
| 1293 | LongSparseArray<PackageState> vpkg = mPackages.get(packageName, uid); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1294 | if (vpkg == null) { |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1295 | vpkg = new LongSparseArray<>(); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1296 | mPackages.put(packageName, uid, vpkg); |
| 1297 | } |
| 1298 | PackageState as = vpkg.get(vers); |
| 1299 | if (as != null) { |
| 1300 | return as; |
| 1301 | } |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1302 | as = new PackageState(this, packageName, uid, vers); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1303 | vpkg.put(vers, as); |
| 1304 | return as; |
| 1305 | } |
| 1306 | |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 1307 | public ProcessState getProcessStateLocked(String packageName, int uid, long vers, |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1308 | String processName) { |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1309 | return getProcessStateLocked(getPackageStateLocked(packageName, uid, vers), processName); |
| 1310 | } |
| 1311 | |
| 1312 | public ProcessState getProcessStateLocked(PackageState pkgState, String processName) { |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1313 | ProcessState ps = pkgState.mProcesses.get(processName); |
| 1314 | if (ps != null) { |
| 1315 | return ps; |
| 1316 | } |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1317 | ProcessState commonProc = mProcesses.get(processName, pkgState.mUid); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1318 | if (commonProc == null) { |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1319 | commonProc = new ProcessState(this, pkgState.mPackageName, pkgState.mUid, |
| 1320 | pkgState.mVersionCode, processName); |
| 1321 | mProcesses.put(processName, pkgState.mUid, commonProc); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1322 | if (DEBUG) Slog.d(TAG, "GETPROC created new common " + commonProc); |
| 1323 | } |
| 1324 | if (!commonProc.isMultiPackage()) { |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1325 | if (pkgState.mPackageName.equals(commonProc.getPackage()) |
| 1326 | && pkgState.mVersionCode == commonProc.getVersion()) { |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1327 | // 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 Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1345 | pkgState.mUid, commonProc.getVersion()); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1346 | 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 Hackborn | 95031ef | 2018-07-09 09:09:05 -0700 | [diff] [blame] | 1362 | // 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1373 | } else { |
| 1374 | Slog.w(TAG, "Cloning proc state: no package state " + commonProc.getPackage() |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1375 | + "/" + pkgState.mUid + " for proc " + commonProc.getName()); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1376 | } |
| 1377 | // And now make a fresh new process state for the new package name. |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1378 | ps = new ProcessState(commonProc, pkgState.mPackageName, pkgState.mUid, |
| 1379 | pkgState.mVersionCode, processName, now); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1380 | 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 Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1385 | ps = new ProcessState(commonProc, pkgState.mPackageName, pkgState.mUid, |
| 1386 | pkgState.mVersionCode, processName, |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1387 | 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 Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 1395 | public ServiceState getServiceStateLocked(String packageName, int uid, long vers, |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1396 | 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 Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1411 | 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 Hackborn | 95031ef | 2018-07-09 09:09:05 -0700 | [diff] [blame] | 1421 | as = new AssociationState(this, pkgs, className, processName, procs); |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1422 | pkgs.mAssociations.put(className, as); |
| 1423 | if (DEBUG) Slog.d(TAG, "GETASC: creating " + as + " in " + procs); |
| 1424 | return as; |
| 1425 | } |
| 1426 | |
Makoto Onuki | 621ed9f | 2018-12-12 16:36:20 -0800 | [diff] [blame] | 1427 | // 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 Onuki | 3a8e5c5 | 2018-11-05 15:53:53 -0800 | [diff] [blame] | 1431 | |
Dianne Hackborn | 95031ef | 2018-07-09 09:09:05 -0700 | [diff] [blame] | 1432 | 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 Hackborn | 7aea7a4 | 2018-07-25 08:58:47 -0700 | [diff] [blame] | 1436 | 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 Hackborn | 95031ef | 2018-07-09 09:09:05 -0700 | [diff] [blame] | 1441 | act.mInTrackingList = false; |
Dianne Hackborn | 7aea7a4 | 2018-07-25 08:58:47 -0700 | [diff] [blame] | 1442 | act.mProcState = ProcessStats.STATE_NOTHING; |
Dianne Hackborn | 95031ef | 2018-07-09 09:09:05 -0700 | [diff] [blame] | 1443 | mTrackingAssociations.remove(i); |
| 1444 | } else { |
| 1445 | final ProcessState proc = act.getAssociationState().getProcess(); |
| 1446 | if (proc != null) { |
Dianne Hackborn | 2fd8ce4 | 2018-07-12 14:51:54 -0700 | [diff] [blame] | 1447 | final int procState = proc.getCombinedState() % STATE_COUNT; |
| 1448 | if (act.mProcState == procState) { |
Dianne Hackborn | 95031ef | 2018-07-09 09:09:05 -0700 | [diff] [blame] | 1449 | act.startActive(now); |
| 1450 | } else { |
| 1451 | act.stopActive(now); |
Dianne Hackborn | 2fd8ce4 | 2018-07-12 14:51:54 -0700 | [diff] [blame] | 1452 | if (act.mProcState < procState) { |
Makoto Onuki | 3a8e5c5 | 2018-11-05 15:53:53 -0800 | [diff] [blame] | 1453 | final long nowUptime = SystemClock.uptimeMillis(); |
Makoto Onuki | 621ed9f | 2018-12-12 16:36:20 -0800 | [diff] [blame] | 1454 | if (mNextInverseProcStateWarningUptime > nowUptime) { |
| 1455 | mSkippedInverseProcStateWarningCount++; |
Makoto Onuki | 3a8e5c5 | 2018-11-05 15:53:53 -0800 | [diff] [blame] | 1456 | } else { |
| 1457 | // TODO We still see it during boot related to GMS-core. |
| 1458 | // b/118826162 |
Makoto Onuki | 621ed9f | 2018-12-12 16:36:20 -0800 | [diff] [blame] | 1459 | Slog.w(TAG, "Tracking association " + act + " whose proc state " |
Makoto Onuki | 3a8e5c5 | 2018-11-05 15:53:53 -0800 | [diff] [blame] | 1460 | + act.mProcState + " is better than process " + proc |
| 1461 | + " proc state " + procState |
Makoto Onuki | 621ed9f | 2018-12-12 16:36:20 -0800 | [diff] [blame] | 1462 | + " (" + mSkippedInverseProcStateWarningCount |
| 1463 | + " skipped)"); |
| 1464 | mSkippedInverseProcStateWarningCount = 0; |
| 1465 | mNextInverseProcStateWarningUptime = |
| 1466 | nowUptime + INVERSE_PROC_STATE_WARNING_MIN_INTERVAL_MS; |
Makoto Onuki | 3a8e5c5 | 2018-11-05 15:53:53 -0800 | [diff] [blame] | 1467 | } |
Dianne Hackborn | 95031ef | 2018-07-09 09:09:05 -0700 | [diff] [blame] | 1468 | } |
| 1469 | } |
| 1470 | } else { |
Makoto Onuki | 3a8e5c5 | 2018-11-05 15:53:53 -0800 | [diff] [blame] | 1471 | // Don't need rate limiting on it. |
Dianne Hackborn | 95031ef | 2018-07-09 09:09:05 -0700 | [diff] [blame] | 1472 | Slog.wtf(TAG, "Tracking association without process: " + act |
| 1473 | + " in " + act.getAssociationState()); |
| 1474 | } |
| 1475 | } |
| 1476 | } |
| 1477 | } |
| 1478 | |
Dianne Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 1479 | 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1508 | public void dumpLocked(PrintWriter pw, String reqPackage, long now, boolean dumpSummary, |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1509 | boolean dumpDetails, boolean dumpAll, boolean activeOnly, int section) { |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1510 | long totalTime = DumpUtils.dumpSingleTime(null, null, mMemFactorDurations, mMemFactor, |
| 1511 | mStartTime, now); |
Dianne Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 1512 | 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1548 | if (mSysMemUsage.getKeyCount() > 0) { |
Dianne Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 1549 | pw.println(); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1550 | pw.println("System memory usage:"); |
| 1551 | mSysMemUsage.dump(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1552 | } |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1553 | boolean printedHeader = false; |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1554 | 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 Hackborn | 769b2e7 | 2018-12-05 08:51:20 -0800 | [diff] [blame] | 1570 | boolean onlyAssociations = false; |
Dianne Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 1571 | boolean procMatch = false; |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1572 | if (!pkgMatch) { |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1573 | 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1579 | } |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1580 | if (!procMatch) { |
Dianne Hackborn | 769b2e7 | 2018-12-05 08:51:20 -0800 | [diff] [blame] | 1581 | // 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 Hackborn | 24bbe58 | 2018-12-17 11:58:31 -0800 | [diff] [blame] | 1585 | if (asc.hasProcessOrPackage(reqPackage)) { |
Dianne Hackborn | 769b2e7 | 2018-12-05 08:51:20 -0800 | [diff] [blame] | 1586 | onlyAssociations = true; |
| 1587 | break; |
| 1588 | } |
| 1589 | } |
| 1590 | if (!onlyAssociations) { |
| 1591 | continue; |
| 1592 | } |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1593 | } |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1594 | } |
| 1595 | if (NPROCS > 0 || NSRVS > 0 || NASCS > 0) { |
| 1596 | if (!printedHeader) { |
Dianne Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 1597 | pw.println(); |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1598 | pw.println("Per-Package Stats:"); |
| 1599 | printedHeader = true; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1600 | } |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1601 | pw.print(" * "); |
| 1602 | pw.print(pkgName); |
| 1603 | pw.print(" / "); |
| 1604 | UserHandle.formatUid(pw, uid); |
| 1605 | pw.print(" / v"); |
| 1606 | pw.print(vers); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1607 | pw.println(":"); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1608 | } |
Dianne Hackborn | 769b2e7 | 2018-12-05 08:51:20 -0800 | [diff] [blame] | 1609 | if ((section & REPORT_PKG_PROC_STATS) != 0 && !onlyAssociations) { |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1610 | 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1654 | } |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1655 | } |
Dianne Hackborn | 769b2e7 | 2018-12-05 08:51:20 -0800 | [diff] [blame] | 1656 | if ((section & REPORT_PKG_SVC_STATS) != 0 && !onlyAssociations) { |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1657 | 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1679 | } |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1680 | } |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1681 | if ((section & REPORT_PKG_ASC_STATS) != 0) { |
Dianne Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 1682 | ArrayList<AssociationDumpContainer> associations = |
| 1683 | new ArrayList<>(NASCS); |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1684 | for (int iasc = 0; iasc < NASCS; iasc++) { |
| 1685 | AssociationState asc = pkgState.mAssociations.valueAt(iasc); |
| 1686 | if (!pkgMatch && !reqPackage.equals(asc.getProcessName())) { |
Dianne Hackborn | 24bbe58 | 2018-12-17 11:58:31 -0800 | [diff] [blame] | 1687 | if (!onlyAssociations || !asc.hasProcessOrPackage(reqPackage)) { |
Dianne Hackborn | 769b2e7 | 2018-12-05 08:51:20 -0800 | [diff] [blame] | 1688 | continue; |
| 1689 | } |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1690 | } |
Dianne Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 1691 | 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 Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1703 | 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 Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 1714 | pw.print(cont.mState.getName()); |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1715 | pw.println(":"); |
| 1716 | pw.print(" Process: "); |
| 1717 | pw.println(asc.getProcessName()); |
| 1718 | asc.dumpStats(pw, " ", " ", " ", |
Dianne Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 1719 | cont.mSources, now, totalTime, |
| 1720 | onlyAssociations && !pkgMatch && !procMatch |
| 1721 | && !asc.getProcessName().equals(reqPackage) |
| 1722 | ? reqPackage : null, dumpDetails, dumpAll); |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1723 | } |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1724 | } |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1725 | } |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1726 | } |
| 1727 | } |
| 1728 | } |
| 1729 | |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1730 | 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 Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 1752 | pw.println(); |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1753 | 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1775 | } |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1776 | } |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 1777 | pw.print(" Total procs: "); pw.print(numShownProcs); |
| 1778 | pw.print(" shown of "); pw.print(numTotalProcs); pw.println(" total"); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1779 | } |
Dianne Hackborn | 95031ef | 2018-07-09 09:09:05 -0700 | [diff] [blame] | 1780 | |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1781 | if (dumpAll) { |
Dianne Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 1782 | pw.println(); |
Dianne Hackborn | 95031ef | 2018-07-09 09:09:05 -0700 | [diff] [blame] | 1783 | 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 Hackborn | 7aea7a4 | 2018-07-25 08:58:47 -0700 | [diff] [blame] | 1820 | pw.print(": "); |
| 1821 | asc.dumpActiveDurationSummary(pw, src, totalTime, now, dumpAll); |
Dianne Hackborn | 95031ef | 2018-07-09 09:09:05 -0700 | [diff] [blame] | 1822 | pw.println(); |
| 1823 | } |
| 1824 | } |
| 1825 | } |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1826 | } |
| 1827 | |
Dianne Hackborn | 442e9fa | 2019-08-07 10:28:59 -0700 | [diff] [blame] | 1828 | pw.println(); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1829 | if (dumpSummary) { |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1830 | pw.println("Process summary:"); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1831 | 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 Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 1845 | |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1846 | if (reqPackage == null) { |
| 1847 | dumpFragmentationLocked(pw); |
| 1848 | } |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1849 | } |
| 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 Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1854 | dumpFilteredSummaryLocked(pw, null, " ", null, ALL_SCREEN_ADJ, ALL_MEM_ADJ, |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1855 | ALL_PROC_STATES, NON_CACHED_PROC_STATES, now, totalTime, reqPackage, activeOnly); |
| 1856 | pw.println(); |
| 1857 | dumpTotalsLocked(pw, now); |
| 1858 | } |
| 1859 | |
Joe Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 1860 | 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 Hackborn | 9f669bf | 2019-01-14 16:21:25 -0800 | [diff] [blame] | 1865 | pw.format("Node %3d Zone %7s %14s ", mPageTypeNodes.get(i), mPageTypeZones.get(i), |
| 1866 | mPageTypeLabels.get(i)); |
Joe Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 1867 | 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1876 | 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 Hackborn | 052e314 | 2017-12-19 16:08:30 -0800 | [diff] [blame] | 1927 | pw.println("PSS collection stats:"); |
Dianne Hackborn | e17b445 | 2018-01-10 13:15:40 -0800 | [diff] [blame] | 1928 | pw.print(" Internal Single: "); |
| 1929 | pw.print(mInternalSinglePssCount); |
Dianne Hackborn | 052e314 | 2017-12-19 16:08:30 -0800 | [diff] [blame] | 1930 | pw.print("x over "); |
Dianne Hackborn | e17b445 | 2018-01-10 13:15:40 -0800 | [diff] [blame] | 1931 | 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 Hackborn | 052e314 | 2017-12-19 16:08:30 -0800 | [diff] [blame] | 1942 | 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1953 | } |
| 1954 | |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1955 | void dumpFilteredSummaryLocked(PrintWriter pw, String header, String prefix, String prcLabel, |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1956 | 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 Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 1965 | DumpUtils.dumpProcessSummaryLocked(pw, prefix, prcLabel, procs, screenStates, memStates, |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1966 | 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 Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 1974 | final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = |
| 1975 | mPackages.getMap(); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1976 | for (int ip=0; ip<pkgMap.size(); ip++) { |
| 1977 | final String pkgName = pkgMap.keyAt(ip); |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 1978 | final SparseArray<LongSparseArray<PackageState>> procs = pkgMap.valueAt(ip); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1979 | for (int iu=0; iu<procs.size(); iu++) { |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 1980 | final LongSparseArray<PackageState> vpkgs = procs.valueAt(iu); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 1981 | 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 Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 2013 | /** |
| 2014 | * Prints checkin style stats dump. |
| 2015 | */ |
| 2016 | public void dumpCheckinLocked(PrintWriter pw, String reqPackage, int section) { |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 2017 | final long now = SystemClock.uptimeMillis(); |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 2018 | final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = |
| 2019 | mPackages.getMap(); |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 2020 | 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 Hackborn | ef0a402 | 2016-05-11 14:21:07 -0700 | [diff] [blame] | 2040 | if (mHasSwappedOutPss) { |
| 2041 | pw.print(",swapped-out-pss"); |
| 2042 | } |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 2043 | pw.println(); |
| 2044 | pw.print("config,"); pw.println(mRuntime); |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 2045 | |
| 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 Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 2085 | } |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 2086 | } |
| 2087 | } |
| 2088 | } |
| 2089 | |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 2090 | 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 2100 | } |
| 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 Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 2154 | |
| 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 Hackborn | 9f669bf | 2019-01-14 16:21:25 -0800 | [diff] [blame] | 2162 | // Wasn't included in original output. |
| 2163 | //pw.print(mPageTypeNodes.get(i)); |
| 2164 | //pw.print(","); |
Joe Onorato | c23befa | 2016-05-19 15:46:00 -0700 | [diff] [blame] | 2165 | 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 2175 | } |
| 2176 | |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 2177 | /** |
| 2178 | * Writes to ProtoOutputStream. |
| 2179 | */ |
Jeffrey Huang | cb78285 | 2019-12-05 11:28:11 -0800 | [diff] [blame] | 2180 | public void dumpDebug(ProtoOutputStream proto, long now, int section) { |
Yi Jin | 9680cfa | 2017-09-15 15:14:43 -0700 | [diff] [blame] | 2181 | 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 Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 2189 | if ((mFlags & FLAG_SHUTDOWN) != 0) { |
Yi Jin | 9680cfa | 2017-09-15 15:14:43 -0700 | [diff] [blame] | 2190 | proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SHUTDOWN); |
| 2191 | partial = false; |
| 2192 | } |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 2193 | if ((mFlags & FLAG_SYSPROPS) != 0) { |
Yi Jin | 9680cfa | 2017-09-15 15:14:43 -0700 | [diff] [blame] | 2194 | proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SYSPROPS); |
| 2195 | partial = false; |
| 2196 | } |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 2197 | if ((mFlags & FLAG_COMPLETE) != 0) { |
Yi Jin | 9680cfa | 2017-09-15 15:14:43 -0700 | [diff] [blame] | 2198 | 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 Hackborn | 9f669bf | 2019-01-14 16:21:25 -0800 | [diff] [blame] | 2205 | 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 Hackborn | eaed0ba | 2018-08-08 17:10:17 -0700 | [diff] [blame] | 2219 | final ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap(); |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 2220 | 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 Huang | cb78285 | 2019-12-05 11:28:11 -0800 | [diff] [blame] | 2227 | procState.dumpDebug(proto, ProcessStatsSectionProto.PROCESS_STATS, procName, |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 2228 | uid, now); |
Dianne Hackborn | eaed0ba | 2018-08-08 17:10:17 -0700 | [diff] [blame] | 2229 | } |
| 2230 | } |
| 2231 | } |
| 2232 | |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 2233 | 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 Huang | cb78285 | 2019-12-05 11:28:11 -0800 | [diff] [blame] | 2242 | pkgState.dumpDebug(proto, ProcessStatsSectionProto.PACKAGE_STATS, now, |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 2243 | section); |
| 2244 | } |
| 2245 | } |
| 2246 | } |
| 2247 | } |
Yi Jin | 9680cfa | 2017-09-15 15:14:43 -0700 | [diff] [blame] | 2248 | } |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 2249 | |
| 2250 | final public static class ProcessStateHolder { |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 2251 | public final long appVersion; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 2252 | public ProcessState state; |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 2253 | public PackageState pkg; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 2254 | |
Dianne Hackborn | 3accca0 | 2013-09-20 09:32:11 -0700 | [diff] [blame] | 2255 | public ProcessStateHolder(long _appVersion) { |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 2256 | appVersion = _appVersion; |
| 2257 | } |
| 2258 | } |
| 2259 | |
| 2260 | public static final class PackageState { |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 2261 | 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 2265 | public final String mPackageName; |
| 2266 | public final int mUid; |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 2267 | public final long mVersionCode; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 2268 | |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 2269 | public PackageState(ProcessStats procStats, String packageName, int uid, long versionCode) { |
| 2270 | mProcessStats = procStats; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 2271 | mUid = uid; |
| 2272 | mPackageName = packageName; |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 2273 | mVersionCode = versionCode; |
| 2274 | } |
| 2275 | |
Dianne Hackborn | 95031ef | 2018-07-09 09:09:05 -0700 | [diff] [blame] | 2276 | public AssociationState getAssociationStateLocked(ProcessState proc, String className) { |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 2277 | AssociationState as = mAssociations.get(className); |
| 2278 | if (as != null) { |
| 2279 | if (DEBUG) Slog.d(TAG, "GETASC: returning existing " + as); |
Dianne Hackborn | 95031ef | 2018-07-09 09:09:05 -0700 | [diff] [blame] | 2280 | if (proc != null) { |
| 2281 | as.setProcess(proc); |
| 2282 | } |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 2283 | return as; |
| 2284 | } |
Dianne Hackborn | 95031ef | 2018-07-09 09:09:05 -0700 | [diff] [blame] | 2285 | as = new AssociationState(mProcessStats, this, className, proc.getName(), |
| 2286 | proc); |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 2287 | mAssociations.put(className, as); |
Dianne Hackborn | 95031ef | 2018-07-09 09:09:05 -0700 | [diff] [blame] | 2288 | if (DEBUG) Slog.d(TAG, "GETASC: creating " + as + " in " + proc.getName()); |
Dianne Hackborn | 2aec55a | 2018-06-26 10:35:35 -0700 | [diff] [blame] | 2289 | return as; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 2290 | } |
Dianne Hackborn | eaed0ba | 2018-08-08 17:10:17 -0700 | [diff] [blame] | 2291 | |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 2292 | /** |
| 2293 | * Writes the containing stats into proto, with options to choose smaller sections. |
| 2294 | */ |
Jeffrey Huang | cb78285 | 2019-12-05 11:28:11 -0800 | [diff] [blame] | 2295 | public void dumpDebug(ProtoOutputStream proto, long fieldId, long now, int section) { |
Dianne Hackborn | eaed0ba | 2018-08-08 17:10:17 -0700 | [diff] [blame] | 2296 | 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 Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 2302 | 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 Huang | cb78285 | 2019-12-05 11:28:11 -0800 | [diff] [blame] | 2306 | procState.dumpDebug(proto, ProcessStatsPackageProto.PROCESS_STATS, procName, |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 2307 | mUid, now); |
| 2308 | } |
Dianne Hackborn | eaed0ba | 2018-08-08 17:10:17 -0700 | [diff] [blame] | 2309 | } |
| 2310 | |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 2311 | 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 Huang | cb78285 | 2019-12-05 11:28:11 -0800 | [diff] [blame] | 2314 | serviceState.dumpDebug(proto, ProcessStatsPackageProto.SERVICE_STATS, |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 2315 | now); |
| 2316 | } |
Dianne Hackborn | eaed0ba | 2018-08-08 17:10:17 -0700 | [diff] [blame] | 2317 | } |
| 2318 | |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 2319 | 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 Huang | cb78285 | 2019-12-05 11:28:11 -0800 | [diff] [blame] | 2322 | ascState.dumpDebug(proto, ProcessStatsPackageProto.ASSOCIATION_STATS, |
Chenjie Yu | 4e028d0 | 2018-09-14 16:24:26 -0700 | [diff] [blame] | 2323 | now); |
| 2324 | } |
Dianne Hackborn | eaed0ba | 2018-08-08 17:10:17 -0700 | [diff] [blame] | 2325 | } |
| 2326 | |
| 2327 | proto.end(token); |
| 2328 | } |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 2329 | } |
| 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 Hackborn | e17b445 | 2018-01-10 13:15:40 -0800 | [diff] [blame] | 2344 | public long minRss; |
| 2345 | public long avgRss; |
| 2346 | public long maxRss; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 2347 | |
| 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 Hackborn | e17b445 | 2018-01-10 13:15:40 -0800 | [diff] [blame] | 2372 | 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 Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 2378 | 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 Hackborn | ef0a402 | 2016-05-11 14:21:07 -0700 | [diff] [blame] | 2408 | public boolean hasSwappedOutPss; |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 2409 | } |
| 2410 | |
| 2411 | } |