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 19 import android.content.ComponentName; 20 import android.os.Debug; 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; 26 import android.service.procstats.ProcessStatsAvailablePagesProto; 27 import android.service.procstats.ProcessStatsPackageProto; 28 import android.service.procstats.ProcessStatsSectionProto; 29 import android.text.format.DateFormat; 30 import android.util.ArrayMap; 31 import android.util.ArraySet; 32 import android.util.DebugUtils; 33 import android.util.LongSparseArray; 34 import android.util.Slog; 35 import android.util.SparseArray; 36 import android.util.TimeUtils; 37 import android.util.proto.ProtoOutputStream; 38 39 import com.android.internal.app.ProcessMap; 40 41 import dalvik.system.VMRuntime; 42 43 import java.io.BufferedReader; 44 import java.io.FileReader; 45 import java.io.IOException; 46 import java.io.InputStream; 47 import java.io.PrintWriter; 48 import java.util.ArrayList; 49 import java.util.Arrays; 50 import java.util.Collections; 51 import java.util.Objects; 52 import java.util.regex.Matcher; 53 import java.util.regex.Pattern; 54 55 public final class ProcessStats implements Parcelable { 56 public static final String TAG = "ProcessStats"; 57 static final boolean DEBUG = false; 58 static final boolean DEBUG_PARCEL = false; 59 60 public static final String SERVICE_NAME = "procstats"; 61 62 // How often the service commits its data, giving the minimum batching 63 // that is done. 64 public static long COMMIT_PERIOD = 3*60*60*1000; // Commit current stats every 3 hours 65 66 // Minimum uptime period before committing. If the COMMIT_PERIOD has elapsed but 67 // the total uptime has not exceeded this amount, then the commit will be held until 68 // it is reached. 69 public static long COMMIT_UPTIME_PERIOD = 60*60*1000; // Must have at least 1 hour elapsed 70 71 public static final int STATE_NOTHING = -1; 72 public static final int STATE_PERSISTENT = 0; 73 public static final int STATE_TOP = 1; 74 public static final int STATE_IMPORTANT_FOREGROUND = 2; 75 public static final int STATE_IMPORTANT_BACKGROUND = 3; 76 public static final int STATE_BACKUP = 4; 77 public static final int STATE_SERVICE = 5; 78 public static final int STATE_SERVICE_RESTARTING = 6; 79 public static final int STATE_RECEIVER = 7; 80 public static final int STATE_HEAVY_WEIGHT = 8; 81 public static final int STATE_HOME = 9; 82 public static final int STATE_LAST_ACTIVITY = 10; 83 public static final int STATE_CACHED_ACTIVITY = 11; 84 public static final int STATE_CACHED_ACTIVITY_CLIENT = 12; 85 public static final int STATE_CACHED_EMPTY = 13; 86 public static final int STATE_COUNT = STATE_CACHED_EMPTY+1; 87 88 public static final int PSS_SAMPLE_COUNT = 0; 89 public static final int PSS_MINIMUM = 1; 90 public static final int PSS_AVERAGE = 2; 91 public static final int PSS_MAXIMUM = 3; 92 public static final int PSS_USS_MINIMUM = 4; 93 public static final int PSS_USS_AVERAGE = 5; 94 public static final int PSS_USS_MAXIMUM = 6; 95 public static final int PSS_RSS_MINIMUM = 7; 96 public static final int PSS_RSS_AVERAGE = 8; 97 public static final int PSS_RSS_MAXIMUM = 9; 98 public static final int PSS_COUNT = PSS_RSS_MAXIMUM+1; 99 100 public static final int SYS_MEM_USAGE_SAMPLE_COUNT = 0; 101 public static final int SYS_MEM_USAGE_CACHED_MINIMUM = 1; 102 public static final int SYS_MEM_USAGE_CACHED_AVERAGE = 2; 103 public static final int SYS_MEM_USAGE_CACHED_MAXIMUM = 3; 104 public static final int SYS_MEM_USAGE_FREE_MINIMUM = 4; 105 public static final int SYS_MEM_USAGE_FREE_AVERAGE = 5; 106 public static final int SYS_MEM_USAGE_FREE_MAXIMUM = 6; 107 public static final int SYS_MEM_USAGE_ZRAM_MINIMUM = 7; 108 public static final int SYS_MEM_USAGE_ZRAM_AVERAGE = 8; 109 public static final int SYS_MEM_USAGE_ZRAM_MAXIMUM = 9; 110 public static final int SYS_MEM_USAGE_KERNEL_MINIMUM = 10; 111 public static final int SYS_MEM_USAGE_KERNEL_AVERAGE = 11; 112 public static final int SYS_MEM_USAGE_KERNEL_MAXIMUM = 12; 113 public static final int SYS_MEM_USAGE_NATIVE_MINIMUM = 13; 114 public static final int SYS_MEM_USAGE_NATIVE_AVERAGE = 14; 115 public static final int SYS_MEM_USAGE_NATIVE_MAXIMUM = 15; 116 public static final int SYS_MEM_USAGE_COUNT = SYS_MEM_USAGE_NATIVE_MAXIMUM+1; 117 118 public static final int ADJ_NOTHING = -1; 119 public static final int ADJ_MEM_FACTOR_NORMAL = 0; 120 public static final int ADJ_MEM_FACTOR_MODERATE = 1; 121 public static final int ADJ_MEM_FACTOR_LOW = 2; 122 public static final int ADJ_MEM_FACTOR_CRITICAL = 3; 123 public static final int ADJ_MEM_FACTOR_COUNT = ADJ_MEM_FACTOR_CRITICAL+1; 124 public static final int ADJ_SCREEN_MOD = ADJ_MEM_FACTOR_COUNT; 125 public static final int ADJ_SCREEN_OFF = 0; 126 public static final int ADJ_SCREEN_ON = ADJ_SCREEN_MOD; 127 public static final int ADJ_COUNT = ADJ_SCREEN_ON*2; 128 129 public static final int FLAG_COMPLETE = 1<<0; 130 public static final int FLAG_SHUTDOWN = 1<<1; 131 public static final int FLAG_SYSPROPS = 1<<2; 132 133 public static final int ADD_PSS_INTERNAL_SINGLE = 0; 134 public static final int ADD_PSS_INTERNAL_ALL_MEM = 1; 135 public static final int ADD_PSS_INTERNAL_ALL_POLL = 2; 136 public static final int ADD_PSS_EXTERNAL = 3; 137 public static final int ADD_PSS_EXTERNAL_SLOW = 4; 138 139 public static final int[] ALL_MEM_ADJ = new int[] { ADJ_MEM_FACTOR_NORMAL, 140 ADJ_MEM_FACTOR_MODERATE, ADJ_MEM_FACTOR_LOW, ADJ_MEM_FACTOR_CRITICAL }; 141 142 public static final int[] ALL_SCREEN_ADJ = new int[] { ADJ_SCREEN_OFF, ADJ_SCREEN_ON }; 143 144 public static final int[] NON_CACHED_PROC_STATES = new int[] { 145 STATE_PERSISTENT, STATE_TOP, STATE_IMPORTANT_FOREGROUND, 146 STATE_IMPORTANT_BACKGROUND, STATE_BACKUP, 147 STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER, STATE_HEAVY_WEIGHT 148 }; 149 150 public static final int[] BACKGROUND_PROC_STATES = new int[] { 151 STATE_IMPORTANT_FOREGROUND, STATE_IMPORTANT_BACKGROUND, STATE_BACKUP, 152 STATE_HEAVY_WEIGHT, STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER 153 }; 154 155 public static final int[] ALL_PROC_STATES = new int[] { STATE_PERSISTENT, 156 STATE_TOP, STATE_IMPORTANT_FOREGROUND, STATE_IMPORTANT_BACKGROUND, STATE_BACKUP, 157 STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER, 158 STATE_HEAVY_WEIGHT, STATE_HOME, STATE_LAST_ACTIVITY, STATE_CACHED_ACTIVITY, 159 STATE_CACHED_ACTIVITY_CLIENT, STATE_CACHED_EMPTY 160 }; 161 162 // Should report process stats. 163 public static final int REPORT_PROC_STATS = 0x01; 164 // Should report package process stats. 165 public static final int REPORT_PKG_PROC_STATS = 0x02; 166 // Should report package service stats. 167 public static final int REPORT_PKG_SVC_STATS = 0x04; 168 // Should report package association stats. 169 public static final int REPORT_PKG_ASC_STATS = 0x08; 170 // Should report package stats. 171 public static final int REPORT_PKG_STATS = 0x0E; 172 // Should report all stats. 173 public static final int REPORT_ALL = 0x0F; 174 175 public static final int[] OPTIONS = 176 {REPORT_PROC_STATS, REPORT_PKG_PROC_STATS, REPORT_PKG_SVC_STATS, REPORT_PKG_ASC_STATS, 177 REPORT_PKG_STATS, REPORT_ALL}; 178 public static final String[] OPTIONS_STR = 179 {"proc", "pkg-proc", "pkg-svc", "pkg-asc", "pkg-all", "all"}; 180 181 // Current version of the parcel format. 182 private static final int PARCEL_VERSION = 36; 183 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data 184 private static final int MAGIC = 0x50535454; 185 186 public String mReadError; 187 public String mTimePeriodStartClockStr; 188 public int mFlags; 189 190 public final ProcessMap<LongSparseArray<PackageState>> mPackages = new ProcessMap<>(); 191 public final ProcessMap<ProcessState> mProcesses = new ProcessMap<>(); 192 193 public final ArrayList<AssociationState.SourceState> mTrackingAssociations = new ArrayList<>(); 194 195 public final long[] mMemFactorDurations = new long[ADJ_COUNT]; 196 public int mMemFactor = STATE_NOTHING; 197 public long mStartTime; 198 199 public long mTimePeriodStartClock; 200 public long mTimePeriodStartRealtime; 201 public long mTimePeriodEndRealtime; 202 public long mTimePeriodStartUptime; 203 public long mTimePeriodEndUptime; 204 String mRuntime; 205 boolean mRunning; 206 207 boolean mHasSwappedOutPss; 208 209 // Count and total time expended doing "quick" single pss computations for internal use. 210 public long mInternalSinglePssCount; 211 public long mInternalSinglePssTime; 212 213 // Count and total time expended doing "quick" all mem pss computations for internal use. 214 public long mInternalAllMemPssCount; 215 public long mInternalAllMemPssTime; 216 217 // Count and total time expended doing "quick" all poll pss computations for internal use. 218 public long mInternalAllPollPssCount; 219 public long mInternalAllPollPssTime; 220 221 // Count and total time expended doing "quick" pss computations due to external requests. 222 public long mExternalPssCount; 223 public long mExternalPssTime; 224 225 // Count and total time expended doing full/slow pss computations due to external requests. 226 public long mExternalSlowPssCount; 227 public long mExternalSlowPssTime; 228 229 public final SparseMappingTable mTableData = new SparseMappingTable(); 230 231 public final long[] mSysMemUsageArgs = new long[SYS_MEM_USAGE_COUNT]; 232 public final SysMemUsageTable mSysMemUsage = new SysMemUsageTable(mTableData); 233 234 // For writing parcels. 235 ArrayMap<String, Integer> mCommonStringToIndex; 236 237 // For reading parcels. 238 ArrayList<String> mIndexToCommonString; 239 240 private static final Pattern sPageTypeRegex = Pattern.compile( 241 "^Node\\s+(\\d+),.* zone\\s+(\\w+),.* type\\s+(\\w+)\\s+([\\s\\d]+?)\\s*$"); 242 private final ArrayList<Integer> mPageTypeNodes = new ArrayList<>(); 243 private final ArrayList<String> mPageTypeZones = new ArrayList<>(); 244 private final ArrayList<String> mPageTypeLabels = new ArrayList<>(); 245 private final ArrayList<int[]> mPageTypeSizes = new ArrayList<>(); 246 ProcessStats(boolean running)247 public ProcessStats(boolean running) { 248 mRunning = running; 249 reset(); 250 if (running) { 251 // If we are actively running, we need to determine whether the system is 252 // collecting swap pss data. 253 Debug.MemoryInfo info = new Debug.MemoryInfo(); 254 Debug.getMemoryInfo(android.os.Process.myPid(), info); 255 mHasSwappedOutPss = info.hasSwappedOutPss(); 256 } 257 } 258 ProcessStats(Parcel in)259 public ProcessStats(Parcel in) { 260 reset(); 261 readFromParcel(in); 262 } 263 add(ProcessStats other)264 public void add(ProcessStats other) { 265 ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = 266 other.mPackages.getMap(); 267 for (int ip=0; ip<pkgMap.size(); ip++) { 268 final String pkgName = pkgMap.keyAt(ip); 269 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip); 270 for (int iu=0; iu<uids.size(); iu++) { 271 final int uid = uids.keyAt(iu); 272 final LongSparseArray<PackageState> versions = uids.valueAt(iu); 273 for (int iv=0; iv<versions.size(); iv++) { 274 final long vers = versions.keyAt(iv); 275 final PackageState otherState = versions.valueAt(iv); 276 final int NPROCS = otherState.mProcesses.size(); 277 final int NSRVS = otherState.mServices.size(); 278 final int NASCS = otherState.mAssociations.size(); 279 for (int iproc=0; iproc<NPROCS; iproc++) { 280 ProcessState otherProc = otherState.mProcesses.valueAt(iproc); 281 if (otherProc.getCommonProcess() != otherProc) { 282 if (DEBUG) Slog.d(TAG, "Adding pkg " + pkgName + " uid " + uid 283 + " vers " + vers + " proc " + otherProc.getName()); 284 ProcessState thisProc = getProcessStateLocked(pkgName, uid, vers, 285 otherProc.getName()); 286 if (thisProc.getCommonProcess() == thisProc) { 287 if (DEBUG) Slog.d(TAG, "Existing process is single-package, splitting"); 288 thisProc.setMultiPackage(true); 289 long now = SystemClock.uptimeMillis(); 290 final PackageState pkgState = getPackageStateLocked(pkgName, uid, 291 vers); 292 thisProc = thisProc.clone(now); 293 pkgState.mProcesses.put(thisProc.getName(), thisProc); 294 } 295 thisProc.add(otherProc); 296 } 297 } 298 for (int isvc=0; isvc<NSRVS; isvc++) { 299 ServiceState otherSvc = otherState.mServices.valueAt(isvc); 300 if (DEBUG) Slog.d(TAG, "Adding pkg " + pkgName + " uid " + uid 301 + " service " + otherSvc.getName()); 302 ServiceState thisSvc = getServiceStateLocked(pkgName, uid, vers, 303 otherSvc.getProcessName(), otherSvc.getName()); 304 thisSvc.add(otherSvc); 305 } 306 for (int iasc=0; iasc<NASCS; iasc++) { 307 AssociationState otherAsc = otherState.mAssociations.valueAt(iasc); 308 if (DEBUG) Slog.d(TAG, "Adding pkg " + pkgName + " uid " + uid 309 + " association " + otherAsc.getName()); 310 AssociationState thisAsc = getAssociationStateLocked(pkgName, uid, vers, 311 otherAsc.getProcessName(), otherAsc.getName()); 312 thisAsc.add(otherAsc); 313 } 314 } 315 } 316 } 317 318 ArrayMap<String, SparseArray<ProcessState>> procMap = other.mProcesses.getMap(); 319 for (int ip=0; ip<procMap.size(); ip++) { 320 SparseArray<ProcessState> uids = procMap.valueAt(ip); 321 for (int iu=0; iu<uids.size(); iu++) { 322 int uid = uids.keyAt(iu); 323 ProcessState otherProc = uids.valueAt(iu); 324 final String name = otherProc.getName(); 325 final String pkg = otherProc.getPackage(); 326 final long vers = otherProc.getVersion(); 327 ProcessState thisProc = mProcesses.get(name, uid); 328 if (DEBUG) Slog.d(TAG, "Adding uid " + uid + " proc " + name); 329 if (thisProc == null) { 330 if (DEBUG) Slog.d(TAG, "Creating new process!"); 331 thisProc = new ProcessState(this, pkg, uid, vers, name); 332 mProcesses.put(name, uid, thisProc); 333 PackageState thisState = getPackageStateLocked(pkg, uid, vers); 334 if (!thisState.mProcesses.containsKey(name)) { 335 thisState.mProcesses.put(name, thisProc); 336 } 337 } 338 thisProc.add(otherProc); 339 } 340 } 341 342 for (int i=0; i<ADJ_COUNT; i++) { 343 if (DEBUG) Slog.d(TAG, "Total duration #" + i + " inc by " 344 + other.mMemFactorDurations[i] + " from " 345 + mMemFactorDurations[i]); 346 mMemFactorDurations[i] += other.mMemFactorDurations[i]; 347 } 348 349 mSysMemUsage.mergeStats(other.mSysMemUsage); 350 351 if (other.mTimePeriodStartClock < mTimePeriodStartClock) { 352 mTimePeriodStartClock = other.mTimePeriodStartClock; 353 mTimePeriodStartClockStr = other.mTimePeriodStartClockStr; 354 } 355 mTimePeriodEndRealtime += other.mTimePeriodEndRealtime - other.mTimePeriodStartRealtime; 356 mTimePeriodEndUptime += other.mTimePeriodEndUptime - other.mTimePeriodStartUptime; 357 358 mInternalSinglePssCount += other.mInternalSinglePssCount; 359 mInternalSinglePssTime += other.mInternalSinglePssTime; 360 mInternalAllMemPssCount += other.mInternalAllMemPssCount; 361 mInternalAllMemPssTime += other.mInternalAllMemPssTime; 362 mInternalAllPollPssCount += other.mInternalAllPollPssCount; 363 mInternalAllPollPssTime += other.mInternalAllPollPssTime; 364 mExternalPssCount += other.mExternalPssCount; 365 mExternalPssTime += other.mExternalPssTime; 366 mExternalSlowPssCount += other.mExternalSlowPssCount; 367 mExternalSlowPssTime += other.mExternalSlowPssTime; 368 369 mHasSwappedOutPss |= other.mHasSwappedOutPss; 370 } 371 addSysMemUsage(long cachedMem, long freeMem, long zramMem, long kernelMem, long nativeMem)372 public void addSysMemUsage(long cachedMem, long freeMem, long zramMem, long kernelMem, 373 long nativeMem) { 374 if (mMemFactor != STATE_NOTHING) { 375 int state = mMemFactor * STATE_COUNT; 376 mSysMemUsageArgs[SYS_MEM_USAGE_SAMPLE_COUNT] = 1; 377 for (int i=0; i<3; i++) { 378 mSysMemUsageArgs[SYS_MEM_USAGE_CACHED_MINIMUM + i] = cachedMem; 379 mSysMemUsageArgs[SYS_MEM_USAGE_FREE_MINIMUM + i] = freeMem; 380 mSysMemUsageArgs[SYS_MEM_USAGE_ZRAM_MINIMUM + i] = zramMem; 381 mSysMemUsageArgs[SYS_MEM_USAGE_KERNEL_MINIMUM + i] = kernelMem; 382 mSysMemUsageArgs[SYS_MEM_USAGE_NATIVE_MINIMUM + i] = nativeMem; 383 } 384 mSysMemUsage.mergeStats(state, mSysMemUsageArgs, 0); 385 } 386 } 387 388 public static final Parcelable.Creator<ProcessStats> CREATOR 389 = new Parcelable.Creator<ProcessStats>() { 390 public ProcessStats createFromParcel(Parcel in) { 391 return new ProcessStats(in); 392 } 393 394 public ProcessStats[] newArray(int size) { 395 return new ProcessStats[size]; 396 } 397 }; 398 computeTotalMemoryUse(TotalMemoryUseCollection data, long now)399 public void computeTotalMemoryUse(TotalMemoryUseCollection data, long now) { 400 data.totalTime = 0; 401 for (int i=0; i<STATE_COUNT; i++) { 402 data.processStateWeight[i] = 0; 403 data.processStatePss[i] = 0; 404 data.processStateTime[i] = 0; 405 data.processStateSamples[i] = 0; 406 } 407 for (int i=0; i<SYS_MEM_USAGE_COUNT; i++) { 408 data.sysMemUsage[i] = 0; 409 } 410 data.sysMemCachedWeight = 0; 411 data.sysMemFreeWeight = 0; 412 data.sysMemZRamWeight = 0; 413 data.sysMemKernelWeight = 0; 414 data.sysMemNativeWeight = 0; 415 data.sysMemSamples = 0; 416 final long[] totalMemUsage = mSysMemUsage.getTotalMemUsage(); 417 for (int is=0; is<data.screenStates.length; is++) { 418 for (int im=0; im<data.memStates.length; im++) { 419 int memBucket = data.screenStates[is] + data.memStates[im]; 420 int stateBucket = memBucket * STATE_COUNT; 421 long memTime = mMemFactorDurations[memBucket]; 422 if (mMemFactor == memBucket) { 423 memTime += now - mStartTime; 424 } 425 data.totalTime += memTime; 426 final int sysKey = mSysMemUsage.getKey((byte)stateBucket); 427 long[] longs = totalMemUsage; 428 int idx = 0; 429 if (sysKey != SparseMappingTable.INVALID_KEY) { 430 final long[] tmpLongs = mSysMemUsage.getArrayForKey(sysKey); 431 final int tmpIndex = SparseMappingTable.getIndexFromKey(sysKey); 432 if (tmpLongs[tmpIndex+SYS_MEM_USAGE_SAMPLE_COUNT] >= 3) { 433 SysMemUsageTable.mergeSysMemUsage(data.sysMemUsage, 0, longs, idx); 434 longs = tmpLongs; 435 idx = tmpIndex; 436 } 437 } 438 data.sysMemCachedWeight += longs[idx+SYS_MEM_USAGE_CACHED_AVERAGE] 439 * (double)memTime; 440 data.sysMemFreeWeight += longs[idx+SYS_MEM_USAGE_FREE_AVERAGE] 441 * (double)memTime; 442 data.sysMemZRamWeight += longs[idx + SYS_MEM_USAGE_ZRAM_AVERAGE] 443 * (double) memTime; 444 data.sysMemKernelWeight += longs[idx+SYS_MEM_USAGE_KERNEL_AVERAGE] 445 * (double)memTime; 446 data.sysMemNativeWeight += longs[idx+SYS_MEM_USAGE_NATIVE_AVERAGE] 447 * (double)memTime; 448 data.sysMemSamples += longs[idx+SYS_MEM_USAGE_SAMPLE_COUNT]; 449 } 450 } 451 data.hasSwappedOutPss = mHasSwappedOutPss; 452 ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap(); 453 for (int iproc=0; iproc<procMap.size(); iproc++) { 454 SparseArray<ProcessState> uids = procMap.valueAt(iproc); 455 for (int iu=0; iu<uids.size(); iu++) { 456 final ProcessState proc = uids.valueAt(iu); 457 proc.aggregatePss(data, now); 458 } 459 } 460 } 461 reset()462 public void reset() { 463 if (DEBUG) Slog.d(TAG, "Resetting state of " + mTimePeriodStartClockStr); 464 resetCommon(); 465 mPackages.getMap().clear(); 466 mProcesses.getMap().clear(); 467 mMemFactor = STATE_NOTHING; 468 mStartTime = 0; 469 if (DEBUG) Slog.d(TAG, "State reset; now " + mTimePeriodStartClockStr); 470 } 471 resetSafely()472 public void resetSafely() { 473 if (DEBUG) Slog.d(TAG, "Safely resetting state of " + mTimePeriodStartClockStr); 474 resetCommon(); 475 476 // First initialize use count of all common processes. 477 final long now = SystemClock.uptimeMillis(); 478 final ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap(); 479 for (int ip=procMap.size()-1; ip>=0; ip--) { 480 final SparseArray<ProcessState> uids = procMap.valueAt(ip); 481 for (int iu=uids.size()-1; iu>=0; iu--) { 482 uids.valueAt(iu).tmpNumInUse = 0; 483 } 484 } 485 486 // Next reset or prune all per-package processes, and for the ones that are reset 487 // track this back to the common processes. 488 final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = 489 mPackages.getMap(); 490 for (int ip=pkgMap.size()-1; ip>=0; ip--) { 491 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip); 492 for (int iu=uids.size()-1; iu>=0; iu--) { 493 final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu); 494 for (int iv=vpkgs.size()-1; iv>=0; iv--) { 495 final PackageState pkgState = vpkgs.valueAt(iv); 496 for (int iproc=pkgState.mProcesses.size()-1; iproc>=0; iproc--) { 497 final ProcessState ps = pkgState.mProcesses.valueAt(iproc); 498 if (ps.isInUse()) { 499 ps.resetSafely(now); 500 ps.getCommonProcess().tmpNumInUse++; 501 ps.getCommonProcess().tmpFoundSubProc = ps; 502 } else { 503 pkgState.mProcesses.valueAt(iproc).makeDead(); 504 pkgState.mProcesses.removeAt(iproc); 505 } 506 } 507 for (int isvc=pkgState.mServices.size()-1; isvc>=0; isvc--) { 508 final ServiceState ss = pkgState.mServices.valueAt(isvc); 509 if (ss.isInUse()) { 510 ss.resetSafely(now); 511 } else { 512 pkgState.mServices.removeAt(isvc); 513 } 514 } 515 for (int iasc=pkgState.mAssociations.size()-1; iasc>=0; iasc--) { 516 final AssociationState as = pkgState.mAssociations.valueAt(iasc); 517 if (as.isInUse()) { 518 as.resetSafely(now); 519 } else { 520 pkgState.mAssociations.removeAt(iasc); 521 } 522 } 523 if (pkgState.mProcesses.size() <= 0 && pkgState.mServices.size() <= 0 524 && pkgState.mAssociations.size() <= 0) { 525 vpkgs.removeAt(iv); 526 } 527 } 528 if (vpkgs.size() <= 0) { 529 uids.removeAt(iu); 530 } 531 } 532 if (uids.size() <= 0) { 533 pkgMap.removeAt(ip); 534 } 535 } 536 537 // Finally prune out any common processes that are no longer in use. 538 for (int ip=procMap.size()-1; ip>=0; ip--) { 539 final SparseArray<ProcessState> uids = procMap.valueAt(ip); 540 for (int iu=uids.size()-1; iu>=0; iu--) { 541 ProcessState ps = uids.valueAt(iu); 542 if (ps.isInUse() || ps.tmpNumInUse > 0) { 543 // If this is a process for multiple packages, we could at this point 544 // be back down to one package. In that case, we want to revert back 545 // to a single shared ProcessState. We can do this by converting the 546 // current package-specific ProcessState up to the shared ProcessState, 547 // throwing away the current one we have here (because nobody else is 548 // using it). 549 if (!ps.isActive() && ps.isMultiPackage() && ps.tmpNumInUse == 1) { 550 // Here we go... 551 ps = ps.tmpFoundSubProc; 552 ps.makeStandalone(); 553 uids.setValueAt(iu, ps); 554 } else { 555 ps.resetSafely(now); 556 } 557 } else { 558 ps.makeDead(); 559 uids.removeAt(iu); 560 } 561 } 562 if (uids.size() <= 0) { 563 procMap.removeAt(ip); 564 } 565 } 566 567 mStartTime = now; 568 if (DEBUG) Slog.d(TAG, "State reset; now " + mTimePeriodStartClockStr); 569 } 570 resetCommon()571 private void resetCommon() { 572 mTimePeriodStartClock = System.currentTimeMillis(); 573 buildTimePeriodStartClockStr(); 574 mTimePeriodStartRealtime = mTimePeriodEndRealtime = SystemClock.elapsedRealtime(); 575 mTimePeriodStartUptime = mTimePeriodEndUptime = SystemClock.uptimeMillis(); 576 mInternalSinglePssCount = 0; 577 mInternalSinglePssTime = 0; 578 mInternalAllMemPssCount = 0; 579 mInternalAllMemPssTime = 0; 580 mInternalAllPollPssCount = 0; 581 mInternalAllPollPssTime = 0; 582 mExternalPssCount = 0; 583 mExternalPssTime = 0; 584 mExternalSlowPssCount = 0; 585 mExternalSlowPssTime = 0; 586 mTableData.reset(); 587 Arrays.fill(mMemFactorDurations, 0); 588 mSysMemUsage.resetTable(); 589 mStartTime = 0; 590 mReadError = null; 591 mFlags = 0; 592 evaluateSystemProperties(true); 593 updateFragmentation(); 594 } 595 evaluateSystemProperties(boolean update)596 public boolean evaluateSystemProperties(boolean update) { 597 boolean changed = false; 598 String runtime = SystemProperties.get("persist.sys.dalvik.vm.lib.2", 599 VMRuntime.getRuntime().vmLibrary()); 600 if (!Objects.equals(runtime, mRuntime)) { 601 changed = true; 602 if (update) { 603 mRuntime = runtime; 604 } 605 } 606 return changed; 607 } 608 buildTimePeriodStartClockStr()609 private void buildTimePeriodStartClockStr() { 610 mTimePeriodStartClockStr = DateFormat.format("yyyy-MM-dd-HH-mm-ss", 611 mTimePeriodStartClock).toString(); 612 } 613 614 static final int[] BAD_TABLE = new int[0]; 615 616 617 /** 618 * Load the system's memory fragmentation info. 619 */ updateFragmentation()620 public void updateFragmentation() { 621 // Parse /proc/pagetypeinfo and store the values. 622 BufferedReader reader = null; 623 try { 624 reader = new BufferedReader(new FileReader("/proc/pagetypeinfo")); 625 final Matcher matcher = sPageTypeRegex.matcher(""); 626 mPageTypeNodes.clear(); 627 mPageTypeZones.clear(); 628 mPageTypeLabels.clear(); 629 mPageTypeSizes.clear(); 630 while (true) { 631 final String line = reader.readLine(); 632 if (line == null) { 633 break; 634 } 635 matcher.reset(line); 636 if (matcher.matches()) { 637 final Integer node = Integer.valueOf(matcher.group(1), 10); 638 if (node == null) { 639 continue; 640 } 641 mPageTypeNodes.add(node); 642 mPageTypeZones.add(matcher.group(2)); 643 mPageTypeLabels.add(matcher.group(3)); 644 mPageTypeSizes.add(splitAndParseNumbers(matcher.group(4))); 645 } 646 } 647 } catch (IOException ex) { 648 mPageTypeNodes.clear(); 649 mPageTypeZones.clear(); 650 mPageTypeLabels.clear(); 651 mPageTypeSizes.clear(); 652 return; 653 } finally { 654 if (reader != null) { 655 try { 656 reader.close(); 657 } catch (IOException allHopeIsLost) { 658 } 659 } 660 } 661 } 662 663 /** 664 * Split the string of digits separaed by spaces. There must be no 665 * leading or trailing spaces. The format is ensured by the regex 666 * above. 667 */ splitAndParseNumbers(String s)668 private static int[] splitAndParseNumbers(String s) { 669 // These are always positive and the numbers can't be so big that we'll overflow 670 // so just do the parsing inline. 671 boolean digit = false; 672 int count = 0; 673 final int N = s.length(); 674 // Count the numbers 675 for (int i=0; i<N; i++) { 676 final char c = s.charAt(i); 677 if (c >= '0' && c <= '9') { 678 if (!digit) { 679 digit = true; 680 count++; 681 } 682 } else { 683 digit = false; 684 } 685 } 686 // Parse the numbers 687 final int[] result = new int[count]; 688 int p = 0; 689 int val = 0; 690 for (int i=0; i<N; i++) { 691 final char c = s.charAt(i); 692 if (c >= '0' && c <= '9') { 693 if (!digit) { 694 digit = true; 695 val = c - '0'; 696 } else { 697 val *= 10; 698 val += c - '0'; 699 } 700 } else { 701 if (digit) { 702 digit = false; 703 result[p++] = val; 704 } 705 } 706 } 707 if (count > 0) { 708 result[count-1] = val; 709 } 710 return result; 711 } 712 713 writeCompactedLongArray(Parcel out, long[] array, int num)714 private void writeCompactedLongArray(Parcel out, long[] array, int num) { 715 for (int i=0; i<num; i++) { 716 long val = array[i]; 717 if (val < 0) { 718 Slog.w(TAG, "Time val negative: " + val); 719 val = 0; 720 } 721 if (val <= Integer.MAX_VALUE) { 722 out.writeInt((int)val); 723 } else { 724 int top = ~((int)((val>>32)&0x7fffffff)); 725 int bottom = (int)(val&0x0ffffffffL); 726 out.writeInt(top); 727 out.writeInt(bottom); 728 } 729 } 730 } 731 readCompactedLongArray(Parcel in, int version, long[] array, int num)732 private void readCompactedLongArray(Parcel in, int version, long[] array, int num) { 733 if (version <= 10) { 734 in.readLongArray(array); 735 return; 736 } 737 final int alen = array.length; 738 if (num > alen) { 739 throw new RuntimeException("bad array lengths: got " + num + " array is " + alen); 740 } 741 int i; 742 for (i=0; i<num; i++) { 743 int val = in.readInt(); 744 if (val >= 0) { 745 array[i] = val; 746 } else { 747 int bottom = in.readInt(); 748 array[i] = (((long)~val)<<32) | bottom; 749 } 750 } 751 while (i < alen) { 752 array[i] = 0; 753 i++; 754 } 755 } 756 writeCommonString(Parcel out, String name)757 void writeCommonString(Parcel out, String name) { 758 Integer index = mCommonStringToIndex.get(name); 759 if (index != null) { 760 out.writeInt(index); 761 return; 762 } 763 index = mCommonStringToIndex.size(); 764 mCommonStringToIndex.put(name, index); 765 out.writeInt(~index); 766 out.writeString(name); 767 } 768 readCommonString(Parcel in, int version)769 String readCommonString(Parcel in, int version) { 770 if (version <= 9) { 771 return in.readString(); 772 } 773 int index = in.readInt(); 774 if (index >= 0) { 775 return mIndexToCommonString.get(index); 776 } 777 index = ~index; 778 String name = in.readString(); 779 while (mIndexToCommonString.size() <= index) { 780 mIndexToCommonString.add(null); 781 } 782 mIndexToCommonString.set(index, name); 783 return name; 784 } 785 786 @Override describeContents()787 public int describeContents() { 788 return 0; 789 } 790 791 @Override writeToParcel(Parcel out, int flags)792 public void writeToParcel(Parcel out, int flags) { 793 writeToParcel(out, SystemClock.uptimeMillis(), flags); 794 } 795 796 /** @hide */ writeToParcel(Parcel out, long now, int flags)797 public void writeToParcel(Parcel out, long now, int flags) { 798 out.writeInt(MAGIC); 799 out.writeInt(PARCEL_VERSION); 800 out.writeInt(STATE_COUNT); 801 out.writeInt(ADJ_COUNT); 802 out.writeInt(PSS_COUNT); 803 out.writeInt(SYS_MEM_USAGE_COUNT); 804 out.writeInt(SparseMappingTable.ARRAY_SIZE); 805 806 mCommonStringToIndex = new ArrayMap<String, Integer>(mProcesses.size()); 807 808 // First commit all running times. 809 ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap(); 810 final int NPROC = procMap.size(); 811 for (int ip=0; ip<NPROC; ip++) { 812 SparseArray<ProcessState> uids = procMap.valueAt(ip); 813 final int NUID = uids.size(); 814 for (int iu=0; iu<NUID; iu++) { 815 uids.valueAt(iu).commitStateTime(now); 816 } 817 } 818 final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = 819 mPackages.getMap(); 820 final int NPKG = pkgMap.size(); 821 for (int ip=0; ip<NPKG; ip++) { 822 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip); 823 final int NUID = uids.size(); 824 for (int iu=0; iu<NUID; iu++) { 825 final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu); 826 final int NVERS = vpkgs.size(); 827 for (int iv=0; iv<NVERS; iv++) { 828 PackageState pkgState = vpkgs.valueAt(iv); 829 final int NPROCS = pkgState.mProcesses.size(); 830 for (int iproc=0; iproc<NPROCS; iproc++) { 831 ProcessState proc = pkgState.mProcesses.valueAt(iproc); 832 if (proc.getCommonProcess() != proc) { 833 proc.commitStateTime(now); 834 } 835 } 836 final int NSRVS = pkgState.mServices.size(); 837 for (int isvc=0; isvc<NSRVS; isvc++) { 838 pkgState.mServices.valueAt(isvc).commitStateTime(now); 839 } 840 final int NASCS = pkgState.mAssociations.size(); 841 for (int iasc=0; iasc<NASCS; iasc++) { 842 pkgState.mAssociations.valueAt(iasc).commitStateTime(now); 843 } 844 } 845 } 846 } 847 848 out.writeLong(mTimePeriodStartClock); 849 out.writeLong(mTimePeriodStartRealtime); 850 out.writeLong(mTimePeriodEndRealtime); 851 out.writeLong(mTimePeriodStartUptime); 852 out.writeLong(mTimePeriodEndUptime); 853 out.writeLong(mInternalSinglePssCount); 854 out.writeLong(mInternalSinglePssTime); 855 out.writeLong(mInternalAllMemPssCount); 856 out.writeLong(mInternalAllMemPssTime); 857 out.writeLong(mInternalAllPollPssCount); 858 out.writeLong(mInternalAllPollPssTime); 859 out.writeLong(mExternalPssCount); 860 out.writeLong(mExternalPssTime); 861 out.writeLong(mExternalSlowPssCount); 862 out.writeLong(mExternalSlowPssTime); 863 out.writeString(mRuntime); 864 out.writeInt(mHasSwappedOutPss ? 1 : 0); 865 out.writeInt(mFlags); 866 867 mTableData.writeToParcel(out); 868 869 if (mMemFactor != STATE_NOTHING) { 870 mMemFactorDurations[mMemFactor] += now - mStartTime; 871 mStartTime = now; 872 } 873 writeCompactedLongArray(out, mMemFactorDurations, mMemFactorDurations.length); 874 875 mSysMemUsage.writeToParcel(out); 876 877 out.writeInt(NPROC); 878 for (int ip=0; ip<NPROC; ip++) { 879 writeCommonString(out, procMap.keyAt(ip)); 880 final SparseArray<ProcessState> uids = procMap.valueAt(ip); 881 final int NUID = uids.size(); 882 out.writeInt(NUID); 883 for (int iu=0; iu<NUID; iu++) { 884 out.writeInt(uids.keyAt(iu)); 885 final ProcessState proc = uids.valueAt(iu); 886 writeCommonString(out, proc.getPackage()); 887 out.writeLong(proc.getVersion()); 888 proc.writeToParcel(out, now); 889 } 890 } 891 out.writeInt(NPKG); 892 for (int ip=0; ip<NPKG; ip++) { 893 writeCommonString(out, pkgMap.keyAt(ip)); 894 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip); 895 final int NUID = uids.size(); 896 out.writeInt(NUID); 897 for (int iu=0; iu<NUID; iu++) { 898 out.writeInt(uids.keyAt(iu)); 899 final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu); 900 final int NVERS = vpkgs.size(); 901 out.writeInt(NVERS); 902 for (int iv=0; iv<NVERS; iv++) { 903 out.writeLong(vpkgs.keyAt(iv)); 904 final PackageState pkgState = vpkgs.valueAt(iv); 905 final int NPROCS = pkgState.mProcesses.size(); 906 out.writeInt(NPROCS); 907 for (int iproc=0; iproc<NPROCS; iproc++) { 908 writeCommonString(out, pkgState.mProcesses.keyAt(iproc)); 909 final ProcessState proc = pkgState.mProcesses.valueAt(iproc); 910 if (proc.getCommonProcess() == proc) { 911 // This is the same as the common process we wrote above. 912 out.writeInt(0); 913 } else { 914 // There is separate data for this package's process. 915 out.writeInt(1); 916 proc.writeToParcel(out, now); 917 } 918 } 919 final int NSRVS = pkgState.mServices.size(); 920 out.writeInt(NSRVS); 921 for (int isvc=0; isvc<NSRVS; isvc++) { 922 out.writeString(pkgState.mServices.keyAt(isvc)); 923 final ServiceState svc = pkgState.mServices.valueAt(isvc); 924 writeCommonString(out, svc.getProcessName()); 925 svc.writeToParcel(out, now); 926 } 927 final int NASCS = pkgState.mAssociations.size(); 928 out.writeInt(NASCS); 929 for (int iasc=0; iasc<NASCS; iasc++) { 930 writeCommonString(out, pkgState.mAssociations.keyAt(iasc)); 931 final AssociationState asc = pkgState.mAssociations.valueAt(iasc); 932 writeCommonString(out, asc.getProcessName()); 933 asc.writeToParcel(this, out, now); 934 } 935 } 936 } 937 } 938 939 // Fragmentation info (/proc/pagetypeinfo) 940 final int NPAGETYPES = mPageTypeLabels.size(); 941 out.writeInt(NPAGETYPES); 942 for (int i=0; i<NPAGETYPES; i++) { 943 out.writeInt(mPageTypeNodes.get(i)); 944 out.writeString(mPageTypeZones.get(i)); 945 out.writeString(mPageTypeLabels.get(i)); 946 out.writeIntArray(mPageTypeSizes.get(i)); 947 } 948 949 mCommonStringToIndex = null; 950 } 951 readCheckedInt(Parcel in, int val, String what)952 private boolean readCheckedInt(Parcel in, int val, String what) { 953 int got; 954 if ((got=in.readInt()) != val) { 955 mReadError = "bad " + what + ": " + got; 956 return false; 957 } 958 return true; 959 } 960 readFully(InputStream stream, int[] outLen)961 static byte[] readFully(InputStream stream, int[] outLen) throws IOException { 962 int pos = 0; 963 final int initialAvail = stream.available(); 964 byte[] data = new byte[initialAvail > 0 ? (initialAvail+1) : 16384]; 965 while (true) { 966 int amt = stream.read(data, pos, data.length-pos); 967 if (DEBUG_PARCEL) Slog.i("foo", "Read " + amt + " bytes at " + pos 968 + " of avail " + data.length); 969 if (amt < 0) { 970 if (DEBUG_PARCEL) Slog.i("foo", "**** FINISHED READING: pos=" + pos 971 + " len=" + data.length); 972 outLen[0] = pos; 973 return data; 974 } 975 pos += amt; 976 if (pos >= data.length) { 977 byte[] newData = new byte[pos+16384]; 978 if (DEBUG_PARCEL) Slog.i(TAG, "Copying " + pos + " bytes to new array len " 979 + newData.length); 980 System.arraycopy(data, 0, newData, 0, pos); 981 data = newData; 982 } 983 } 984 } 985 read(InputStream stream)986 public void read(InputStream stream) { 987 try { 988 int[] len = new int[1]; 989 byte[] raw = readFully(stream, len); 990 Parcel in = Parcel.obtain(); 991 in.unmarshall(raw, 0, len[0]); 992 in.setDataPosition(0); 993 stream.close(); 994 995 readFromParcel(in); 996 } catch (IOException e) { 997 mReadError = "caught exception: " + e; 998 } 999 } 1000 readFromParcel(Parcel in)1001 public void readFromParcel(Parcel in) { 1002 final boolean hadData = mPackages.getMap().size() > 0 1003 || mProcesses.getMap().size() > 0; 1004 if (hadData) { 1005 resetSafely(); 1006 } 1007 1008 if (!readCheckedInt(in, MAGIC, "magic number")) { 1009 return; 1010 } 1011 int version = in.readInt(); 1012 if (version != PARCEL_VERSION) { 1013 mReadError = "bad version: " + version; 1014 return; 1015 } 1016 if (!readCheckedInt(in, STATE_COUNT, "state count")) { 1017 return; 1018 } 1019 if (!readCheckedInt(in, ADJ_COUNT, "adj count")) { 1020 return; 1021 } 1022 if (!readCheckedInt(in, PSS_COUNT, "pss count")) { 1023 return; 1024 } 1025 if (!readCheckedInt(in, SYS_MEM_USAGE_COUNT, "sys mem usage count")) { 1026 return; 1027 } 1028 if (!readCheckedInt(in, SparseMappingTable.ARRAY_SIZE, "longs size")) { 1029 return; 1030 } 1031 1032 mIndexToCommonString = new ArrayList<String>(); 1033 1034 mTimePeriodStartClock = in.readLong(); 1035 buildTimePeriodStartClockStr(); 1036 mTimePeriodStartRealtime = in.readLong(); 1037 mTimePeriodEndRealtime = in.readLong(); 1038 mTimePeriodStartUptime = in.readLong(); 1039 mTimePeriodEndUptime = in.readLong(); 1040 mInternalSinglePssCount = in.readLong(); 1041 mInternalSinglePssTime = in.readLong(); 1042 mInternalAllMemPssCount = in.readLong(); 1043 mInternalAllMemPssTime = in.readLong(); 1044 mInternalAllPollPssCount = in.readLong(); 1045 mInternalAllPollPssTime = in.readLong(); 1046 mExternalPssCount = in.readLong(); 1047 mExternalPssTime = in.readLong(); 1048 mExternalSlowPssCount = in.readLong(); 1049 mExternalSlowPssTime = in.readLong(); 1050 mRuntime = in.readString(); 1051 mHasSwappedOutPss = in.readInt() != 0; 1052 mFlags = in.readInt(); 1053 mTableData.readFromParcel(in); 1054 readCompactedLongArray(in, version, mMemFactorDurations, mMemFactorDurations.length); 1055 if (!mSysMemUsage.readFromParcel(in)) { 1056 return; 1057 } 1058 1059 int NPROC = in.readInt(); 1060 if (NPROC < 0) { 1061 mReadError = "bad process count: " + NPROC; 1062 return; 1063 } 1064 while (NPROC > 0) { 1065 NPROC--; 1066 final String procName = readCommonString(in, version); 1067 if (procName == null) { 1068 mReadError = "bad process name"; 1069 return; 1070 } 1071 int NUID = in.readInt(); 1072 if (NUID < 0) { 1073 mReadError = "bad uid count: " + NUID; 1074 return; 1075 } 1076 while (NUID > 0) { 1077 NUID--; 1078 final int uid = in.readInt(); 1079 if (uid < 0) { 1080 mReadError = "bad uid: " + uid; 1081 return; 1082 } 1083 final String pkgName = readCommonString(in, version); 1084 if (pkgName == null) { 1085 mReadError = "bad process package name"; 1086 return; 1087 } 1088 final long vers = in.readLong(); 1089 ProcessState proc = hadData ? mProcesses.get(procName, uid) : null; 1090 if (proc != null) { 1091 if (!proc.readFromParcel(in, false)) { 1092 return; 1093 } 1094 } else { 1095 proc = new ProcessState(this, pkgName, uid, vers, procName); 1096 if (!proc.readFromParcel(in, true)) { 1097 return; 1098 } 1099 } 1100 if (DEBUG_PARCEL) Slog.d(TAG, "Adding process: " + procName + " " + uid 1101 + " " + proc); 1102 mProcesses.put(procName, uid, proc); 1103 } 1104 } 1105 1106 if (DEBUG_PARCEL) Slog.d(TAG, "Read " + mProcesses.getMap().size() + " processes"); 1107 1108 int NPKG = in.readInt(); 1109 if (NPKG < 0) { 1110 mReadError = "bad package count: " + NPKG; 1111 return; 1112 } 1113 while (NPKG > 0) { 1114 NPKG--; 1115 final String pkgName = readCommonString(in, version); 1116 if (pkgName == null) { 1117 mReadError = "bad package name"; 1118 return; 1119 } 1120 int NUID = in.readInt(); 1121 if (NUID < 0) { 1122 mReadError = "bad uid count: " + NUID; 1123 return; 1124 } 1125 while (NUID > 0) { 1126 NUID--; 1127 final int uid = in.readInt(); 1128 if (uid < 0) { 1129 mReadError = "bad uid: " + uid; 1130 return; 1131 } 1132 int NVERS = in.readInt(); 1133 if (NVERS < 0) { 1134 mReadError = "bad versions count: " + NVERS; 1135 return; 1136 } 1137 while (NVERS > 0) { 1138 NVERS--; 1139 final long vers = in.readLong(); 1140 PackageState pkgState = new PackageState(this, pkgName, uid, vers); 1141 LongSparseArray<PackageState> vpkg = mPackages.get(pkgName, uid); 1142 if (vpkg == null) { 1143 vpkg = new LongSparseArray<>(); 1144 mPackages.put(pkgName, uid, vpkg); 1145 } 1146 vpkg.put(vers, pkgState); 1147 int NPROCS = in.readInt(); 1148 if (NPROCS < 0) { 1149 mReadError = "bad package process count: " + NPROCS; 1150 return; 1151 } 1152 while (NPROCS > 0) { 1153 NPROCS--; 1154 String procName = readCommonString(in, version); 1155 if (procName == null) { 1156 mReadError = "bad package process name"; 1157 return; 1158 } 1159 int hasProc = in.readInt(); 1160 if (DEBUG_PARCEL) Slog.d(TAG, "Reading package " + pkgName + " " + uid 1161 + " process " + procName + " hasProc=" + hasProc); 1162 ProcessState commonProc = mProcesses.get(procName, uid); 1163 if (DEBUG_PARCEL) Slog.d(TAG, "Got common proc " + procName + " " + uid 1164 + ": " + commonProc); 1165 if (commonProc == null) { 1166 mReadError = "no common proc: " + procName; 1167 return; 1168 } 1169 if (hasProc != 0) { 1170 // The process for this package is unique to the package; we 1171 // need to load it. We don't need to do anything about it if 1172 // it is not unique because if someone later looks for it 1173 // they will find and use it from the global procs. 1174 ProcessState proc = hadData ? pkgState.mProcesses.get(procName) : null; 1175 if (proc != null) { 1176 if (!proc.readFromParcel(in, false)) { 1177 return; 1178 } 1179 } else { 1180 proc = new ProcessState(commonProc, pkgName, uid, vers, procName, 1181 0); 1182 if (!proc.readFromParcel(in, true)) { 1183 return; 1184 } 1185 } 1186 if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " process: " 1187 + procName + " " + uid + " " + proc); 1188 pkgState.mProcesses.put(procName, proc); 1189 } else { 1190 if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " process: " 1191 + procName + " " + uid + " " + commonProc); 1192 pkgState.mProcesses.put(procName, commonProc); 1193 } 1194 } 1195 int NSRVS = in.readInt(); 1196 if (NSRVS < 0) { 1197 mReadError = "bad package service count: " + NSRVS; 1198 return; 1199 } 1200 while (NSRVS > 0) { 1201 NSRVS--; 1202 String serviceName = in.readString(); 1203 if (serviceName == null) { 1204 mReadError = "bad package service name"; 1205 return; 1206 } 1207 String processName = version > 9 ? readCommonString(in, version) : null; 1208 ServiceState serv = hadData ? pkgState.mServices.get(serviceName) : null; 1209 if (serv == null) { 1210 serv = new ServiceState(this, pkgName, serviceName, processName, null); 1211 } 1212 if (!serv.readFromParcel(in)) { 1213 return; 1214 } 1215 if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " service: " 1216 + serviceName + " " + uid + " " + serv); 1217 pkgState.mServices.put(serviceName, serv); 1218 } 1219 int NASCS = in.readInt(); 1220 if (NASCS < 0) { 1221 mReadError = "bad package association count: " + NASCS; 1222 return; 1223 } 1224 while (NASCS > 0) { 1225 NASCS--; 1226 String associationName = readCommonString(in, version); 1227 if (associationName == null) { 1228 mReadError = "bad package association name"; 1229 return; 1230 } 1231 String processName = readCommonString(in, version); 1232 AssociationState asc = hadData 1233 ? pkgState.mAssociations.get(associationName) : null; 1234 if (asc == null) { 1235 asc = new AssociationState(this, pkgState, associationName, 1236 processName, null); 1237 } 1238 String errorMsg = asc.readFromParcel(this, in, version); 1239 if (errorMsg != null) { 1240 mReadError = errorMsg; 1241 return; 1242 } 1243 if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " association: " 1244 + associationName + " " + uid + " " + asc); 1245 pkgState.mAssociations.put(associationName, asc); 1246 } 1247 } 1248 } 1249 } 1250 1251 // Fragmentation info 1252 final int NPAGETYPES = in.readInt(); 1253 mPageTypeNodes.clear(); 1254 mPageTypeNodes.ensureCapacity(NPAGETYPES); 1255 mPageTypeZones.clear(); 1256 mPageTypeZones.ensureCapacity(NPAGETYPES); 1257 mPageTypeLabels.clear(); 1258 mPageTypeLabels.ensureCapacity(NPAGETYPES); 1259 mPageTypeSizes.clear(); 1260 mPageTypeSizes.ensureCapacity(NPAGETYPES); 1261 for (int i=0; i<NPAGETYPES; i++) { 1262 mPageTypeNodes.add(in.readInt()); 1263 mPageTypeZones.add(in.readString()); 1264 mPageTypeLabels.add(in.readString()); 1265 mPageTypeSizes.add(in.createIntArray()); 1266 } 1267 1268 mIndexToCommonString = null; 1269 1270 if (DEBUG_PARCEL) Slog.d(TAG, "Successfully read procstats!"); 1271 } 1272 getPackageStateLocked(String packageName, int uid, long vers)1273 public PackageState getPackageStateLocked(String packageName, int uid, long vers) { 1274 LongSparseArray<PackageState> vpkg = mPackages.get(packageName, uid); 1275 if (vpkg == null) { 1276 vpkg = new LongSparseArray<>(); 1277 mPackages.put(packageName, uid, vpkg); 1278 } 1279 PackageState as = vpkg.get(vers); 1280 if (as != null) { 1281 return as; 1282 } 1283 as = new PackageState(this, packageName, uid, vers); 1284 vpkg.put(vers, as); 1285 return as; 1286 } 1287 getProcessStateLocked(String packageName, int uid, long vers, String processName)1288 public ProcessState getProcessStateLocked(String packageName, int uid, long vers, 1289 String processName) { 1290 return getProcessStateLocked(getPackageStateLocked(packageName, uid, vers), processName); 1291 } 1292 getProcessStateLocked(PackageState pkgState, String processName)1293 public ProcessState getProcessStateLocked(PackageState pkgState, String processName) { 1294 ProcessState ps = pkgState.mProcesses.get(processName); 1295 if (ps != null) { 1296 return ps; 1297 } 1298 ProcessState commonProc = mProcesses.get(processName, pkgState.mUid); 1299 if (commonProc == null) { 1300 commonProc = new ProcessState(this, pkgState.mPackageName, pkgState.mUid, 1301 pkgState.mVersionCode, processName); 1302 mProcesses.put(processName, pkgState.mUid, commonProc); 1303 if (DEBUG) Slog.d(TAG, "GETPROC created new common " + commonProc); 1304 } 1305 if (!commonProc.isMultiPackage()) { 1306 if (pkgState.mPackageName.equals(commonProc.getPackage()) 1307 && pkgState.mVersionCode == commonProc.getVersion()) { 1308 // This common process is not in use by multiple packages, and 1309 // is for the calling package, so we can just use it directly. 1310 ps = commonProc; 1311 if (DEBUG) Slog.d(TAG, "GETPROC also using for pkg " + commonProc); 1312 } else { 1313 if (DEBUG) Slog.d(TAG, "GETPROC need to split common proc!"); 1314 // This common process has not been in use by multiple packages, 1315 // but it was created for a different package than the caller. 1316 // We need to convert it to a multi-package process. 1317 commonProc.setMultiPackage(true); 1318 // To do this, we need to make two new process states, one a copy 1319 // of the current state for the process under the original package 1320 // name, and the second a free new process state for it as the 1321 // new package name. 1322 long now = SystemClock.uptimeMillis(); 1323 // First let's make a copy of the current process state and put 1324 // that under the now unique state for its original package name. 1325 final PackageState commonPkgState = getPackageStateLocked(commonProc.getPackage(), 1326 pkgState.mUid, commonProc.getVersion()); 1327 if (commonPkgState != null) { 1328 ProcessState cloned = commonProc.clone(now); 1329 if (DEBUG) Slog.d(TAG, "GETPROC setting clone to pkg " + commonProc.getPackage() 1330 + ": " + cloned); 1331 commonPkgState.mProcesses.put(commonProc.getName(), cloned); 1332 // If this has active services, we need to update their process pointer 1333 // to point to the new package-specific process state. 1334 for (int i=commonPkgState.mServices.size()-1; i>=0; i--) { 1335 ServiceState ss = commonPkgState.mServices.valueAt(i); 1336 if (ss.getProcess() == commonProc) { 1337 if (DEBUG) Slog.d(TAG, "GETPROC switching service to cloned: " + ss); 1338 ss.setProcess(cloned); 1339 } else if (DEBUG) { 1340 Slog.d(TAG, "GETPROC leaving proc of " + ss); 1341 } 1342 } 1343 // Also update active associations. 1344 for (int i=commonPkgState.mAssociations.size()-1; i>=0; i--) { 1345 AssociationState as = commonPkgState.mAssociations.valueAt(i); 1346 if (as.getProcess() == commonProc) { 1347 if (DEBUG) Slog.d(TAG, "GETPROC switching association to cloned: " 1348 + as); 1349 as.setProcess(cloned); 1350 } else if (DEBUG) { 1351 Slog.d(TAG, "GETPROC leaving proc of " + as); 1352 } 1353 } 1354 } else { 1355 Slog.w(TAG, "Cloning proc state: no package state " + commonProc.getPackage() 1356 + "/" + pkgState.mUid + " for proc " + commonProc.getName()); 1357 } 1358 // And now make a fresh new process state for the new package name. 1359 ps = new ProcessState(commonProc, pkgState.mPackageName, pkgState.mUid, 1360 pkgState.mVersionCode, processName, now); 1361 if (DEBUG) Slog.d(TAG, "GETPROC created new pkg " + ps); 1362 } 1363 } else { 1364 // The common process is for multiple packages, we need to create a 1365 // separate object for the per-package data. 1366 ps = new ProcessState(commonProc, pkgState.mPackageName, pkgState.mUid, 1367 pkgState.mVersionCode, processName, 1368 SystemClock.uptimeMillis()); 1369 if (DEBUG) Slog.d(TAG, "GETPROC created new pkg " + ps); 1370 } 1371 pkgState.mProcesses.put(processName, ps); 1372 if (DEBUG) Slog.d(TAG, "GETPROC adding new pkg " + ps); 1373 return ps; 1374 } 1375 getServiceStateLocked(String packageName, int uid, long vers, String processName, String className)1376 public ServiceState getServiceStateLocked(String packageName, int uid, long vers, 1377 String processName, String className) { 1378 final ProcessStats.PackageState as = getPackageStateLocked(packageName, uid, vers); 1379 ServiceState ss = as.mServices.get(className); 1380 if (ss != null) { 1381 if (DEBUG) Slog.d(TAG, "GETSVC: returning existing " + ss); 1382 return ss; 1383 } 1384 final ProcessState ps = processName != null 1385 ? getProcessStateLocked(packageName, uid, vers, processName) : null; 1386 ss = new ServiceState(this, packageName, className, processName, ps); 1387 as.mServices.put(className, ss); 1388 if (DEBUG) Slog.d(TAG, "GETSVC: creating " + ss + " in " + ps); 1389 return ss; 1390 } 1391 getAssociationStateLocked(String packageName, int uid, long vers, String processName, String className)1392 public AssociationState getAssociationStateLocked(String packageName, int uid, long vers, 1393 String processName, String className) { 1394 final ProcessStats.PackageState pkgs = getPackageStateLocked(packageName, uid, vers); 1395 AssociationState as = pkgs.mAssociations.get(className); 1396 if (as != null) { 1397 if (DEBUG) Slog.d(TAG, "GETASC: returning existing " + as); 1398 return as; 1399 } 1400 final ProcessState procs = processName != null 1401 ? getProcessStateLocked(packageName, uid, vers, processName) : null; 1402 as = new AssociationState(this, pkgs, className, processName, procs); 1403 pkgs.mAssociations.put(className, as); 1404 if (DEBUG) Slog.d(TAG, "GETASC: creating " + as + " in " + procs); 1405 return as; 1406 } 1407 1408 // See b/118826162 -- to avoid logspaming, we rate limit the warnings. 1409 private static final long INVERSE_PROC_STATE_WARNING_MIN_INTERVAL_MS = 10_000L; 1410 private long mNextInverseProcStateWarningUptime; 1411 private int mSkippedInverseProcStateWarningCount; 1412 updateTrackingAssociationsLocked(int curSeq, long now)1413 public void updateTrackingAssociationsLocked(int curSeq, long now) { 1414 final int NUM = mTrackingAssociations.size(); 1415 for (int i = NUM - 1; i >= 0; i--) { 1416 final AssociationState.SourceState act = mTrackingAssociations.get(i); 1417 if (act.mProcStateSeq != curSeq || act.mProcState >= ProcessStats.STATE_HOME) { 1418 // If this association did not get touched the last time we computed 1419 // process states, or its state ended up down in cached, then we no 1420 // longer have a reason to track it at all. 1421 act.stopActive(now); 1422 act.mInTrackingList = false; 1423 act.mProcState = ProcessStats.STATE_NOTHING; 1424 mTrackingAssociations.remove(i); 1425 } else { 1426 final ProcessState proc = act.getAssociationState().getProcess(); 1427 if (proc != null) { 1428 final int procState = proc.getCombinedState() % STATE_COUNT; 1429 if (act.mProcState == procState) { 1430 act.startActive(now); 1431 } else { 1432 act.stopActive(now); 1433 if (act.mProcState < procState) { 1434 final long nowUptime = SystemClock.uptimeMillis(); 1435 if (mNextInverseProcStateWarningUptime > nowUptime) { 1436 mSkippedInverseProcStateWarningCount++; 1437 } else { 1438 // TODO We still see it during boot related to GMS-core. 1439 // b/118826162 1440 Slog.w(TAG, "Tracking association " + act + " whose proc state " 1441 + act.mProcState + " is better than process " + proc 1442 + " proc state " + procState 1443 + " (" + mSkippedInverseProcStateWarningCount 1444 + " skipped)"); 1445 mSkippedInverseProcStateWarningCount = 0; 1446 mNextInverseProcStateWarningUptime = 1447 nowUptime + INVERSE_PROC_STATE_WARNING_MIN_INTERVAL_MS; 1448 } 1449 } 1450 } 1451 } else { 1452 // Don't need rate limiting on it. 1453 Slog.wtf(TAG, "Tracking association without process: " + act 1454 + " in " + act.getAssociationState()); 1455 } 1456 } 1457 } 1458 } 1459 dumpLocked(PrintWriter pw, String reqPackage, long now, boolean dumpSummary, boolean dumpDetails, boolean dumpAll, boolean activeOnly, int section)1460 public void dumpLocked(PrintWriter pw, String reqPackage, long now, boolean dumpSummary, 1461 boolean dumpDetails, boolean dumpAll, boolean activeOnly, int section) { 1462 long totalTime = DumpUtils.dumpSingleTime(null, null, mMemFactorDurations, mMemFactor, 1463 mStartTime, now); 1464 boolean sepNeeded = false; 1465 if (mSysMemUsage.getKeyCount() > 0) { 1466 pw.println("System memory usage:"); 1467 mSysMemUsage.dump(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ); 1468 sepNeeded = true; 1469 } 1470 boolean printedHeader = false; 1471 if ((section & REPORT_PKG_STATS) != 0) { 1472 ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = 1473 mPackages.getMap(); 1474 for (int ip = 0; ip < pkgMap.size(); ip++) { 1475 final String pkgName = pkgMap.keyAt(ip); 1476 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip); 1477 for (int iu = 0; iu < uids.size(); iu++) { 1478 final int uid = uids.keyAt(iu); 1479 final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu); 1480 for (int iv = 0; iv < vpkgs.size(); iv++) { 1481 final long vers = vpkgs.keyAt(iv); 1482 final PackageState pkgState = vpkgs.valueAt(iv); 1483 final int NPROCS = pkgState.mProcesses.size(); 1484 final int NSRVS = pkgState.mServices.size(); 1485 final int NASCS = pkgState.mAssociations.size(); 1486 final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName); 1487 boolean onlyAssociations = false; 1488 if (!pkgMatch) { 1489 boolean procMatch = false; 1490 for (int iproc = 0; iproc < NPROCS; iproc++) { 1491 ProcessState proc = pkgState.mProcesses.valueAt(iproc); 1492 if (reqPackage.equals(proc.getName())) { 1493 procMatch = true; 1494 break; 1495 } 1496 } 1497 if (!procMatch) { 1498 // Check if this app has any associations with the requested 1499 // package, so that if so we print those. 1500 for (int iasc = 0; iasc < NASCS; iasc++) { 1501 AssociationState asc = pkgState.mAssociations.valueAt(iasc); 1502 if (asc.hasProcessOrPackage(reqPackage)) { 1503 onlyAssociations = true; 1504 break; 1505 } 1506 } 1507 if (!onlyAssociations) { 1508 continue; 1509 } 1510 } 1511 } 1512 if (NPROCS > 0 || NSRVS > 0 || NASCS > 0) { 1513 if (!printedHeader) { 1514 if (sepNeeded) pw.println(); 1515 pw.println("Per-Package Stats:"); 1516 printedHeader = true; 1517 sepNeeded = true; 1518 } 1519 pw.print(" * "); 1520 pw.print(pkgName); 1521 pw.print(" / "); 1522 UserHandle.formatUid(pw, uid); 1523 pw.print(" / v"); 1524 pw.print(vers); 1525 pw.println(":"); 1526 } 1527 if ((section & REPORT_PKG_PROC_STATS) != 0 && !onlyAssociations) { 1528 if (!dumpSummary || dumpAll) { 1529 for (int iproc = 0; iproc < NPROCS; iproc++) { 1530 ProcessState proc = pkgState.mProcesses.valueAt(iproc); 1531 if (!pkgMatch && !reqPackage.equals(proc.getName())) { 1532 continue; 1533 } 1534 if (activeOnly && !proc.isInUse()) { 1535 pw.print(" (Not active: "); 1536 pw.print(pkgState.mProcesses.keyAt(iproc)); 1537 pw.println(")"); 1538 continue; 1539 } 1540 pw.print(" Process "); 1541 pw.print(pkgState.mProcesses.keyAt(iproc)); 1542 if (proc.getCommonProcess().isMultiPackage()) { 1543 pw.print(" (multi, "); 1544 } else { 1545 pw.print(" (unique, "); 1546 } 1547 pw.print(proc.getDurationsBucketCount()); 1548 pw.print(" entries)"); 1549 pw.println(":"); 1550 proc.dumpProcessState(pw, " ", ALL_SCREEN_ADJ, 1551 ALL_MEM_ADJ, 1552 ALL_PROC_STATES, now); 1553 proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, 1554 ALL_PROC_STATES, now); 1555 proc.dumpInternalLocked(pw, " ", dumpAll); 1556 } 1557 } else { 1558 ArrayList<ProcessState> procs = new ArrayList<ProcessState>(); 1559 for (int iproc = 0; iproc < NPROCS; iproc++) { 1560 ProcessState proc = pkgState.mProcesses.valueAt(iproc); 1561 if (!pkgMatch && !reqPackage.equals(proc.getName())) { 1562 continue; 1563 } 1564 if (activeOnly && !proc.isInUse()) { 1565 continue; 1566 } 1567 procs.add(proc); 1568 } 1569 DumpUtils.dumpProcessSummaryLocked(pw, " ", "Prc ", procs, 1570 ALL_SCREEN_ADJ, ALL_MEM_ADJ, NON_CACHED_PROC_STATES, 1571 now, totalTime); 1572 } 1573 } 1574 if ((section & REPORT_PKG_SVC_STATS) != 0 && !onlyAssociations) { 1575 for (int isvc = 0; isvc < NSRVS; isvc++) { 1576 ServiceState svc = pkgState.mServices.valueAt(isvc); 1577 if (!pkgMatch && !reqPackage.equals(svc.getProcessName())) { 1578 continue; 1579 } 1580 if (activeOnly && !svc.isInUse()) { 1581 pw.print(" (Not active service: "); 1582 pw.print(pkgState.mServices.keyAt(isvc)); 1583 pw.println(")"); 1584 continue; 1585 } 1586 if (dumpAll) { 1587 pw.print(" Service "); 1588 } else { 1589 pw.print(" * Svc "); 1590 } 1591 pw.print(pkgState.mServices.keyAt(isvc)); 1592 pw.println(":"); 1593 pw.print(" Process: "); 1594 pw.println(svc.getProcessName()); 1595 svc.dumpStats(pw, " ", " ", " ", 1596 now, totalTime, dumpSummary, dumpAll); 1597 } 1598 } 1599 if ((section & REPORT_PKG_ASC_STATS) != 0) { 1600 for (int iasc = 0; iasc < NASCS; iasc++) { 1601 AssociationState asc = pkgState.mAssociations.valueAt(iasc); 1602 if (!pkgMatch && !reqPackage.equals(asc.getProcessName())) { 1603 if (!onlyAssociations || !asc.hasProcessOrPackage(reqPackage)) { 1604 continue; 1605 } 1606 } 1607 if (activeOnly && !asc.isInUse()) { 1608 pw.print(" (Not active association: "); 1609 pw.print(pkgState.mAssociations.keyAt(iasc)); 1610 pw.println(")"); 1611 continue; 1612 } 1613 if (dumpAll) { 1614 pw.print(" Association "); 1615 } else { 1616 pw.print(" * Asc "); 1617 } 1618 pw.print(pkgState.mAssociations.keyAt(iasc)); 1619 pw.println(":"); 1620 pw.print(" Process: "); 1621 pw.println(asc.getProcessName()); 1622 asc.dumpStats(pw, " ", " ", " ", 1623 now, totalTime, onlyAssociations ? reqPackage : null, 1624 dumpDetails, dumpAll); 1625 } 1626 } 1627 } 1628 } 1629 } 1630 } 1631 1632 if ((section & REPORT_PROC_STATS) != 0) { 1633 ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap(); 1634 printedHeader = false; 1635 int numShownProcs = 0, numTotalProcs = 0; 1636 for (int ip = 0; ip < procMap.size(); ip++) { 1637 String procName = procMap.keyAt(ip); 1638 SparseArray<ProcessState> uids = procMap.valueAt(ip); 1639 for (int iu = 0; iu < uids.size(); iu++) { 1640 int uid = uids.keyAt(iu); 1641 numTotalProcs++; 1642 final ProcessState proc = uids.valueAt(iu); 1643 if (!proc.hasAnyData()) { 1644 continue; 1645 } 1646 if (!proc.isMultiPackage()) { 1647 continue; 1648 } 1649 if (reqPackage != null && !reqPackage.equals(procName) 1650 && !reqPackage.equals(proc.getPackage())) { 1651 continue; 1652 } 1653 numShownProcs++; 1654 if (sepNeeded) { 1655 pw.println(); 1656 } 1657 sepNeeded = true; 1658 if (!printedHeader) { 1659 pw.println("Multi-Package Common Processes:"); 1660 printedHeader = true; 1661 } 1662 if (activeOnly && !proc.isInUse()) { 1663 pw.print(" (Not active: "); 1664 pw.print(procName); 1665 pw.println(")"); 1666 continue; 1667 } 1668 pw.print(" * "); 1669 pw.print(procName); 1670 pw.print(" / "); 1671 UserHandle.formatUid(pw, uid); 1672 pw.print(" ("); 1673 pw.print(proc.getDurationsBucketCount()); 1674 pw.print(" entries)"); 1675 pw.println(":"); 1676 proc.dumpProcessState(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, 1677 ALL_PROC_STATES, now); 1678 proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, ALL_PROC_STATES, now); 1679 proc.dumpInternalLocked(pw, " ", dumpAll); 1680 } 1681 } 1682 pw.print(" Total procs: "); pw.print(numShownProcs); 1683 pw.print(" shown of "); pw.print(numTotalProcs); pw.println(" total"); 1684 } 1685 1686 if (dumpAll) { 1687 if (sepNeeded) { 1688 pw.println(); 1689 } 1690 sepNeeded = true; 1691 1692 if (mTrackingAssociations.size() > 0) { 1693 pw.println(); 1694 pw.println("Tracking associations:"); 1695 for (int i = 0; i < mTrackingAssociations.size(); i++) { 1696 final AssociationState.SourceState src = mTrackingAssociations.get(i); 1697 final AssociationState asc = src.getAssociationState(); 1698 pw.print(" #"); 1699 pw.print(i); 1700 pw.print(": "); 1701 pw.print(asc.getProcessName()); 1702 pw.print("/"); 1703 UserHandle.formatUid(pw, asc.getUid()); 1704 pw.print(" <- "); 1705 pw.print(src.getProcessName()); 1706 pw.print("/"); 1707 UserHandle.formatUid(pw, src.getUid()); 1708 pw.println(":"); 1709 pw.print(" Tracking for: "); 1710 TimeUtils.formatDuration(now - src.mTrackingUptime, pw); 1711 pw.println(); 1712 pw.print(" Component: "); 1713 pw.print(new ComponentName(asc.getPackage(), asc.getName()) 1714 .flattenToShortString()); 1715 pw.println(); 1716 pw.print(" Proc state: "); 1717 if (src.mProcState != ProcessStats.STATE_NOTHING) { 1718 pw.print(DumpUtils.STATE_NAMES[src.mProcState]); 1719 } else { 1720 pw.print("--"); 1721 } 1722 pw.print(" #"); 1723 pw.println(src.mProcStateSeq); 1724 pw.print(" Process: "); 1725 pw.println(asc.getProcess()); 1726 if (src.mActiveCount > 0) { 1727 pw.print(" Active count "); 1728 pw.print(src.mActiveCount); 1729 pw.print(": "); 1730 asc.dumpActiveDurationSummary(pw, src, totalTime, now, dumpAll); 1731 pw.println(); 1732 } 1733 } 1734 } 1735 } 1736 1737 if (sepNeeded) { 1738 pw.println(); 1739 } 1740 if (dumpSummary) { 1741 pw.println("Process summary:"); 1742 dumpSummaryLocked(pw, reqPackage, now, activeOnly); 1743 } else { 1744 dumpTotalsLocked(pw, now); 1745 } 1746 1747 if (dumpAll) { 1748 pw.println(); 1749 pw.println("Internal state:"); 1750 /* 1751 pw.print(" Num long arrays: "); pw.println(mLongs.size()); 1752 pw.print(" Next long entry: "); pw.println(mNextLong); 1753 */ 1754 pw.print(" mRunning="); pw.println(mRunning); 1755 } 1756 1757 if (reqPackage == null) { 1758 dumpFragmentationLocked(pw); 1759 } 1760 } 1761 dumpSummaryLocked(PrintWriter pw, String reqPackage, long now, boolean activeOnly)1762 public void dumpSummaryLocked(PrintWriter pw, String reqPackage, long now, boolean activeOnly) { 1763 long totalTime = DumpUtils.dumpSingleTime(null, null, mMemFactorDurations, mMemFactor, 1764 mStartTime, now); 1765 dumpFilteredSummaryLocked(pw, null, " ", null, ALL_SCREEN_ADJ, ALL_MEM_ADJ, 1766 ALL_PROC_STATES, NON_CACHED_PROC_STATES, now, totalTime, reqPackage, activeOnly); 1767 pw.println(); 1768 dumpTotalsLocked(pw, now); 1769 } 1770 dumpFragmentationLocked(PrintWriter pw)1771 private void dumpFragmentationLocked(PrintWriter pw) { 1772 pw.println(); 1773 pw.println("Available pages by page size:"); 1774 final int NPAGETYPES = mPageTypeLabels.size(); 1775 for (int i=0; i<NPAGETYPES; i++) { 1776 pw.format("Node %3d Zone %7s %14s ", mPageTypeNodes.get(i), mPageTypeZones.get(i), 1777 mPageTypeLabels.get(i)); 1778 final int[] sizes = mPageTypeSizes.get(i); 1779 final int N = sizes == null ? 0 : sizes.length; 1780 for (int j=0; j<N; j++) { 1781 pw.format("%6d", sizes[j]); 1782 } 1783 pw.println(); 1784 } 1785 } 1786 printMemoryCategory(PrintWriter pw, String prefix, String label, double memWeight, long totalTime, long curTotalMem, int samples)1787 long printMemoryCategory(PrintWriter pw, String prefix, String label, double memWeight, 1788 long totalTime, long curTotalMem, int samples) { 1789 if (memWeight != 0) { 1790 long mem = (long)(memWeight * 1024 / totalTime); 1791 pw.print(prefix); 1792 pw.print(label); 1793 pw.print(": "); 1794 DebugUtils.printSizeValue(pw, mem); 1795 pw.print(" ("); 1796 pw.print(samples); 1797 pw.print(" samples)"); 1798 pw.println(); 1799 return curTotalMem + mem; 1800 } 1801 return curTotalMem; 1802 } 1803 dumpTotalsLocked(PrintWriter pw, long now)1804 void dumpTotalsLocked(PrintWriter pw, long now) { 1805 pw.println("Run time Stats:"); 1806 DumpUtils.dumpSingleTime(pw, " ", mMemFactorDurations, mMemFactor, mStartTime, now); 1807 pw.println(); 1808 pw.println("Memory usage:"); 1809 TotalMemoryUseCollection totalMem = new TotalMemoryUseCollection(ALL_SCREEN_ADJ, 1810 ALL_MEM_ADJ); 1811 computeTotalMemoryUse(totalMem, now); 1812 long totalPss = 0; 1813 totalPss = printMemoryCategory(pw, " ", "Kernel ", totalMem.sysMemKernelWeight, 1814 totalMem.totalTime, totalPss, totalMem.sysMemSamples); 1815 totalPss = printMemoryCategory(pw, " ", "Native ", totalMem.sysMemNativeWeight, 1816 totalMem.totalTime, totalPss, totalMem.sysMemSamples); 1817 for (int i=0; i<STATE_COUNT; i++) { 1818 // Skip restarting service state -- that is not actually a running process. 1819 if (i != STATE_SERVICE_RESTARTING) { 1820 totalPss = printMemoryCategory(pw, " ", DumpUtils.STATE_NAMES[i], 1821 totalMem.processStateWeight[i], totalMem.totalTime, totalPss, 1822 totalMem.processStateSamples[i]); 1823 } 1824 } 1825 totalPss = printMemoryCategory(pw, " ", "Cached ", totalMem.sysMemCachedWeight, 1826 totalMem.totalTime, totalPss, totalMem.sysMemSamples); 1827 totalPss = printMemoryCategory(pw, " ", "Free ", totalMem.sysMemFreeWeight, 1828 totalMem.totalTime, totalPss, totalMem.sysMemSamples); 1829 totalPss = printMemoryCategory(pw, " ", "Z-Ram ", totalMem.sysMemZRamWeight, 1830 totalMem.totalTime, totalPss, totalMem.sysMemSamples); 1831 pw.print(" TOTAL : "); 1832 DebugUtils.printSizeValue(pw, totalPss); 1833 pw.println(); 1834 printMemoryCategory(pw, " ", DumpUtils.STATE_NAMES[STATE_SERVICE_RESTARTING], 1835 totalMem.processStateWeight[STATE_SERVICE_RESTARTING], totalMem.totalTime, totalPss, 1836 totalMem.processStateSamples[STATE_SERVICE_RESTARTING]); 1837 pw.println(); 1838 pw.println("PSS collection stats:"); 1839 pw.print(" Internal Single: "); 1840 pw.print(mInternalSinglePssCount); 1841 pw.print("x over "); 1842 TimeUtils.formatDuration(mInternalSinglePssTime, pw); 1843 pw.println(); 1844 pw.print(" Internal All Procs (Memory Change): "); 1845 pw.print(mInternalAllMemPssCount); 1846 pw.print("x over "); 1847 TimeUtils.formatDuration(mInternalAllMemPssTime, pw); 1848 pw.println(); 1849 pw.print(" Internal All Procs (Polling): "); 1850 pw.print(mInternalAllPollPssCount); 1851 pw.print("x over "); 1852 TimeUtils.formatDuration(mInternalAllPollPssTime, pw); 1853 pw.println(); 1854 pw.print(" External: "); 1855 pw.print(mExternalPssCount); 1856 pw.print("x over "); 1857 TimeUtils.formatDuration(mExternalPssTime, pw); 1858 pw.println(); 1859 pw.print(" External Slow: "); 1860 pw.print(mExternalSlowPssCount); 1861 pw.print("x over "); 1862 TimeUtils.formatDuration(mExternalSlowPssTime, pw); 1863 pw.println(); 1864 pw.println(); 1865 pw.print(" Start time: "); 1866 pw.print(DateFormat.format("yyyy-MM-dd HH:mm:ss", mTimePeriodStartClock)); 1867 pw.println(); 1868 pw.print(" Total uptime: "); 1869 TimeUtils.formatDuration( 1870 (mRunning ? SystemClock.uptimeMillis() : mTimePeriodEndUptime) 1871 - mTimePeriodStartUptime, pw); 1872 pw.println(); 1873 pw.print(" Total elapsed time: "); 1874 TimeUtils.formatDuration( 1875 (mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime) 1876 - mTimePeriodStartRealtime, pw); 1877 boolean partial = true; 1878 if ((mFlags&FLAG_SHUTDOWN) != 0) { 1879 pw.print(" (shutdown)"); 1880 partial = false; 1881 } 1882 if ((mFlags&FLAG_SYSPROPS) != 0) { 1883 pw.print(" (sysprops)"); 1884 partial = false; 1885 } 1886 if ((mFlags&FLAG_COMPLETE) != 0) { 1887 pw.print(" (complete)"); 1888 partial = false; 1889 } 1890 if (partial) { 1891 pw.print(" (partial)"); 1892 } 1893 if (mHasSwappedOutPss) { 1894 pw.print(" (swapped-out-pss)"); 1895 } 1896 pw.print(' '); 1897 pw.print(mRuntime); 1898 pw.println(); 1899 } 1900 dumpFilteredSummaryLocked(PrintWriter pw, String header, String prefix, String prcLabel, int[] screenStates, int[] memStates, int[] procStates, int[] sortProcStates, long now, long totalTime, String reqPackage, boolean activeOnly)1901 void dumpFilteredSummaryLocked(PrintWriter pw, String header, String prefix, String prcLabel, 1902 int[] screenStates, int[] memStates, int[] procStates, 1903 int[] sortProcStates, long now, long totalTime, String reqPackage, boolean activeOnly) { 1904 ArrayList<ProcessState> procs = collectProcessesLocked(screenStates, memStates, 1905 procStates, sortProcStates, now, reqPackage, activeOnly); 1906 if (procs.size() > 0) { 1907 if (header != null) { 1908 pw.println(); 1909 pw.println(header); 1910 } 1911 DumpUtils.dumpProcessSummaryLocked(pw, prefix, prcLabel, procs, screenStates, memStates, 1912 sortProcStates, now, totalTime); 1913 } 1914 } 1915 collectProcessesLocked(int[] screenStates, int[] memStates, int[] procStates, int sortProcStates[], long now, String reqPackage, boolean activeOnly)1916 public ArrayList<ProcessState> collectProcessesLocked(int[] screenStates, int[] memStates, 1917 int[] procStates, int sortProcStates[], long now, String reqPackage, 1918 boolean activeOnly) { 1919 final ArraySet<ProcessState> foundProcs = new ArraySet<ProcessState>(); 1920 final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = 1921 mPackages.getMap(); 1922 for (int ip=0; ip<pkgMap.size(); ip++) { 1923 final String pkgName = pkgMap.keyAt(ip); 1924 final SparseArray<LongSparseArray<PackageState>> procs = pkgMap.valueAt(ip); 1925 for (int iu=0; iu<procs.size(); iu++) { 1926 final LongSparseArray<PackageState> vpkgs = procs.valueAt(iu); 1927 final int NVERS = vpkgs.size(); 1928 for (int iv=0; iv<NVERS; iv++) { 1929 final PackageState state = vpkgs.valueAt(iv); 1930 final int NPROCS = state.mProcesses.size(); 1931 final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName); 1932 for (int iproc=0; iproc<NPROCS; iproc++) { 1933 final ProcessState proc = state.mProcesses.valueAt(iproc); 1934 if (!pkgMatch && !reqPackage.equals(proc.getName())) { 1935 continue; 1936 } 1937 if (activeOnly && !proc.isInUse()) { 1938 continue; 1939 } 1940 foundProcs.add(proc.getCommonProcess()); 1941 } 1942 } 1943 } 1944 } 1945 ArrayList<ProcessState> outProcs = new ArrayList<ProcessState>(foundProcs.size()); 1946 for (int i=0; i<foundProcs.size(); i++) { 1947 ProcessState proc = foundProcs.valueAt(i); 1948 if (proc.computeProcessTimeLocked(screenStates, memStates, procStates, now) > 0) { 1949 outProcs.add(proc); 1950 if (procStates != sortProcStates) { 1951 proc.computeProcessTimeLocked(screenStates, memStates, sortProcStates, now); 1952 } 1953 } 1954 } 1955 Collections.sort(outProcs, ProcessState.COMPARATOR); 1956 return outProcs; 1957 } 1958 1959 /** 1960 * Prints checkin style stats dump. 1961 */ dumpCheckinLocked(PrintWriter pw, String reqPackage, int section)1962 public void dumpCheckinLocked(PrintWriter pw, String reqPackage, int section) { 1963 final long now = SystemClock.uptimeMillis(); 1964 final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = 1965 mPackages.getMap(); 1966 pw.println("vers,5"); 1967 pw.print("period,"); pw.print(mTimePeriodStartClockStr); 1968 pw.print(","); pw.print(mTimePeriodStartRealtime); pw.print(","); 1969 pw.print(mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime); 1970 boolean partial = true; 1971 if ((mFlags&FLAG_SHUTDOWN) != 0) { 1972 pw.print(",shutdown"); 1973 partial = false; 1974 } 1975 if ((mFlags&FLAG_SYSPROPS) != 0) { 1976 pw.print(",sysprops"); 1977 partial = false; 1978 } 1979 if ((mFlags&FLAG_COMPLETE) != 0) { 1980 pw.print(",complete"); 1981 partial = false; 1982 } 1983 if (partial) { 1984 pw.print(",partial"); 1985 } 1986 if (mHasSwappedOutPss) { 1987 pw.print(",swapped-out-pss"); 1988 } 1989 pw.println(); 1990 pw.print("config,"); pw.println(mRuntime); 1991 1992 if ((section & REPORT_PKG_STATS) != 0) { 1993 for (int ip = 0; ip < pkgMap.size(); ip++) { 1994 final String pkgName = pkgMap.keyAt(ip); 1995 if (reqPackage != null && !reqPackage.equals(pkgName)) { 1996 continue; 1997 } 1998 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip); 1999 for (int iu = 0; iu < uids.size(); iu++) { 2000 final int uid = uids.keyAt(iu); 2001 final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu); 2002 for (int iv = 0; iv < vpkgs.size(); iv++) { 2003 final long vers = vpkgs.keyAt(iv); 2004 final PackageState pkgState = vpkgs.valueAt(iv); 2005 final int NPROCS = pkgState.mProcesses.size(); 2006 final int NSRVS = pkgState.mServices.size(); 2007 final int NASCS = pkgState.mAssociations.size(); 2008 if ((section & REPORT_PKG_PROC_STATS) != 0) { 2009 for (int iproc = 0; iproc < NPROCS; iproc++) { 2010 ProcessState proc = pkgState.mProcesses.valueAt(iproc); 2011 proc.dumpPackageProcCheckin(pw, pkgName, uid, vers, 2012 pkgState.mProcesses.keyAt(iproc), now); 2013 } 2014 } 2015 if ((section & REPORT_PKG_SVC_STATS) != 0) { 2016 for (int isvc = 0; isvc < NSRVS; isvc++) { 2017 final String serviceName = DumpUtils.collapseString(pkgName, 2018 pkgState.mServices.keyAt(isvc)); 2019 final ServiceState svc = pkgState.mServices.valueAt(isvc); 2020 svc.dumpTimesCheckin(pw, pkgName, uid, vers, serviceName, now); 2021 } 2022 } 2023 if ((section & REPORT_PKG_ASC_STATS) != 0) { 2024 for (int iasc = 0; iasc < NASCS; iasc++) { 2025 final String associationName = DumpUtils.collapseString(pkgName, 2026 pkgState.mAssociations.keyAt(iasc)); 2027 final AssociationState asc = pkgState.mAssociations.valueAt(iasc); 2028 asc.dumpTimesCheckin(pw, pkgName, uid, vers, associationName, now); 2029 } 2030 } 2031 } 2032 } 2033 } 2034 } 2035 2036 if ((section & REPORT_PROC_STATS) != 0) { 2037 ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap(); 2038 for (int ip = 0; ip < procMap.size(); ip++) { 2039 String procName = procMap.keyAt(ip); 2040 SparseArray<ProcessState> uids = procMap.valueAt(ip); 2041 for (int iu = 0; iu < uids.size(); iu++) { 2042 final int uid = uids.keyAt(iu); 2043 final ProcessState procState = uids.valueAt(iu); 2044 procState.dumpProcCheckin(pw, procName, uid, now); 2045 } 2046 } 2047 } 2048 pw.print("total"); 2049 DumpUtils.dumpAdjTimesCheckin(pw, ",", mMemFactorDurations, mMemFactor, mStartTime, now); 2050 pw.println(); 2051 final int sysMemUsageCount = mSysMemUsage.getKeyCount(); 2052 if (sysMemUsageCount > 0) { 2053 pw.print("sysmemusage"); 2054 for (int i=0; i<sysMemUsageCount; i++) { 2055 final int key = mSysMemUsage.getKeyAt(i); 2056 final int type = SparseMappingTable.getIdFromKey(key); 2057 pw.print(","); 2058 DumpUtils.printProcStateTag(pw, type); 2059 for (int j=SYS_MEM_USAGE_SAMPLE_COUNT; j<SYS_MEM_USAGE_COUNT; j++) { 2060 if (j > SYS_MEM_USAGE_CACHED_MINIMUM) { 2061 pw.print(":"); 2062 } 2063 pw.print(mSysMemUsage.getValue(key, j)); 2064 } 2065 } 2066 } 2067 pw.println(); 2068 TotalMemoryUseCollection totalMem = new TotalMemoryUseCollection(ALL_SCREEN_ADJ, 2069 ALL_MEM_ADJ); 2070 computeTotalMemoryUse(totalMem, now); 2071 pw.print("weights,"); 2072 pw.print(totalMem.totalTime); 2073 pw.print(","); 2074 pw.print(totalMem.sysMemCachedWeight); 2075 pw.print(":"); 2076 pw.print(totalMem.sysMemSamples); 2077 pw.print(","); 2078 pw.print(totalMem.sysMemFreeWeight); 2079 pw.print(":"); 2080 pw.print(totalMem.sysMemSamples); 2081 pw.print(","); 2082 pw.print(totalMem.sysMemZRamWeight); 2083 pw.print(":"); 2084 pw.print(totalMem.sysMemSamples); 2085 pw.print(","); 2086 pw.print(totalMem.sysMemKernelWeight); 2087 pw.print(":"); 2088 pw.print(totalMem.sysMemSamples); 2089 pw.print(","); 2090 pw.print(totalMem.sysMemNativeWeight); 2091 pw.print(":"); 2092 pw.print(totalMem.sysMemSamples); 2093 for (int i=0; i<STATE_COUNT; i++) { 2094 pw.print(","); 2095 pw.print(totalMem.processStateWeight[i]); 2096 pw.print(":"); 2097 pw.print(totalMem.processStateSamples[i]); 2098 } 2099 pw.println(); 2100 2101 final int NPAGETYPES = mPageTypeLabels.size(); 2102 for (int i=0; i<NPAGETYPES; i++) { 2103 pw.print("availablepages,"); 2104 pw.print(mPageTypeLabels.get(i)); 2105 pw.print(","); 2106 pw.print(mPageTypeZones.get(i)); 2107 pw.print(","); 2108 // Wasn't included in original output. 2109 //pw.print(mPageTypeNodes.get(i)); 2110 //pw.print(","); 2111 final int[] sizes = mPageTypeSizes.get(i); 2112 final int N = sizes == null ? 0 : sizes.length; 2113 for (int j=0; j<N; j++) { 2114 if (j != 0) { 2115 pw.print(","); 2116 } 2117 pw.print(sizes[j]); 2118 } 2119 pw.println(); 2120 } 2121 } 2122 2123 /** 2124 * Writes to ProtoOutputStream. 2125 */ writeToProto(ProtoOutputStream proto, long now, int section)2126 public void writeToProto(ProtoOutputStream proto, long now, int section) { 2127 proto.write(ProcessStatsSectionProto.START_REALTIME_MS, mTimePeriodStartRealtime); 2128 proto.write(ProcessStatsSectionProto.END_REALTIME_MS, 2129 mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime); 2130 proto.write(ProcessStatsSectionProto.START_UPTIME_MS, mTimePeriodStartUptime); 2131 proto.write(ProcessStatsSectionProto.END_UPTIME_MS, mTimePeriodEndUptime); 2132 proto.write(ProcessStatsSectionProto.RUNTIME, mRuntime); 2133 proto.write(ProcessStatsSectionProto.HAS_SWAPPED_PSS, mHasSwappedOutPss); 2134 boolean partial = true; 2135 if ((mFlags & FLAG_SHUTDOWN) != 0) { 2136 proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SHUTDOWN); 2137 partial = false; 2138 } 2139 if ((mFlags & FLAG_SYSPROPS) != 0) { 2140 proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SYSPROPS); 2141 partial = false; 2142 } 2143 if ((mFlags & FLAG_COMPLETE) != 0) { 2144 proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_COMPLETE); 2145 partial = false; 2146 } 2147 if (partial) { 2148 proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_PARTIAL); 2149 } 2150 2151 final int NPAGETYPES = mPageTypeLabels.size(); 2152 for (int i = 0; i < NPAGETYPES; i++) { 2153 final long token = proto.start(ProcessStatsSectionProto.AVAILABLE_PAGES); 2154 proto.write(ProcessStatsAvailablePagesProto.NODE, mPageTypeNodes.get(i)); 2155 proto.write(ProcessStatsAvailablePagesProto.ZONE, mPageTypeZones.get(i)); 2156 proto.write(ProcessStatsAvailablePagesProto.LABEL, mPageTypeLabels.get(i)); 2157 final int[] sizes = mPageTypeSizes.get(i); 2158 final int N = sizes == null ? 0 : sizes.length; 2159 for (int j = 0; j < N; j++) { 2160 proto.write(ProcessStatsAvailablePagesProto.PAGES_PER_ORDER, sizes[j]); 2161 } 2162 proto.end(token); 2163 } 2164 2165 final ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap(); 2166 if ((section & REPORT_PROC_STATS) != 0) { 2167 for (int ip = 0; ip < procMap.size(); ip++) { 2168 final String procName = procMap.keyAt(ip); 2169 final SparseArray<ProcessState> uids = procMap.valueAt(ip); 2170 for (int iu = 0; iu < uids.size(); iu++) { 2171 final int uid = uids.keyAt(iu); 2172 final ProcessState procState = uids.valueAt(iu); 2173 procState.writeToProto(proto, ProcessStatsSectionProto.PROCESS_STATS, procName, 2174 uid, now); 2175 } 2176 } 2177 } 2178 2179 if ((section & REPORT_PKG_STATS) != 0) { 2180 final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = 2181 mPackages.getMap(); 2182 for (int ip = 0; ip < pkgMap.size(); ip++) { 2183 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip); 2184 for (int iu = 0; iu < uids.size(); iu++) { 2185 final LongSparseArray<PackageState> vers = uids.valueAt(iu); 2186 for (int iv = 0; iv < vers.size(); iv++) { 2187 final PackageState pkgState = vers.valueAt(iv); 2188 pkgState.writeToProto(proto, ProcessStatsSectionProto.PACKAGE_STATS, now, 2189 section); 2190 } 2191 } 2192 } 2193 } 2194 } 2195 2196 final public static class ProcessStateHolder { 2197 public final long appVersion; 2198 public ProcessState state; 2199 public PackageState pkg; 2200 ProcessStateHolder(long _appVersion)2201 public ProcessStateHolder(long _appVersion) { 2202 appVersion = _appVersion; 2203 } 2204 } 2205 2206 public static final class PackageState { 2207 public final ProcessStats mProcessStats; 2208 public final ArrayMap<String, ProcessState> mProcesses = new ArrayMap<>(); 2209 public final ArrayMap<String, ServiceState> mServices = new ArrayMap<>(); 2210 public final ArrayMap<String, AssociationState> mAssociations = new ArrayMap<>(); 2211 public final String mPackageName; 2212 public final int mUid; 2213 public final long mVersionCode; 2214 PackageState(ProcessStats procStats, String packageName, int uid, long versionCode)2215 public PackageState(ProcessStats procStats, String packageName, int uid, long versionCode) { 2216 mProcessStats = procStats; 2217 mUid = uid; 2218 mPackageName = packageName; 2219 mVersionCode = versionCode; 2220 } 2221 getAssociationStateLocked(ProcessState proc, String className)2222 public AssociationState getAssociationStateLocked(ProcessState proc, String className) { 2223 AssociationState as = mAssociations.get(className); 2224 if (as != null) { 2225 if (DEBUG) Slog.d(TAG, "GETASC: returning existing " + as); 2226 if (proc != null) { 2227 as.setProcess(proc); 2228 } 2229 return as; 2230 } 2231 as = new AssociationState(mProcessStats, this, className, proc.getName(), 2232 proc); 2233 mAssociations.put(className, as); 2234 if (DEBUG) Slog.d(TAG, "GETASC: creating " + as + " in " + proc.getName()); 2235 return as; 2236 } 2237 2238 /** 2239 * Writes the containing stats into proto, with options to choose smaller sections. 2240 */ writeToProto(ProtoOutputStream proto, long fieldId, long now, int section)2241 public void writeToProto(ProtoOutputStream proto, long fieldId, long now, int section) { 2242 final long token = proto.start(fieldId); 2243 2244 proto.write(ProcessStatsPackageProto.PACKAGE, mPackageName); 2245 proto.write(ProcessStatsPackageProto.UID, mUid); 2246 proto.write(ProcessStatsPackageProto.VERSION, mVersionCode); 2247 2248 if ((section & ProcessStats.REPORT_PKG_PROC_STATS) != 0) { 2249 for (int ip = 0; ip < mProcesses.size(); ip++) { 2250 final String procName = mProcesses.keyAt(ip); 2251 final ProcessState procState = mProcesses.valueAt(ip); 2252 procState.writeToProto(proto, ProcessStatsPackageProto.PROCESS_STATS, procName, 2253 mUid, now); 2254 } 2255 } 2256 2257 if ((section & ProcessStats.REPORT_PKG_SVC_STATS) != 0) { 2258 for (int is = 0; is < mServices.size(); is++) { 2259 final ServiceState serviceState = mServices.valueAt(is); 2260 serviceState.writeToProto(proto, ProcessStatsPackageProto.SERVICE_STATS, 2261 now); 2262 } 2263 } 2264 2265 if ((section & ProcessStats.REPORT_PKG_ASC_STATS) != 0) { 2266 for (int ia = 0; ia < mAssociations.size(); ia++) { 2267 final AssociationState ascState = mAssociations.valueAt(ia); 2268 ascState.writeToProto(proto, ProcessStatsPackageProto.ASSOCIATION_STATS, 2269 now); 2270 } 2271 } 2272 2273 proto.end(token); 2274 } 2275 } 2276 2277 public static final class ProcessDataCollection { 2278 final int[] screenStates; 2279 final int[] memStates; 2280 final int[] procStates; 2281 2282 public long totalTime; 2283 public long numPss; 2284 public long minPss; 2285 public long avgPss; 2286 public long maxPss; 2287 public long minUss; 2288 public long avgUss; 2289 public long maxUss; 2290 public long minRss; 2291 public long avgRss; 2292 public long maxRss; 2293 ProcessDataCollection(int[] _screenStates, int[] _memStates, int[] _procStates)2294 public ProcessDataCollection(int[] _screenStates, int[] _memStates, int[] _procStates) { 2295 screenStates = _screenStates; 2296 memStates = _memStates; 2297 procStates = _procStates; 2298 } 2299 print(PrintWriter pw, long overallTime, boolean full)2300 void print(PrintWriter pw, long overallTime, boolean full) { 2301 if (totalTime > overallTime) { 2302 pw.print("*"); 2303 } 2304 DumpUtils.printPercent(pw, (double) totalTime / (double) overallTime); 2305 if (numPss > 0) { 2306 pw.print(" ("); 2307 DebugUtils.printSizeValue(pw, minPss * 1024); 2308 pw.print("-"); 2309 DebugUtils.printSizeValue(pw, avgPss * 1024); 2310 pw.print("-"); 2311 DebugUtils.printSizeValue(pw, maxPss * 1024); 2312 pw.print("/"); 2313 DebugUtils.printSizeValue(pw, minUss * 1024); 2314 pw.print("-"); 2315 DebugUtils.printSizeValue(pw, avgUss * 1024); 2316 pw.print("-"); 2317 DebugUtils.printSizeValue(pw, maxUss * 1024); 2318 pw.print("/"); 2319 DebugUtils.printSizeValue(pw, minRss * 1024); 2320 pw.print("-"); 2321 DebugUtils.printSizeValue(pw, avgRss * 1024); 2322 pw.print("-"); 2323 DebugUtils.printSizeValue(pw, maxRss * 1024); 2324 if (full) { 2325 pw.print(" over "); 2326 pw.print(numPss); 2327 } 2328 pw.print(")"); 2329 } 2330 } 2331 } 2332 2333 public static class TotalMemoryUseCollection { 2334 final int[] screenStates; 2335 final int[] memStates; 2336 TotalMemoryUseCollection(int[] _screenStates, int[] _memStates)2337 public TotalMemoryUseCollection(int[] _screenStates, int[] _memStates) { 2338 screenStates = _screenStates; 2339 memStates = _memStates; 2340 } 2341 2342 public long totalTime; 2343 public long[] processStatePss = new long[STATE_COUNT]; 2344 public double[] processStateWeight = new double[STATE_COUNT]; 2345 public long[] processStateTime = new long[STATE_COUNT]; 2346 public int[] processStateSamples = new int[STATE_COUNT]; 2347 public long[] sysMemUsage = new long[SYS_MEM_USAGE_COUNT]; 2348 public double sysMemCachedWeight; 2349 public double sysMemFreeWeight; 2350 public double sysMemZRamWeight; 2351 public double sysMemKernelWeight; 2352 public double sysMemNativeWeight; 2353 public int sysMemSamples; 2354 public boolean hasSwappedOutPss; 2355 } 2356 2357 } 2358