/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.app.procstats;

import android.os.Debug;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.service.procstats.ProcessStatsSectionProto;
import android.text.format.DateFormat;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DebugUtils;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;

import com.android.internal.app.ProcessMap;
import com.android.internal.app.procstats.DurationsTable;
import com.android.internal.app.procstats.ProcessState;
import com.android.internal.app.procstats.PssTable;
import com.android.internal.app.procstats.ServiceState;
import com.android.internal.app.procstats.SparseMappingTable;
import com.android.internal.app.procstats.SysMemUsageTable;
import com.android.internal.app.procstats.DumpUtils.*;

import dalvik.system.VMRuntime;
import libcore.util.EmptyArray;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public final class ProcessStats implements Parcelable {
    public static final String TAG = "ProcessStats";
    static final boolean DEBUG = false;
    static final boolean DEBUG_PARCEL = false;

    public static final String SERVICE_NAME = "procstats";

    // How often the service commits its data, giving the minimum batching
    // that is done.
    public static long COMMIT_PERIOD = 3*60*60*1000;  // Commit current stats every 3 hours

    // Minimum uptime period before committing.  If the COMMIT_PERIOD has elapsed but
    // the total uptime has not exceeded this amount, then the commit will be held until
    // it is reached.
    public static long COMMIT_UPTIME_PERIOD = 60*60*1000;  // Must have at least 1 hour elapsed

    public static final int STATE_NOTHING = -1;
    public static final int STATE_PERSISTENT = 0;
    public static final int STATE_TOP = 1;
    public static final int STATE_IMPORTANT_FOREGROUND = 2;
    public static final int STATE_IMPORTANT_BACKGROUND = 3;
    public static final int STATE_BACKUP = 4;
    public static final int STATE_SERVICE = 5;
    public static final int STATE_SERVICE_RESTARTING = 6;
    public static final int STATE_RECEIVER = 7;
    public static final int STATE_HEAVY_WEIGHT = 8;
    public static final int STATE_HOME = 9;
    public static final int STATE_LAST_ACTIVITY = 10;
    public static final int STATE_CACHED_ACTIVITY = 11;
    public static final int STATE_CACHED_ACTIVITY_CLIENT = 12;
    public static final int STATE_CACHED_EMPTY = 13;
    public static final int STATE_COUNT = STATE_CACHED_EMPTY+1;

    public static final int PSS_SAMPLE_COUNT = 0;
    public static final int PSS_MINIMUM = 1;
    public static final int PSS_AVERAGE = 2;
    public static final int PSS_MAXIMUM = 3;
    public static final int PSS_USS_MINIMUM = 4;
    public static final int PSS_USS_AVERAGE = 5;
    public static final int PSS_USS_MAXIMUM = 6;
    public static final int PSS_COUNT = PSS_USS_MAXIMUM+1;

    public static final int SYS_MEM_USAGE_SAMPLE_COUNT = 0;
    public static final int SYS_MEM_USAGE_CACHED_MINIMUM = 1;
    public static final int SYS_MEM_USAGE_CACHED_AVERAGE = 2;
    public static final int SYS_MEM_USAGE_CACHED_MAXIMUM = 3;
    public static final int SYS_MEM_USAGE_FREE_MINIMUM = 4;
    public static final int SYS_MEM_USAGE_FREE_AVERAGE = 5;
    public static final int SYS_MEM_USAGE_FREE_MAXIMUM = 6;
    public static final int SYS_MEM_USAGE_ZRAM_MINIMUM = 7;
    public static final int SYS_MEM_USAGE_ZRAM_AVERAGE = 8;
    public static final int SYS_MEM_USAGE_ZRAM_MAXIMUM = 9;
    public static final int SYS_MEM_USAGE_KERNEL_MINIMUM = 10;
    public static final int SYS_MEM_USAGE_KERNEL_AVERAGE = 11;
    public static final int SYS_MEM_USAGE_KERNEL_MAXIMUM = 12;
    public static final int SYS_MEM_USAGE_NATIVE_MINIMUM = 13;
    public static final int SYS_MEM_USAGE_NATIVE_AVERAGE = 14;
    public static final int SYS_MEM_USAGE_NATIVE_MAXIMUM = 15;
    public static final int SYS_MEM_USAGE_COUNT = SYS_MEM_USAGE_NATIVE_MAXIMUM+1;

    public static final int ADJ_NOTHING = -1;
    public static final int ADJ_MEM_FACTOR_NORMAL = 0;
    public static final int ADJ_MEM_FACTOR_MODERATE = 1;
    public static final int ADJ_MEM_FACTOR_LOW = 2;
    public static final int ADJ_MEM_FACTOR_CRITICAL = 3;
    public static final int ADJ_MEM_FACTOR_COUNT = ADJ_MEM_FACTOR_CRITICAL+1;
    public static final int ADJ_SCREEN_MOD = ADJ_MEM_FACTOR_COUNT;
    public static final int ADJ_SCREEN_OFF = 0;
    public static final int ADJ_SCREEN_ON = ADJ_SCREEN_MOD;
    public static final int ADJ_COUNT = ADJ_SCREEN_ON*2;

    public static final int FLAG_COMPLETE = 1<<0;
    public static final int FLAG_SHUTDOWN = 1<<1;
    public static final int FLAG_SYSPROPS = 1<<2;

    public static final int ADD_PSS_INTERNAL = 0;
    public static final int ADD_PSS_EXTERNAL = 1;
    public static final int ADD_PSS_EXTERNAL_SLOW = 2;

    public static final int[] ALL_MEM_ADJ = new int[] { ADJ_MEM_FACTOR_NORMAL,
            ADJ_MEM_FACTOR_MODERATE, ADJ_MEM_FACTOR_LOW, ADJ_MEM_FACTOR_CRITICAL };

    public static final int[] ALL_SCREEN_ADJ = new int[] { ADJ_SCREEN_OFF, ADJ_SCREEN_ON };

    public static final int[] NON_CACHED_PROC_STATES = new int[] {
            STATE_PERSISTENT, STATE_TOP, STATE_IMPORTANT_FOREGROUND,
            STATE_IMPORTANT_BACKGROUND, STATE_BACKUP,
            STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER, STATE_HEAVY_WEIGHT
    };

    public static final int[] BACKGROUND_PROC_STATES = new int[] {
            STATE_IMPORTANT_FOREGROUND, STATE_IMPORTANT_BACKGROUND, STATE_BACKUP,
            STATE_HEAVY_WEIGHT, STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER
    };

    public static final int[] ALL_PROC_STATES = new int[] { STATE_PERSISTENT,
            STATE_TOP, STATE_IMPORTANT_FOREGROUND, STATE_IMPORTANT_BACKGROUND, STATE_BACKUP,
            STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER,
            STATE_HEAVY_WEIGHT, STATE_HOME, STATE_LAST_ACTIVITY, STATE_CACHED_ACTIVITY,
            STATE_CACHED_ACTIVITY_CLIENT, STATE_CACHED_EMPTY
    };

    // Current version of the parcel format.
    private static final int PARCEL_VERSION = 24;
    // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
    private static final int MAGIC = 0x50535454;

    public String mReadError;
    public String mTimePeriodStartClockStr;
    public int mFlags;

    public final ProcessMap<LongSparseArray<PackageState>> mPackages = new ProcessMap<>();
    public final ProcessMap<ProcessState> mProcesses = new ProcessMap<>();

    public final long[] mMemFactorDurations = new long[ADJ_COUNT];
    public int mMemFactor = STATE_NOTHING;
    public long mStartTime;

    public long mTimePeriodStartClock;
    public long mTimePeriodStartRealtime;
    public long mTimePeriodEndRealtime;
    public long mTimePeriodStartUptime;
    public long mTimePeriodEndUptime;
    String mRuntime;
    boolean mRunning;

    boolean mHasSwappedOutPss;

    // Count and total time expended doing "quick" pss computations for internal use.
    public long mInternalPssCount;
    public long mInternalPssTime;

    // Count and total time expended doing "quick" pss computations due to external requests.
    public long mExternalPssCount;
    public long mExternalPssTime;

    // Count and total time expended doing full/slow pss computations due to external requests.
    public long mExternalSlowPssCount;
    public long mExternalSlowPssTime;

    public final SparseMappingTable mTableData = new SparseMappingTable();

    public final long[] mSysMemUsageArgs = new long[SYS_MEM_USAGE_COUNT];
    public final SysMemUsageTable mSysMemUsage = new SysMemUsageTable(mTableData);

    // For writing parcels.
    ArrayMap<String, Integer> mCommonStringToIndex;

    // For reading parcels.
    ArrayList<String> mIndexToCommonString;

    private static final Pattern sPageTypeRegex = Pattern.compile(
            "^Node\\s+(\\d+),.*. type\\s+(\\w+)\\s+([\\s\\d]+?)\\s*$");
    private final ArrayList<Integer> mPageTypeZones = new ArrayList<Integer>();
    private final ArrayList<String> mPageTypeLabels = new ArrayList<String>();
    private final ArrayList<int[]> mPageTypeSizes = new ArrayList<int[]>();

    public ProcessStats(boolean running) {
        mRunning = running;
        reset();
        if (running) {
            // If we are actively running, we need to determine whether the system is
            // collecting swap pss data.
            Debug.MemoryInfo info = new Debug.MemoryInfo();
            Debug.getMemoryInfo(android.os.Process.myPid(), info);
            mHasSwappedOutPss = info.hasSwappedOutPss();
        }
    }

    public ProcessStats(Parcel in) {
        reset();
        readFromParcel(in);
    }

    public void add(ProcessStats other) {
        ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap =
                other.mPackages.getMap();
        for (int ip=0; ip<pkgMap.size(); ip++) {
            final String pkgName = pkgMap.keyAt(ip);
            final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
            for (int iu=0; iu<uids.size(); iu++) {
                final int uid = uids.keyAt(iu);
                final LongSparseArray<PackageState> versions = uids.valueAt(iu);
                for (int iv=0; iv<versions.size(); iv++) {
                    final long vers = versions.keyAt(iv);
                    final PackageState otherState = versions.valueAt(iv);
                    final int NPROCS = otherState.mProcesses.size();
                    final int NSRVS = otherState.mServices.size();
                    for (int iproc=0; iproc<NPROCS; iproc++) {
                        ProcessState otherProc = otherState.mProcesses.valueAt(iproc);
                        if (otherProc.getCommonProcess() != otherProc) {
                            if (DEBUG) Slog.d(TAG, "Adding pkg " + pkgName + " uid " + uid
                                    + " vers " + vers + " proc " + otherProc.getName());
                            ProcessState thisProc = getProcessStateLocked(pkgName, uid, vers,
                                    otherProc.getName());
                            if (thisProc.getCommonProcess() == thisProc) {
                                if (DEBUG) Slog.d(TAG, "Existing process is single-package, splitting");
                                thisProc.setMultiPackage(true);
                                long now = SystemClock.uptimeMillis();
                                final PackageState pkgState = getPackageStateLocked(pkgName, uid,
                                        vers);
                                thisProc = thisProc.clone(now);
                                pkgState.mProcesses.put(thisProc.getName(), thisProc);
                            }
                            thisProc.add(otherProc);
                        }
                    }
                    for (int isvc=0; isvc<NSRVS; isvc++) {
                        ServiceState otherSvc = otherState.mServices.valueAt(isvc);
                        if (DEBUG) Slog.d(TAG, "Adding pkg " + pkgName + " uid " + uid
                                + " service " + otherSvc.getName());
                        ServiceState thisSvc = getServiceStateLocked(pkgName, uid, vers,
                                otherSvc.getProcessName(), otherSvc.getName());
                        thisSvc.add(otherSvc);
                    }
                }
            }
        }

        ArrayMap<String, SparseArray<ProcessState>> procMap = other.mProcesses.getMap();
        for (int ip=0; ip<procMap.size(); ip++) {
            SparseArray<ProcessState> uids = procMap.valueAt(ip);
            for (int iu=0; iu<uids.size(); iu++) {
                int uid = uids.keyAt(iu);
                ProcessState otherProc = uids.valueAt(iu);
                final String name = otherProc.getName();
                final String pkg = otherProc.getPackage();
                final long vers = otherProc.getVersion();
                ProcessState thisProc = mProcesses.get(name, uid);
                if (DEBUG) Slog.d(TAG, "Adding uid " + uid + " proc " + name);
                if (thisProc == null) {
                    if (DEBUG) Slog.d(TAG, "Creating new process!");
                    thisProc = new ProcessState(this, pkg, uid, vers, name);
                    mProcesses.put(name, uid, thisProc);
                    PackageState thisState = getPackageStateLocked(pkg, uid, vers);
                    if (!thisState.mProcesses.containsKey(name)) {
                        thisState.mProcesses.put(name, thisProc);
                    }
                }
                thisProc.add(otherProc);
            }
        }

        for (int i=0; i<ADJ_COUNT; i++) {
            if (DEBUG) Slog.d(TAG, "Total duration #" + i + " inc by "
                    + other.mMemFactorDurations[i] + " from "
                    + mMemFactorDurations[i]);
            mMemFactorDurations[i] += other.mMemFactorDurations[i];
        }

        mSysMemUsage.mergeStats(other.mSysMemUsage);

        if (other.mTimePeriodStartClock < mTimePeriodStartClock) {
            mTimePeriodStartClock = other.mTimePeriodStartClock;
            mTimePeriodStartClockStr = other.mTimePeriodStartClockStr;
        }
        mTimePeriodEndRealtime += other.mTimePeriodEndRealtime - other.mTimePeriodStartRealtime;
        mTimePeriodEndUptime += other.mTimePeriodEndUptime - other.mTimePeriodStartUptime;

        mInternalPssCount += other.mInternalPssCount;
        mInternalPssTime += other.mInternalPssTime;
        mExternalPssCount += other.mExternalPssCount;
        mExternalPssTime += other.mExternalPssTime;
        mExternalSlowPssCount += other.mExternalSlowPssCount;
        mExternalSlowPssTime += other.mExternalSlowPssTime;

        mHasSwappedOutPss |= other.mHasSwappedOutPss;
    }

    public void addSysMemUsage(long cachedMem, long freeMem, long zramMem, long kernelMem,
            long nativeMem) {
        if (mMemFactor != STATE_NOTHING) {
            int state = mMemFactor * STATE_COUNT;
            mSysMemUsageArgs[SYS_MEM_USAGE_SAMPLE_COUNT] = 1;
            for (int i=0; i<3; i++) {
                mSysMemUsageArgs[SYS_MEM_USAGE_CACHED_MINIMUM + i] = cachedMem;
                mSysMemUsageArgs[SYS_MEM_USAGE_FREE_MINIMUM + i] = freeMem;
                mSysMemUsageArgs[SYS_MEM_USAGE_ZRAM_MINIMUM + i] = zramMem;
                mSysMemUsageArgs[SYS_MEM_USAGE_KERNEL_MINIMUM + i] = kernelMem;
                mSysMemUsageArgs[SYS_MEM_USAGE_NATIVE_MINIMUM + i] = nativeMem;
            }
            mSysMemUsage.mergeStats(state, mSysMemUsageArgs, 0);
        }
    }

    public static final Parcelable.Creator<ProcessStats> CREATOR
            = new Parcelable.Creator<ProcessStats>() {
        public ProcessStats createFromParcel(Parcel in) {
            return new ProcessStats(in);
        }

        public ProcessStats[] newArray(int size) {
            return new ProcessStats[size];
        }
    };

    public void computeTotalMemoryUse(TotalMemoryUseCollection data, long now) {
        data.totalTime = 0;
        for (int i=0; i<STATE_COUNT; i++) {
            data.processStateWeight[i] = 0;
            data.processStatePss[i] = 0;
            data.processStateTime[i] = 0;
            data.processStateSamples[i] = 0;
        }
        for (int i=0; i<SYS_MEM_USAGE_COUNT; i++) {
            data.sysMemUsage[i] = 0;
        }
        data.sysMemCachedWeight = 0;
        data.sysMemFreeWeight = 0;
        data.sysMemZRamWeight = 0;
        data.sysMemKernelWeight = 0;
        data.sysMemNativeWeight = 0;
        data.sysMemSamples = 0;
        final long[] totalMemUsage = mSysMemUsage.getTotalMemUsage();
        for (int is=0; is<data.screenStates.length; is++) {
            for (int im=0; im<data.memStates.length; im++) {
                int memBucket = data.screenStates[is] + data.memStates[im];
                int stateBucket = memBucket * STATE_COUNT;
                long memTime = mMemFactorDurations[memBucket];
                if (mMemFactor == memBucket) {
                    memTime += now - mStartTime;
                }
                data.totalTime += memTime;
                final int sysKey = mSysMemUsage.getKey((byte)stateBucket);
                long[] longs = totalMemUsage;
                int idx = 0;
                if (sysKey != SparseMappingTable.INVALID_KEY) {
                    final long[] tmpLongs = mSysMemUsage.getArrayForKey(sysKey);
                    final int tmpIndex = SparseMappingTable.getIndexFromKey(sysKey);
                    if (tmpLongs[tmpIndex+SYS_MEM_USAGE_SAMPLE_COUNT] >= 3) {
                        SysMemUsageTable.mergeSysMemUsage(data.sysMemUsage, 0, longs, idx);
                        longs = tmpLongs;
                        idx = tmpIndex;
                    }
                }
                data.sysMemCachedWeight += longs[idx+SYS_MEM_USAGE_CACHED_AVERAGE]
                        * (double)memTime;
                data.sysMemFreeWeight += longs[idx+SYS_MEM_USAGE_FREE_AVERAGE]
                        * (double)memTime;
                data.sysMemZRamWeight += longs[idx + SYS_MEM_USAGE_ZRAM_AVERAGE]
                        * (double) memTime;
                data.sysMemKernelWeight += longs[idx+SYS_MEM_USAGE_KERNEL_AVERAGE]
                        * (double)memTime;
                data.sysMemNativeWeight += longs[idx+SYS_MEM_USAGE_NATIVE_AVERAGE]
                        * (double)memTime;
                data.sysMemSamples += longs[idx+SYS_MEM_USAGE_SAMPLE_COUNT];
             }
        }
        data.hasSwappedOutPss = mHasSwappedOutPss;
        ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
        for (int iproc=0; iproc<procMap.size(); iproc++) {
            SparseArray<ProcessState> uids = procMap.valueAt(iproc);
            for (int iu=0; iu<uids.size(); iu++) {
                final ProcessState proc = uids.valueAt(iu);
                proc.aggregatePss(data, now);
            }
        }
    }

    public void reset() {
        if (DEBUG) Slog.d(TAG, "Resetting state of " + mTimePeriodStartClockStr);
        resetCommon();
        mPackages.getMap().clear();
        mProcesses.getMap().clear();
        mMemFactor = STATE_NOTHING;
        mStartTime = 0;
        if (DEBUG) Slog.d(TAG, "State reset; now " + mTimePeriodStartClockStr);
    }

    public void resetSafely() {
        if (DEBUG) Slog.d(TAG, "Safely resetting state of " + mTimePeriodStartClockStr);
        resetCommon();

        // First initialize use count of all common processes.
        final long now = SystemClock.uptimeMillis();
        final ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
        for (int ip=procMap.size()-1; ip>=0; ip--) {
            final SparseArray<ProcessState> uids = procMap.valueAt(ip);
            for (int iu=uids.size()-1; iu>=0; iu--) {
                uids.valueAt(iu).tmpNumInUse = 0;
           }
        }

        // Next reset or prune all per-package processes, and for the ones that are reset
        // track this back to the common processes.
        final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap =
                mPackages.getMap();
        for (int ip=pkgMap.size()-1; ip>=0; ip--) {
            final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
            for (int iu=uids.size()-1; iu>=0; iu--) {
                final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu);
                for (int iv=vpkgs.size()-1; iv>=0; iv--) {
                    final PackageState pkgState = vpkgs.valueAt(iv);
                    for (int iproc=pkgState.mProcesses.size()-1; iproc>=0; iproc--) {
                        final ProcessState ps = pkgState.mProcesses.valueAt(iproc);
                        if (ps.isInUse()) {
                            ps.resetSafely(now);
                            ps.getCommonProcess().tmpNumInUse++;
                            ps.getCommonProcess().tmpFoundSubProc = ps;
                        } else {
                            pkgState.mProcesses.valueAt(iproc).makeDead();
                            pkgState.mProcesses.removeAt(iproc);
                        }
                    }
                    for (int isvc=pkgState.mServices.size()-1; isvc>=0; isvc--) {
                        final ServiceState ss = pkgState.mServices.valueAt(isvc);
                        if (ss.isInUse()) {
                            ss.resetSafely(now);
                        } else {
                            pkgState.mServices.removeAt(isvc);
                        }
                    }
                    if (pkgState.mProcesses.size() <= 0 && pkgState.mServices.size() <= 0) {
                        vpkgs.removeAt(iv);
                    }
                }
                if (vpkgs.size() <= 0) {
                    uids.removeAt(iu);
                }
            }
            if (uids.size() <= 0) {
                pkgMap.removeAt(ip);
            }
        }

        // Finally prune out any common processes that are no longer in use.
        for (int ip=procMap.size()-1; ip>=0; ip--) {
            final SparseArray<ProcessState> uids = procMap.valueAt(ip);
            for (int iu=uids.size()-1; iu>=0; iu--) {
                ProcessState ps = uids.valueAt(iu);
                if (ps.isInUse() || ps.tmpNumInUse > 0) {
                    // If this is a process for multiple packages, we could at this point
                    // be back down to one package.  In that case, we want to revert back
                    // to a single shared ProcessState.  We can do this by converting the
                    // current package-specific ProcessState up to the shared ProcessState,
                    // throwing away the current one we have here (because nobody else is
                    // using it).
                    if (!ps.isActive() && ps.isMultiPackage() && ps.tmpNumInUse == 1) {
                        // Here we go...
                        ps = ps.tmpFoundSubProc;
                        ps.makeStandalone();
                        uids.setValueAt(iu, ps);
                    } else {
                        ps.resetSafely(now);
                    }
                } else {
                    ps.makeDead();
                    uids.removeAt(iu);
                }
            }
            if (uids.size() <= 0) {
                procMap.removeAt(ip);
            }
        }

        mStartTime = now;
        if (DEBUG) Slog.d(TAG, "State reset; now " + mTimePeriodStartClockStr);
    }

    private void resetCommon() {
        mTimePeriodStartClock = System.currentTimeMillis();
        buildTimePeriodStartClockStr();
        mTimePeriodStartRealtime = mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
        mTimePeriodStartUptime = mTimePeriodEndUptime = SystemClock.uptimeMillis();
        mInternalPssCount = 0;
        mInternalPssTime = 0;
        mExternalPssCount = 0;
        mExternalPssTime = 0;
        mExternalSlowPssCount = 0;
        mExternalSlowPssTime = 0;
        mTableData.reset();
        Arrays.fill(mMemFactorDurations, 0);
        mSysMemUsage.resetTable();
        mStartTime = 0;
        mReadError = null;
        mFlags = 0;
        evaluateSystemProperties(true);
        updateFragmentation();
    }

    public boolean evaluateSystemProperties(boolean update) {
        boolean changed = false;
        String runtime = SystemProperties.get("persist.sys.dalvik.vm.lib.2",
                VMRuntime.getRuntime().vmLibrary());
        if (!Objects.equals(runtime, mRuntime)) {
            changed = true;
            if (update) {
                mRuntime = runtime;
            }
        }
        return changed;
    }

    private void buildTimePeriodStartClockStr() {
        mTimePeriodStartClockStr = DateFormat.format("yyyy-MM-dd-HH-mm-ss",
                mTimePeriodStartClock).toString();
    }

    static final int[] BAD_TABLE = new int[0];


    /**
     * Load the system's memory fragmentation info.
     */
    public void updateFragmentation() {
        // Parse /proc/pagetypeinfo and store the values.
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader("/proc/pagetypeinfo"));
            final Matcher matcher = sPageTypeRegex.matcher("");
            mPageTypeZones.clear();
            mPageTypeLabels.clear();
            mPageTypeSizes.clear();
            while (true) {
                final String line = reader.readLine();
                if (line == null) {
                    break;
                }
                matcher.reset(line);
                if (matcher.matches()) {
                    final Integer zone = Integer.valueOf(matcher.group(1), 10);
                    if (zone == null) {
                        continue;
                    }
                    mPageTypeZones.add(zone);
                    mPageTypeLabels.add(matcher.group(2));
                    mPageTypeSizes.add(splitAndParseNumbers(matcher.group(3)));
                }
            }
        } catch (IOException ex) {
            mPageTypeZones.clear();
            mPageTypeLabels.clear();
            mPageTypeSizes.clear();
            return;
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException allHopeIsLost) {
                }
            }
        }
    }

    /**
     * Split the string of digits separaed by spaces.  There must be no
     * leading or trailing spaces.  The format is ensured by the regex
     * above.
     */
    private static int[] splitAndParseNumbers(String s) {
        // These are always positive and the numbers can't be so big that we'll overflow
        // so just do the parsing inline.
        boolean digit = false;
        int count = 0;
        final int N = s.length();
        // Count the numbers
        for (int i=0; i<N; i++) {
            final char c = s.charAt(i);
            if (c >= '0' && c <= '9') {
                if (!digit) {
                    digit = true;
                    count++;
                }
            } else {
                digit = false;
            }
        }
        // Parse the numbers
        final int[] result = new int[count];
        int p = 0;
        int val = 0;
        for (int i=0; i<N; i++) {
            final char c = s.charAt(i);
            if (c >= '0' && c <= '9') {
                if (!digit) {
                    digit = true;
                    val = c - '0';
                } else {
                    val *= 10;
                    val += c - '0';
                }
            } else {
                if (digit) {
                    digit = false;
                    result[p++] = val;
                }
            }
        }
        if (count > 0) {
            result[count-1] = val;
        }
        return result;
    }


    private void writeCompactedLongArray(Parcel out, long[] array, int num) {
        for (int i=0; i<num; i++) {
            long val = array[i];
            if (val < 0) {
                Slog.w(TAG, "Time val negative: " + val);
                val = 0;
            }
            if (val <= Integer.MAX_VALUE) {
                out.writeInt((int)val);
            } else {
                int top = ~((int)((val>>32)&0x7fffffff));
                int bottom = (int)(val&0x0ffffffffL);
                out.writeInt(top);
                out.writeInt(bottom);
            }
        }
    }

    private void readCompactedLongArray(Parcel in, int version, long[] array, int num) {
        if (version <= 10) {
            in.readLongArray(array);
            return;
        }
        final int alen = array.length;
        if (num > alen) {
            throw new RuntimeException("bad array lengths: got " + num + " array is " + alen);
        }
        int i;
        for (i=0; i<num; i++) {
            int val = in.readInt();
            if (val >= 0) {
                array[i] = val;
            } else {
                int bottom = in.readInt();
                array[i] = (((long)~val)<<32) | bottom;
            }
        }
        while (i < alen) {
            array[i] = 0;
            i++;
        }
    }

    private void writeCommonString(Parcel out, String name) {
        Integer index = mCommonStringToIndex.get(name);
        if (index != null) {
            out.writeInt(index);
            return;
        }
        index = mCommonStringToIndex.size();
        mCommonStringToIndex.put(name, index);
        out.writeInt(~index);
        out.writeString(name);
    }

    private String readCommonString(Parcel in, int version) {
        if (version <= 9) {
            return in.readString();
        }
        int index = in.readInt();
        if (index >= 0) {
            return mIndexToCommonString.get(index);
        }
        index = ~index;
        String name = in.readString();
        while (mIndexToCommonString.size() <= index) {
            mIndexToCommonString.add(null);
        }
        mIndexToCommonString.set(index, name);
        return name;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        writeToParcel(out, SystemClock.uptimeMillis(), flags);
    }

    /** @hide */
    public void writeToParcel(Parcel out, long now, int flags) {
        out.writeInt(MAGIC);
        out.writeInt(PARCEL_VERSION);
        out.writeInt(STATE_COUNT);
        out.writeInt(ADJ_COUNT);
        out.writeInt(PSS_COUNT);
        out.writeInt(SYS_MEM_USAGE_COUNT);
        out.writeInt(SparseMappingTable.ARRAY_SIZE);

        mCommonStringToIndex = new ArrayMap<String, Integer>(mProcesses.size());

        // First commit all running times.
        ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
        final int NPROC = procMap.size();
        for (int ip=0; ip<NPROC; ip++) {
            SparseArray<ProcessState> uids = procMap.valueAt(ip);
            final int NUID = uids.size();
            for (int iu=0; iu<NUID; iu++) {
                uids.valueAt(iu).commitStateTime(now);
            }
        }
        final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap =
                mPackages.getMap();
        final int NPKG = pkgMap.size();
        for (int ip=0; ip<NPKG; ip++) {
            final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
            final int NUID = uids.size();
            for (int iu=0; iu<NUID; iu++) {
                final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu);
                final int NVERS = vpkgs.size();
                for (int iv=0; iv<NVERS; iv++) {
                    PackageState pkgState = vpkgs.valueAt(iv);
                    final int NPROCS = pkgState.mProcesses.size();
                    for (int iproc=0; iproc<NPROCS; iproc++) {
                        ProcessState proc = pkgState.mProcesses.valueAt(iproc);
                        if (proc.getCommonProcess() != proc) {
                            proc.commitStateTime(now);
                        }
                    }
                    final int NSRVS = pkgState.mServices.size();
                    for (int isvc=0; isvc<NSRVS; isvc++) {
                        pkgState.mServices.valueAt(isvc).commitStateTime(now);
                    }
                }
            }
        }

        out.writeLong(mTimePeriodStartClock);
        out.writeLong(mTimePeriodStartRealtime);
        out.writeLong(mTimePeriodEndRealtime);
        out.writeLong(mTimePeriodStartUptime);
        out.writeLong(mTimePeriodEndUptime);
        out.writeLong(mInternalPssCount);
        out.writeLong(mInternalPssTime);
        out.writeLong(mExternalPssCount);
        out.writeLong(mExternalPssTime);
        out.writeLong(mExternalSlowPssCount);
        out.writeLong(mExternalSlowPssTime);
        out.writeString(mRuntime);
        out.writeInt(mHasSwappedOutPss ? 1 : 0);
        out.writeInt(mFlags);

        mTableData.writeToParcel(out);

        if (mMemFactor != STATE_NOTHING) {
            mMemFactorDurations[mMemFactor] += now - mStartTime;
            mStartTime = now;
        }
        writeCompactedLongArray(out, mMemFactorDurations, mMemFactorDurations.length);

        mSysMemUsage.writeToParcel(out);

        out.writeInt(NPROC);
        for (int ip=0; ip<NPROC; ip++) {
            writeCommonString(out, procMap.keyAt(ip));
            final SparseArray<ProcessState> uids = procMap.valueAt(ip);
            final int NUID = uids.size();
            out.writeInt(NUID);
            for (int iu=0; iu<NUID; iu++) {
                out.writeInt(uids.keyAt(iu));
                final ProcessState proc = uids.valueAt(iu);
                writeCommonString(out, proc.getPackage());
                out.writeLong(proc.getVersion());
                proc.writeToParcel(out, now);
            }
        }
        out.writeInt(NPKG);
        for (int ip=0; ip<NPKG; ip++) {
            writeCommonString(out, pkgMap.keyAt(ip));
            final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
            final int NUID = uids.size();
            out.writeInt(NUID);
            for (int iu=0; iu<NUID; iu++) {
                out.writeInt(uids.keyAt(iu));
                final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu);
                final int NVERS = vpkgs.size();
                out.writeInt(NVERS);
                for (int iv=0; iv<NVERS; iv++) {
                    out.writeLong(vpkgs.keyAt(iv));
                    final PackageState pkgState = vpkgs.valueAt(iv);
                    final int NPROCS = pkgState.mProcesses.size();
                    out.writeInt(NPROCS);
                    for (int iproc=0; iproc<NPROCS; iproc++) {
                        writeCommonString(out, pkgState.mProcesses.keyAt(iproc));
                        final ProcessState proc = pkgState.mProcesses.valueAt(iproc);
                        if (proc.getCommonProcess() == proc) {
                            // This is the same as the common process we wrote above.
                            out.writeInt(0);
                        } else {
                            // There is separate data for this package's process.
                            out.writeInt(1);
                            proc.writeToParcel(out, now);
                        }
                    }
                    final int NSRVS = pkgState.mServices.size();
                    out.writeInt(NSRVS);
                    for (int isvc=0; isvc<NSRVS; isvc++) {
                        out.writeString(pkgState.mServices.keyAt(isvc));
                        final ServiceState svc = pkgState.mServices.valueAt(isvc);
                        writeCommonString(out, svc.getProcessName());
                        svc.writeToParcel(out, now);
                    }
                }
            }
        }

        // Fragmentation info (/proc/pagetypeinfo)
        final int NPAGETYPES = mPageTypeLabels.size();
        out.writeInt(NPAGETYPES);
        for (int i=0; i<NPAGETYPES; i++) {
            out.writeInt(mPageTypeZones.get(i));
            out.writeString(mPageTypeLabels.get(i));
            out.writeIntArray(mPageTypeSizes.get(i));
        }

        mCommonStringToIndex = null;
    }

    private boolean readCheckedInt(Parcel in, int val, String what) {
        int got;
        if ((got=in.readInt()) != val) {
            mReadError = "bad " + what + ": " + got;
            return false;
        }
        return true;
    }

    static byte[] readFully(InputStream stream, int[] outLen) throws IOException {
        int pos = 0;
        final int initialAvail = stream.available();
        byte[] data = new byte[initialAvail > 0 ? (initialAvail+1) : 16384];
        while (true) {
            int amt = stream.read(data, pos, data.length-pos);
            if (DEBUG_PARCEL) Slog.i("foo", "Read " + amt + " bytes at " + pos
                    + " of avail " + data.length);
            if (amt < 0) {
                if (DEBUG_PARCEL) Slog.i("foo", "**** FINISHED READING: pos=" + pos
                        + " len=" + data.length);
                outLen[0] = pos;
                return data;
            }
            pos += amt;
            if (pos >= data.length) {
                byte[] newData = new byte[pos+16384];
                if (DEBUG_PARCEL) Slog.i(TAG, "Copying " + pos + " bytes to new array len "
                        + newData.length);
                System.arraycopy(data, 0, newData, 0, pos);
                data = newData;
            }
        }
    }

    public void read(InputStream stream) {
        try {
            int[] len = new int[1];
            byte[] raw = readFully(stream, len);
            Parcel in = Parcel.obtain();
            in.unmarshall(raw, 0, len[0]);
            in.setDataPosition(0);
            stream.close();

            readFromParcel(in);
        } catch (IOException e) {
            mReadError = "caught exception: " + e;
        }
    }

    public void readFromParcel(Parcel in) {
        final boolean hadData = mPackages.getMap().size() > 0
                || mProcesses.getMap().size() > 0;
        if (hadData) {
            resetSafely();
        }

        if (!readCheckedInt(in, MAGIC, "magic number")) {
            return;
        }
        int version = in.readInt();
        if (version != PARCEL_VERSION) {
            mReadError = "bad version: " + version;
            return;
        }
        if (!readCheckedInt(in, STATE_COUNT, "state count")) {
            return;
        }
        if (!readCheckedInt(in, ADJ_COUNT, "adj count")) {
            return;
        }
        if (!readCheckedInt(in, PSS_COUNT, "pss count")) {
            return;
        }
        if (!readCheckedInt(in, SYS_MEM_USAGE_COUNT, "sys mem usage count")) {
            return;
        }
        if (!readCheckedInt(in, SparseMappingTable.ARRAY_SIZE, "longs size")) {
            return;
        }

        mIndexToCommonString = new ArrayList<String>();

        mTimePeriodStartClock = in.readLong();
        buildTimePeriodStartClockStr();
        mTimePeriodStartRealtime = in.readLong();
        mTimePeriodEndRealtime = in.readLong();
        mTimePeriodStartUptime = in.readLong();
        mTimePeriodEndUptime = in.readLong();
        mInternalPssCount = in.readLong();
        mInternalPssTime = in.readLong();
        mExternalPssCount = in.readLong();
        mExternalPssTime = in.readLong();
        mExternalSlowPssCount = in.readLong();
        mExternalSlowPssTime = in.readLong();
        mRuntime = in.readString();
        mHasSwappedOutPss = in.readInt() != 0;
        mFlags = in.readInt();
        mTableData.readFromParcel(in);
        readCompactedLongArray(in, version, mMemFactorDurations, mMemFactorDurations.length);
        if (!mSysMemUsage.readFromParcel(in)) {
            return;
        }

        int NPROC = in.readInt();
        if (NPROC < 0) {
            mReadError = "bad process count: " + NPROC;
            return;
        }
        while (NPROC > 0) {
            NPROC--;
            final String procName = readCommonString(in, version);
            if (procName == null) {
                mReadError = "bad process name";
                return;
            }
            int NUID = in.readInt();
            if (NUID < 0) {
                mReadError = "bad uid count: " + NUID;
                return;
            }
            while (NUID > 0) {
                NUID--;
                final int uid = in.readInt();
                if (uid < 0) {
                    mReadError = "bad uid: " + uid;
                    return;
                }
                final String pkgName = readCommonString(in, version);
                if (pkgName == null) {
                    mReadError = "bad process package name";
                    return;
                }
                final long vers = in.readLong();
                ProcessState proc = hadData ? mProcesses.get(procName, uid) : null;
                if (proc != null) {
                    if (!proc.readFromParcel(in, false)) {
                        return;
                    }
                } else {
                    proc = new ProcessState(this, pkgName, uid, vers, procName);
                    if (!proc.readFromParcel(in, true)) {
                        return;
                    }
                }
                if (DEBUG_PARCEL) Slog.d(TAG, "Adding process: " + procName + " " + uid
                        + " " + proc);
                mProcesses.put(procName, uid, proc);
            }
        }

        if (DEBUG_PARCEL) Slog.d(TAG, "Read " + mProcesses.getMap().size() + " processes");

        int NPKG = in.readInt();
        if (NPKG < 0) {
            mReadError = "bad package count: " + NPKG;
            return;
        }
        while (NPKG > 0) {
            NPKG--;
            final String pkgName = readCommonString(in, version);
            if (pkgName == null) {
                mReadError = "bad package name";
                return;
            }
            int NUID = in.readInt();
            if (NUID < 0) {
                mReadError = "bad uid count: " + NUID;
                return;
            }
            while (NUID > 0) {
                NUID--;
                final int uid = in.readInt();
                if (uid < 0) {
                    mReadError = "bad uid: " + uid;
                    return;
                }
                int NVERS = in.readInt();
                if (NVERS < 0) {
                    mReadError = "bad versions count: " + NVERS;
                    return;
                }
                while (NVERS > 0) {
                    NVERS--;
                    final long vers = in.readLong();
                    PackageState pkgState = new PackageState(pkgName, uid);
                    LongSparseArray<PackageState> vpkg = mPackages.get(pkgName, uid);
                    if (vpkg == null) {
                        vpkg = new LongSparseArray<>();
                        mPackages.put(pkgName, uid, vpkg);
                    }
                    vpkg.put(vers, pkgState);
                    int NPROCS = in.readInt();
                    if (NPROCS < 0) {
                        mReadError = "bad package process count: " + NPROCS;
                        return;
                    }
                    while (NPROCS > 0) {
                        NPROCS--;
                        String procName = readCommonString(in, version);
                        if (procName == null) {
                            mReadError = "bad package process name";
                            return;
                        }
                        int hasProc = in.readInt();
                        if (DEBUG_PARCEL) Slog.d(TAG, "Reading package " + pkgName + " " + uid
                                + " process " + procName + " hasProc=" + hasProc);
                        ProcessState commonProc = mProcesses.get(procName, uid);
                        if (DEBUG_PARCEL) Slog.d(TAG, "Got common proc " + procName + " " + uid
                                + ": " + commonProc);
                        if (commonProc == null) {
                            mReadError = "no common proc: " + procName;
                            return;
                        }
                        if (hasProc != 0) {
                            // The process for this package is unique to the package; we
                            // need to load it.  We don't need to do anything about it if
                            // it is not unique because if someone later looks for it
                            // they will find and use it from the global procs.
                            ProcessState proc = hadData ? pkgState.mProcesses.get(procName) : null;
                            if (proc != null) {
                                if (!proc.readFromParcel(in, false)) {
                                    return;
                                }
                            } else {
                                proc = new ProcessState(commonProc, pkgName, uid, vers, procName,
                                        0);
                                if (!proc.readFromParcel(in, true)) {
                                    return;
                                }
                            }
                            if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " process: "
                                    + procName + " " + uid + " " + proc);
                            pkgState.mProcesses.put(procName, proc);
                        } else {
                            if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " process: "
                                    + procName + " " + uid + " " + commonProc);
                            pkgState.mProcesses.put(procName, commonProc);
                        }
                    }
                    int NSRVS = in.readInt();
                    if (NSRVS < 0) {
                        mReadError = "bad package service count: " + NSRVS;
                        return;
                    }
                    while (NSRVS > 0) {
                        NSRVS--;
                        String serviceName = in.readString();
                        if (serviceName == null) {
                            mReadError = "bad package service name";
                            return;
                        }
                        String processName = version > 9 ? readCommonString(in, version) : null;
                        ServiceState serv = hadData ? pkgState.mServices.get(serviceName) : null;
                        if (serv == null) {
                            serv = new ServiceState(this, pkgName, serviceName, processName, null);
                        }
                        if (!serv.readFromParcel(in)) {
                            return;
                        }
                        if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " service: "
                                + serviceName + " " + uid + " " + serv);
                        pkgState.mServices.put(serviceName, serv);
                    }
                }
            }
        }

        // Fragmentation info
        final int NPAGETYPES = in.readInt();
        mPageTypeZones.clear();
        mPageTypeZones.ensureCapacity(NPAGETYPES);
        mPageTypeLabels.clear();
        mPageTypeLabels.ensureCapacity(NPAGETYPES);
        mPageTypeSizes.clear();
        mPageTypeSizes.ensureCapacity(NPAGETYPES);
        for (int i=0; i<NPAGETYPES; i++) {
            mPageTypeZones.add(in.readInt());
            mPageTypeLabels.add(in.readString());
            mPageTypeSizes.add(in.createIntArray());
        }

        mIndexToCommonString = null;

        if (DEBUG_PARCEL) Slog.d(TAG, "Successfully read procstats!");
    }

    public PackageState getPackageStateLocked(String packageName, int uid, long vers) {
        LongSparseArray<PackageState> vpkg = mPackages.get(packageName, uid);
        if (vpkg == null) {
            vpkg = new LongSparseArray<PackageState>();
            mPackages.put(packageName, uid, vpkg);
        }
        PackageState as = vpkg.get(vers);
        if (as != null) {
            return as;
        }
        as = new PackageState(packageName, uid);
        vpkg.put(vers, as);
        return as;
    }

    public ProcessState getProcessStateLocked(String packageName, int uid, long vers,
            String processName) {
        final PackageState pkgState = getPackageStateLocked(packageName, uid, vers);
        ProcessState ps = pkgState.mProcesses.get(processName);
        if (ps != null) {
            return ps;
        }
        ProcessState commonProc = mProcesses.get(processName, uid);
        if (commonProc == null) {
            commonProc = new ProcessState(this, packageName, uid, vers, processName);
            mProcesses.put(processName, uid, commonProc);
            if (DEBUG) Slog.d(TAG, "GETPROC created new common " + commonProc);
        }
        if (!commonProc.isMultiPackage()) {
            if (packageName.equals(commonProc.getPackage()) && vers == commonProc.getVersion()) {
                // This common process is not in use by multiple packages, and
                // is for the calling package, so we can just use it directly.
                ps = commonProc;
                if (DEBUG) Slog.d(TAG, "GETPROC also using for pkg " + commonProc);
            } else {
                if (DEBUG) Slog.d(TAG, "GETPROC need to split common proc!");
                // This common process has not been in use by multiple packages,
                // but it was created for a different package than the caller.
                // We need to convert it to a multi-package process.
                commonProc.setMultiPackage(true);
                // To do this, we need to make two new process states, one a copy
                // of the current state for the process under the original package
                // name, and the second a free new process state for it as the
                // new package name.
                long now = SystemClock.uptimeMillis();
                // First let's make a copy of the current process state and put
                // that under the now unique state for its original package name.
                final PackageState commonPkgState = getPackageStateLocked(commonProc.getPackage(),
                        uid, commonProc.getVersion());
                if (commonPkgState != null) {
                    ProcessState cloned = commonProc.clone(now);
                    if (DEBUG) Slog.d(TAG, "GETPROC setting clone to pkg " + commonProc.getPackage()
                            + ": " + cloned);
                    commonPkgState.mProcesses.put(commonProc.getName(), cloned);
                    // If this has active services, we need to update their process pointer
                    // to point to the new package-specific process state.
                    for (int i=commonPkgState.mServices.size()-1; i>=0; i--) {
                        ServiceState ss = commonPkgState.mServices.valueAt(i);
                        if (ss.getProcess() == commonProc) {
                            if (DEBUG) Slog.d(TAG, "GETPROC switching service to cloned: " + ss);
                            ss.setProcess(cloned);
                        } else if (DEBUG) {
                            Slog.d(TAG, "GETPROC leaving proc of " + ss);
                        }
                    }
                } else {
                    Slog.w(TAG, "Cloning proc state: no package state " + commonProc.getPackage()
                            + "/" + uid + " for proc " + commonProc.getName());
                }
                // And now make a fresh new process state for the new package name.
                ps = new ProcessState(commonProc, packageName, uid, vers, processName, now);
                if (DEBUG) Slog.d(TAG, "GETPROC created new pkg " + ps);
            }
        } else {
            // The common process is for multiple packages, we need to create a
            // separate object for the per-package data.
            ps = new ProcessState(commonProc, packageName, uid, vers, processName,
                    SystemClock.uptimeMillis());
            if (DEBUG) Slog.d(TAG, "GETPROC created new pkg " + ps);
        }
        pkgState.mProcesses.put(processName, ps);
        if (DEBUG) Slog.d(TAG, "GETPROC adding new pkg " + ps);
        return ps;
    }

    public ServiceState getServiceStateLocked(String packageName, int uid, long vers,
            String processName, String className) {
        final ProcessStats.PackageState as = getPackageStateLocked(packageName, uid, vers);
        ServiceState ss = as.mServices.get(className);
        if (ss != null) {
            if (DEBUG) Slog.d(TAG, "GETSVC: returning existing " + ss);
            return ss;
        }
        final ProcessState ps = processName != null
                ? getProcessStateLocked(packageName, uid, vers, processName) : null;
        ss = new ServiceState(this, packageName, className, processName, ps);
        as.mServices.put(className, ss);
        if (DEBUG) Slog.d(TAG, "GETSVC: creating " + ss + " in " + ps);
        return ss;
    }

    public void dumpLocked(PrintWriter pw, String reqPackage, long now, boolean dumpSummary,
            boolean dumpAll, boolean activeOnly) {
        long totalTime = DumpUtils.dumpSingleTime(null, null, mMemFactorDurations, mMemFactor,
                mStartTime, now);
        boolean sepNeeded = false;
        if (mSysMemUsage.getKeyCount() > 0) {
            pw.println("System memory usage:");
            mSysMemUsage.dump(pw, "  ", ALL_SCREEN_ADJ, ALL_MEM_ADJ);
            sepNeeded = true;
        }
        ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = mPackages.getMap();
        boolean printedHeader = false;
        for (int ip=0; ip<pkgMap.size(); ip++) {
            final String pkgName = pkgMap.keyAt(ip);
            final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
            for (int iu=0; iu<uids.size(); iu++) {
                final int uid = uids.keyAt(iu);
                final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu);
                for (int iv=0; iv<vpkgs.size(); iv++) {
                    final long vers = vpkgs.keyAt(iv);
                    final PackageState pkgState = vpkgs.valueAt(iv);
                    final int NPROCS = pkgState.mProcesses.size();
                    final int NSRVS = pkgState.mServices.size();
                    final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName);
                    if (!pkgMatch) {
                        boolean procMatch = false;
                        for (int iproc=0; iproc<NPROCS; iproc++) {
                            ProcessState proc = pkgState.mProcesses.valueAt(iproc);
                            if (reqPackage.equals(proc.getName())) {
                                procMatch = true;
                                break;
                            }
                        }
                        if (!procMatch) {
                            continue;
                        }
                    }
                    if (NPROCS > 0 || NSRVS > 0) {
                        if (!printedHeader) {
                            if (sepNeeded) pw.println();
                            pw.println("Per-Package Stats:");
                            printedHeader = true;
                            sepNeeded = true;
                        }
                        pw.print("  * "); pw.print(pkgName); pw.print(" / ");
                                UserHandle.formatUid(pw, uid); pw.print(" / v");
                                pw.print(vers); pw.println(":");
                    }
                    if (!dumpSummary || dumpAll) {
                        for (int iproc=0; iproc<NPROCS; iproc++) {
                            ProcessState proc = pkgState.mProcesses.valueAt(iproc);
                            if (!pkgMatch && !reqPackage.equals(proc.getName())) {
                                continue;
                            }
                            if (activeOnly && !proc.isInUse()) {
                                pw.print("      (Not active: ");
                                        pw.print(pkgState.mProcesses.keyAt(iproc)); pw.println(")");
                                continue;
                            }
                            pw.print("      Process ");
                            pw.print(pkgState.mProcesses.keyAt(iproc));
                            if (proc.getCommonProcess().isMultiPackage()) {
                                pw.print(" (multi, ");
                            } else {
                                pw.print(" (unique, ");
                            }
                            pw.print(proc.getDurationsBucketCount());
                            pw.print(" entries)");
                            pw.println(":");
                            proc.dumpProcessState(pw, "        ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
                                    ALL_PROC_STATES, now);
                            proc.dumpPss(pw, "        ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
                                    ALL_PROC_STATES);
                            proc.dumpInternalLocked(pw, "        ", dumpAll);
                        }
                    } else {
                        ArrayList<ProcessState> procs = new ArrayList<ProcessState>();
                        for (int iproc=0; iproc<NPROCS; iproc++) {
                            ProcessState proc = pkgState.mProcesses.valueAt(iproc);
                            if (!pkgMatch && !reqPackage.equals(proc.getName())) {
                                continue;
                            }
                            if (activeOnly && !proc.isInUse()) {
                                continue;
                            }
                            procs.add(proc);
                        }
                        DumpUtils.dumpProcessSummaryLocked(pw, "      ", procs,
                                ALL_SCREEN_ADJ, ALL_MEM_ADJ, NON_CACHED_PROC_STATES,
                                now, totalTime);
                    }
                    for (int isvc=0; isvc<NSRVS; isvc++) {
                        ServiceState svc = pkgState.mServices.valueAt(isvc);
                        if (!pkgMatch && !reqPackage.equals(svc.getProcessName())) {
                            continue;
                        }
                        if (activeOnly && !svc.isInUse()) {
                            pw.print("      (Not active: ");
                                    pw.print(pkgState.mServices.keyAt(isvc)); pw.println(")");
                            continue;
                        }
                        if (dumpAll) {
                            pw.print("      Service ");
                        } else {
                            pw.print("      * ");
                        }
                        pw.print(pkgState.mServices.keyAt(isvc));
                        pw.println(":");
                        pw.print("        Process: "); pw.println(svc.getProcessName());
                        svc.dumpStats(pw, "        ", "          ", "    ",
                                now, totalTime, dumpSummary, dumpAll);
                    }
                }
            }
        }

        ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
        printedHeader = false;
        int numShownProcs = 0, numTotalProcs = 0;
        for (int ip=0; ip<procMap.size(); ip++) {
            String procName = procMap.keyAt(ip);
            SparseArray<ProcessState> uids = procMap.valueAt(ip);
            for (int iu=0; iu<uids.size(); iu++) {
                int uid = uids.keyAt(iu);
                numTotalProcs++;
                final ProcessState proc = uids.valueAt(iu);
                if (proc.hasAnyData()) {
                    continue;
                }
                if (!proc.isMultiPackage()) {
                    continue;
                }
                if (reqPackage != null && !reqPackage.equals(procName)
                        && !reqPackage.equals(proc.getPackage())) {
                    continue;
                }
                numShownProcs++;
                if (sepNeeded) {
                    pw.println();
                }
                sepNeeded = true;
                if (!printedHeader) {
                    pw.println("Multi-Package Common Processes:");
                    printedHeader = true;
                }
                if (activeOnly && !proc.isInUse()) {
                    pw.print("      (Not active: "); pw.print(procName); pw.println(")");
                    continue;
                }
                pw.print("  * "); pw.print(procName); pw.print(" / ");
                        UserHandle.formatUid(pw, uid);
                        pw.print(" ("); pw.print(proc.getDurationsBucketCount());
                        pw.print(" entries)"); pw.println(":");
                proc.dumpProcessState(pw, "        ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
                        ALL_PROC_STATES, now);
                proc.dumpPss(pw, "        ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, ALL_PROC_STATES);
                proc.dumpInternalLocked(pw, "        ", dumpAll);
            }
        }
        if (dumpAll) {
            pw.println();
            pw.print("  Total procs: "); pw.print(numShownProcs);
                    pw.print(" shown of "); pw.print(numTotalProcs); pw.println(" total");
        }

        if (sepNeeded) {
            pw.println();
        }
        if (dumpSummary) {
            pw.println("Summary:");
            dumpSummaryLocked(pw, reqPackage, now, activeOnly);
        } else {
            dumpTotalsLocked(pw, now);
        }

        if (dumpAll) {
            pw.println();
            pw.println("Internal state:");
            /*
            pw.print("  Num long arrays: "); pw.println(mLongs.size());
            pw.print("  Next long entry: "); pw.println(mNextLong);
            */
            pw.print("  mRunning="); pw.println(mRunning);
        }

        dumpFragmentationLocked(pw);
    }

    public void dumpSummaryLocked(PrintWriter pw, String reqPackage, long now, boolean activeOnly) {
        long totalTime = DumpUtils.dumpSingleTime(null, null, mMemFactorDurations, mMemFactor,
                mStartTime, now);
        dumpFilteredSummaryLocked(pw, null, "  ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
                ALL_PROC_STATES, NON_CACHED_PROC_STATES, now, totalTime, reqPackage, activeOnly);
        pw.println();
        dumpTotalsLocked(pw, now);
    }

    private void dumpFragmentationLocked(PrintWriter pw) {
        pw.println();
        pw.println("Available pages by page size:");
        final int NPAGETYPES = mPageTypeLabels.size();
        for (int i=0; i<NPAGETYPES; i++) {
            pw.format("Zone %3d  %14s ", mPageTypeZones.get(i), mPageTypeLabels.get(i));
            final int[] sizes = mPageTypeSizes.get(i);
            final int N = sizes == null ? 0 : sizes.length;
            for (int j=0; j<N; j++) {
                pw.format("%6d", sizes[j]);
            }
            pw.println();
        }
    }

    long printMemoryCategory(PrintWriter pw, String prefix, String label, double memWeight,
            long totalTime, long curTotalMem, int samples) {
        if (memWeight != 0) {
            long mem = (long)(memWeight * 1024 / totalTime);
            pw.print(prefix);
            pw.print(label);
            pw.print(": ");
            DebugUtils.printSizeValue(pw, mem);
            pw.print(" (");
            pw.print(samples);
            pw.print(" samples)");
            pw.println();
            return curTotalMem + mem;
        }
        return curTotalMem;
    }

    void dumpTotalsLocked(PrintWriter pw, long now) {
        pw.println("Run time Stats:");
        DumpUtils.dumpSingleTime(pw, "  ", mMemFactorDurations, mMemFactor, mStartTime, now);
        pw.println();
        pw.println("Memory usage:");
        TotalMemoryUseCollection totalMem = new TotalMemoryUseCollection(ALL_SCREEN_ADJ,
                ALL_MEM_ADJ);
        computeTotalMemoryUse(totalMem, now);
        long totalPss = 0;
        totalPss = printMemoryCategory(pw, "  ", "Kernel ", totalMem.sysMemKernelWeight,
                totalMem.totalTime, totalPss, totalMem.sysMemSamples);
        totalPss = printMemoryCategory(pw, "  ", "Native ", totalMem.sysMemNativeWeight,
                totalMem.totalTime, totalPss, totalMem.sysMemSamples);
        for (int i=0; i<STATE_COUNT; i++) {
            // Skip restarting service state -- that is not actually a running process.
            if (i != STATE_SERVICE_RESTARTING) {
                totalPss = printMemoryCategory(pw, "  ", DumpUtils.STATE_NAMES[i],
                        totalMem.processStateWeight[i], totalMem.totalTime, totalPss,
                        totalMem.processStateSamples[i]);
            }
        }
        totalPss = printMemoryCategory(pw, "  ", "Cached ", totalMem.sysMemCachedWeight,
                totalMem.totalTime, totalPss, totalMem.sysMemSamples);
        totalPss = printMemoryCategory(pw, "  ", "Free   ", totalMem.sysMemFreeWeight,
                totalMem.totalTime, totalPss, totalMem.sysMemSamples);
        totalPss = printMemoryCategory(pw, "  ", "Z-Ram  ", totalMem.sysMemZRamWeight,
                totalMem.totalTime, totalPss, totalMem.sysMemSamples);
        pw.print("  TOTAL  : ");
        DebugUtils.printSizeValue(pw, totalPss);
        pw.println();
        printMemoryCategory(pw, "  ", DumpUtils.STATE_NAMES[STATE_SERVICE_RESTARTING],
                totalMem.processStateWeight[STATE_SERVICE_RESTARTING], totalMem.totalTime, totalPss,
                totalMem.processStateSamples[STATE_SERVICE_RESTARTING]);
        pw.println();
        pw.println("PSS collection stats:");
        pw.print("  Internal: ");
        pw.print(mInternalPssCount);
        pw.print("x over ");
        TimeUtils.formatDuration(mInternalPssTime, pw);
        pw.println();
        pw.print("  External: ");
        pw.print(mExternalPssCount);
        pw.print("x over ");
        TimeUtils.formatDuration(mExternalPssTime, pw);
        pw.println();
        pw.print("  External Slow: ");
        pw.print(mExternalSlowPssCount);
        pw.print("x over ");
        TimeUtils.formatDuration(mExternalSlowPssTime, pw);
        pw.println();
        pw.println();
        pw.print("          Start time: ");
        pw.print(DateFormat.format("yyyy-MM-dd HH:mm:ss", mTimePeriodStartClock));
        pw.println();
        pw.print("        Total uptime: ");
        TimeUtils.formatDuration(
                (mRunning ? SystemClock.uptimeMillis() : mTimePeriodEndUptime)
                        - mTimePeriodStartUptime, pw);
        pw.println();
        pw.print("  Total elapsed time: ");
        TimeUtils.formatDuration(
                (mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime)
                        - mTimePeriodStartRealtime, pw);
        boolean partial = true;
        if ((mFlags&FLAG_SHUTDOWN) != 0) {
            pw.print(" (shutdown)");
            partial = false;
        }
        if ((mFlags&FLAG_SYSPROPS) != 0) {
            pw.print(" (sysprops)");
            partial = false;
        }
        if ((mFlags&FLAG_COMPLETE) != 0) {
            pw.print(" (complete)");
            partial = false;
        }
        if (partial) {
            pw.print(" (partial)");
        }
        if (mHasSwappedOutPss) {
            pw.print(" (swapped-out-pss)");
        }
        pw.print(' ');
        pw.print(mRuntime);
        pw.println();
    }

    void dumpFilteredSummaryLocked(PrintWriter pw, String header, String prefix,
            int[] screenStates, int[] memStates, int[] procStates,
            int[] sortProcStates, long now, long totalTime, String reqPackage, boolean activeOnly) {
        ArrayList<ProcessState> procs = collectProcessesLocked(screenStates, memStates,
                procStates, sortProcStates, now, reqPackage, activeOnly);
        if (procs.size() > 0) {
            if (header != null) {
                pw.println();
                pw.println(header);
            }
            DumpUtils.dumpProcessSummaryLocked(pw, prefix, procs, screenStates, memStates,
                    sortProcStates, now, totalTime);
        }
    }

    public ArrayList<ProcessState> collectProcessesLocked(int[] screenStates, int[] memStates,
            int[] procStates, int sortProcStates[], long now, String reqPackage,
            boolean activeOnly) {
        final ArraySet<ProcessState> foundProcs = new ArraySet<ProcessState>();
        final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap =
                mPackages.getMap();
        for (int ip=0; ip<pkgMap.size(); ip++) {
            final String pkgName = pkgMap.keyAt(ip);
            final SparseArray<LongSparseArray<PackageState>> procs = pkgMap.valueAt(ip);
            for (int iu=0; iu<procs.size(); iu++) {
                final LongSparseArray<PackageState> vpkgs = procs.valueAt(iu);
                final int NVERS = vpkgs.size();
                for (int iv=0; iv<NVERS; iv++) {
                    final PackageState state = vpkgs.valueAt(iv);
                    final int NPROCS = state.mProcesses.size();
                    final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName);
                    for (int iproc=0; iproc<NPROCS; iproc++) {
                        final ProcessState proc = state.mProcesses.valueAt(iproc);
                        if (!pkgMatch && !reqPackage.equals(proc.getName())) {
                            continue;
                        }
                        if (activeOnly && !proc.isInUse()) {
                            continue;
                        }
                        foundProcs.add(proc.getCommonProcess());
                    }
                }
            }
        }
        ArrayList<ProcessState> outProcs = new ArrayList<ProcessState>(foundProcs.size());
        for (int i=0; i<foundProcs.size(); i++) {
            ProcessState proc = foundProcs.valueAt(i);
            if (proc.computeProcessTimeLocked(screenStates, memStates, procStates, now) > 0) {
                outProcs.add(proc);
                if (procStates != sortProcStates) {
                    proc.computeProcessTimeLocked(screenStates, memStates, sortProcStates, now);
                }
            }
        }
        Collections.sort(outProcs, ProcessState.COMPARATOR);
        return outProcs;
    }

    public void dumpCheckinLocked(PrintWriter pw, String reqPackage) {
        final long now = SystemClock.uptimeMillis();
        final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap =
                mPackages.getMap();
        pw.println("vers,5");
        pw.print("period,"); pw.print(mTimePeriodStartClockStr);
        pw.print(","); pw.print(mTimePeriodStartRealtime); pw.print(",");
        pw.print(mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime);
        boolean partial = true;
        if ((mFlags&FLAG_SHUTDOWN) != 0) {
            pw.print(",shutdown");
            partial = false;
        }
        if ((mFlags&FLAG_SYSPROPS) != 0) {
            pw.print(",sysprops");
            partial = false;
        }
        if ((mFlags&FLAG_COMPLETE) != 0) {
            pw.print(",complete");
            partial = false;
        }
        if (partial) {
            pw.print(",partial");
        }
        if (mHasSwappedOutPss) {
            pw.print(",swapped-out-pss");
        }
        pw.println();
        pw.print("config,"); pw.println(mRuntime);
        for (int ip=0; ip<pkgMap.size(); ip++) {
            final String pkgName = pkgMap.keyAt(ip);
            if (reqPackage != null && !reqPackage.equals(pkgName)) {
                continue;
            }
            final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
            for (int iu=0; iu<uids.size(); iu++) {
                final int uid = uids.keyAt(iu);
                final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu);
                for (int iv=0; iv<vpkgs.size(); iv++) {
                    final long vers = vpkgs.keyAt(iv);
                    final PackageState pkgState = vpkgs.valueAt(iv);
                    final int NPROCS = pkgState.mProcesses.size();
                    final int NSRVS = pkgState.mServices.size();
                    for (int iproc=0; iproc<NPROCS; iproc++) {
                        ProcessState proc = pkgState.mProcesses.valueAt(iproc);
                        proc.dumpPackageProcCheckin(pw, pkgName, uid, vers,
                                pkgState.mProcesses.keyAt(iproc), now);
                    }
                    for (int isvc=0; isvc<NSRVS; isvc++) {
                        final String serviceName = DumpUtils.collapseString(pkgName,
                                pkgState.mServices.keyAt(isvc));
                        final ServiceState svc = pkgState.mServices.valueAt(isvc);
                        svc.dumpTimesCheckin(pw, pkgName, uid, vers, serviceName, now);
                    }
                }
            }
        }

        ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
        for (int ip=0; ip<procMap.size(); ip++) {
            String procName = procMap.keyAt(ip);
            SparseArray<ProcessState> uids = procMap.valueAt(ip);
            for (int iu=0; iu<uids.size(); iu++) {
                final int uid = uids.keyAt(iu);
                final ProcessState procState = uids.valueAt(iu);
                procState.dumpProcCheckin(pw, procName, uid, now);
            }
        }
        pw.print("total");
        DumpUtils.dumpAdjTimesCheckin(pw, ",", mMemFactorDurations, mMemFactor, mStartTime, now);
        pw.println();
        final int sysMemUsageCount = mSysMemUsage.getKeyCount();
        if (sysMemUsageCount > 0) {
            pw.print("sysmemusage");
            for (int i=0; i<sysMemUsageCount; i++) {
                final int key = mSysMemUsage.getKeyAt(i);
                final int type = SparseMappingTable.getIdFromKey(key);
                pw.print(",");
                DumpUtils.printProcStateTag(pw, type);
                for (int j=SYS_MEM_USAGE_SAMPLE_COUNT; j<SYS_MEM_USAGE_COUNT; j++) {
                    if (j > SYS_MEM_USAGE_CACHED_MINIMUM) {
                        pw.print(":");
                    }
                    pw.print(mSysMemUsage.getValue(key, j));
                }
            }
        }
        pw.println();
        TotalMemoryUseCollection totalMem = new TotalMemoryUseCollection(ALL_SCREEN_ADJ,
                ALL_MEM_ADJ);
        computeTotalMemoryUse(totalMem, now);
        pw.print("weights,");
        pw.print(totalMem.totalTime);
        pw.print(",");
        pw.print(totalMem.sysMemCachedWeight);
        pw.print(":");
        pw.print(totalMem.sysMemSamples);
        pw.print(",");
        pw.print(totalMem.sysMemFreeWeight);
        pw.print(":");
        pw.print(totalMem.sysMemSamples);
        pw.print(",");
        pw.print(totalMem.sysMemZRamWeight);
        pw.print(":");
        pw.print(totalMem.sysMemSamples);
        pw.print(",");
        pw.print(totalMem.sysMemKernelWeight);
        pw.print(":");
        pw.print(totalMem.sysMemSamples);
        pw.print(",");
        pw.print(totalMem.sysMemNativeWeight);
        pw.print(":");
        pw.print(totalMem.sysMemSamples);
        for (int i=0; i<STATE_COUNT; i++) {
            pw.print(",");
            pw.print(totalMem.processStateWeight[i]);
            pw.print(":");
            pw.print(totalMem.processStateSamples[i]);
        }
        pw.println();

        final int NPAGETYPES = mPageTypeLabels.size();
        for (int i=0; i<NPAGETYPES; i++) {
            pw.print("availablepages,");
            pw.print(mPageTypeLabels.get(i));
            pw.print(",");
            pw.print(mPageTypeZones.get(i));
            pw.print(",");
            final int[] sizes = mPageTypeSizes.get(i);
            final int N = sizes == null ? 0 : sizes.length;
            for (int j=0; j<N; j++) {
                if (j != 0) {
                    pw.print(",");
                }
                pw.print(sizes[j]);
            }
            pw.println();
        }
    }

    public void toProto(ProtoOutputStream proto, long now) {
        final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap =
                mPackages.getMap();

        proto.write(ProcessStatsSectionProto.START_REALTIME_MS, mTimePeriodStartRealtime);
        proto.write(ProcessStatsSectionProto.END_REALTIME_MS,
                mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime);
        proto.write(ProcessStatsSectionProto.START_UPTIME_MS, mTimePeriodStartUptime);
        proto.write(ProcessStatsSectionProto.END_UPTIME_MS, mTimePeriodEndUptime);
        proto.write(ProcessStatsSectionProto.RUNTIME, mRuntime);
        proto.write(ProcessStatsSectionProto.HAS_SWAPPED_PSS, mHasSwappedOutPss);
        boolean partial = true;
        if ((mFlags&FLAG_SHUTDOWN) != 0) {
            proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SHUTDOWN);
            partial = false;
        }
        if ((mFlags&FLAG_SYSPROPS) != 0) {
            proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SYSPROPS);
            partial = false;
        }
        if ((mFlags&FLAG_COMPLETE) != 0) {
            proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_COMPLETE);
            partial = false;
        }
        if (partial) {
            proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_PARTIAL);
        }

        ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
        for (int ip=0; ip<procMap.size(); ip++) {
            String procName = procMap.keyAt(ip);
            SparseArray<ProcessState> uids = procMap.valueAt(ip);
            for (int iu=0; iu<uids.size(); iu++) {
                final int uid = uids.keyAt(iu);
                final ProcessState procState = uids.valueAt(iu);
                final long processStateToken = proto.start(ProcessStatsSectionProto.PROCESS_STATS);
                procState.toProto(proto, procName, uid, now);
                proto.end(processStateToken);
            }
        }
    }

    final public static class ProcessStateHolder {
        public final long appVersion;
        public ProcessState state;

        public ProcessStateHolder(long _appVersion) {
            appVersion = _appVersion;
        }
    }

    public static final class PackageState {
        public final ArrayMap<String, ProcessState> mProcesses
                = new ArrayMap<String, ProcessState>();
        public final ArrayMap<String, ServiceState> mServices
                = new ArrayMap<String, ServiceState>();
        public final String mPackageName;
        public final int mUid;

        public PackageState(String packageName, int uid) {
            mUid = uid;
            mPackageName = packageName;
        }
    }

    public static final class ProcessDataCollection {
        final int[] screenStates;
        final int[] memStates;
        final int[] procStates;

        public long totalTime;
        public long numPss;
        public long minPss;
        public long avgPss;
        public long maxPss;
        public long minUss;
        public long avgUss;
        public long maxUss;

        public ProcessDataCollection(int[] _screenStates, int[] _memStates, int[] _procStates) {
            screenStates = _screenStates;
            memStates = _memStates;
            procStates = _procStates;
        }

        void print(PrintWriter pw, long overallTime, boolean full) {
            if (totalTime > overallTime) {
                pw.print("*");
            }
            DumpUtils.printPercent(pw, (double) totalTime / (double) overallTime);
            if (numPss > 0) {
                pw.print(" (");
                DebugUtils.printSizeValue(pw, minPss * 1024);
                pw.print("-");
                DebugUtils.printSizeValue(pw, avgPss * 1024);
                pw.print("-");
                DebugUtils.printSizeValue(pw, maxPss * 1024);
                pw.print("/");
                DebugUtils.printSizeValue(pw, minUss * 1024);
                pw.print("-");
                DebugUtils.printSizeValue(pw, avgUss * 1024);
                pw.print("-");
                DebugUtils.printSizeValue(pw, maxUss * 1024);
                if (full) {
                    pw.print(" over ");
                    pw.print(numPss);
                }
                pw.print(")");
            }
        }
    }

    public static class TotalMemoryUseCollection {
        final int[] screenStates;
        final int[] memStates;

        public TotalMemoryUseCollection(int[] _screenStates, int[] _memStates) {
            screenStates = _screenStates;
            memStates = _memStates;
        }

        public long totalTime;
        public long[] processStatePss = new long[STATE_COUNT];
        public double[] processStateWeight = new double[STATE_COUNT];
        public long[] processStateTime = new long[STATE_COUNT];
        public int[] processStateSamples = new int[STATE_COUNT];
        public long[] sysMemUsage = new long[SYS_MEM_USAGE_COUNT];
        public double sysMemCachedWeight;
        public double sysMemFreeWeight;
        public double sysMemZRamWeight;
        public double sysMemKernelWeight;
        public double sysMemNativeWeight;
        public int sysMemSamples;
        public boolean hasSwappedOutPss;
    }

}
