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