/*
 * 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.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.text.format.DateFormat;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DebugUtils;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;

import com.android.internal.app.procstats.ProcessStats;
import com.android.internal.app.procstats.ProcessStats.PackageState;
import com.android.internal.app.procstats.ProcessStats.ProcessStateHolder;
import com.android.internal.app.procstats.ProcessStats.TotalMemoryUseCollection;
import static com.android.internal.app.procstats.ProcessStats.PSS_SAMPLE_COUNT;
import static com.android.internal.app.procstats.ProcessStats.PSS_MINIMUM;
import static com.android.internal.app.procstats.ProcessStats.PSS_AVERAGE;
import static com.android.internal.app.procstats.ProcessStats.PSS_MAXIMUM;
import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MINIMUM;
import static com.android.internal.app.procstats.ProcessStats.PSS_USS_AVERAGE;
import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MAXIMUM;
import static com.android.internal.app.procstats.ProcessStats.PSS_COUNT;
import static com.android.internal.app.procstats.ProcessStats.STATE_NOTHING;
import static com.android.internal.app.procstats.ProcessStats.STATE_PERSISTENT;
import static com.android.internal.app.procstats.ProcessStats.STATE_TOP;
import static com.android.internal.app.procstats.ProcessStats.STATE_IMPORTANT_FOREGROUND;
import static com.android.internal.app.procstats.ProcessStats.STATE_IMPORTANT_BACKGROUND;
import static com.android.internal.app.procstats.ProcessStats.STATE_BACKUP;
import static com.android.internal.app.procstats.ProcessStats.STATE_HEAVY_WEIGHT;
import static com.android.internal.app.procstats.ProcessStats.STATE_SERVICE;
import static com.android.internal.app.procstats.ProcessStats.STATE_SERVICE_RESTARTING;
import static com.android.internal.app.procstats.ProcessStats.STATE_RECEIVER;
import static com.android.internal.app.procstats.ProcessStats.STATE_HOME;
import static com.android.internal.app.procstats.ProcessStats.STATE_LAST_ACTIVITY;
import static com.android.internal.app.procstats.ProcessStats.STATE_CACHED_ACTIVITY;
import static com.android.internal.app.procstats.ProcessStats.STATE_CACHED_ACTIVITY_CLIENT;
import static com.android.internal.app.procstats.ProcessStats.STATE_CACHED_EMPTY;
import static com.android.internal.app.procstats.ProcessStats.STATE_COUNT;

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

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;

public final class ProcessState {
    private static final String TAG = "ProcessStats";
    private static final boolean DEBUG = false;
    private static final boolean DEBUG_PARCEL = false;

    // Map from process states to the states we track.
    private static final int[] PROCESS_STATE_TO_STATE = new int[] {
        STATE_PERSISTENT,               // ActivityManager.PROCESS_STATE_PERSISTENT
        STATE_PERSISTENT,               // ActivityManager.PROCESS_STATE_PERSISTENT_UI
        STATE_TOP,                      // ActivityManager.PROCESS_STATE_TOP
        STATE_IMPORTANT_FOREGROUND,     // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
        STATE_IMPORTANT_FOREGROUND,     // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
        STATE_TOP,                      // ActivityManager.PROCESS_STATE_TOP_SLEEPING
        STATE_IMPORTANT_FOREGROUND,     // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
        STATE_IMPORTANT_BACKGROUND,     // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
        STATE_BACKUP,                   // ActivityManager.PROCESS_STATE_BACKUP
        STATE_HEAVY_WEIGHT,             // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
        STATE_SERVICE,                  // ActivityManager.PROCESS_STATE_SERVICE
        STATE_RECEIVER,                 // ActivityManager.PROCESS_STATE_RECEIVER
        STATE_HOME,                     // ActivityManager.PROCESS_STATE_HOME
        STATE_LAST_ACTIVITY,            // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
        STATE_CACHED_ACTIVITY,          // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
        STATE_CACHED_ACTIVITY_CLIENT,   // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
        STATE_CACHED_EMPTY,             // ActivityManager.PROCESS_STATE_CACHED_EMPTY
    };

    public static final Comparator<ProcessState> COMPARATOR = new Comparator<ProcessState>() {
            @Override
            public int compare(ProcessState lhs, ProcessState rhs) {
                if (lhs.mTmpTotalTime < rhs.mTmpTotalTime) {
                    return -1;
                } else if (lhs.mTmpTotalTime > rhs.mTmpTotalTime) {
                    return 1;
                }
                return 0;
            }
        };

    static class PssAggr {
        long pss = 0;
        long samples = 0;

        void add(long newPss, long newSamples) {
            pss = (long)( (pss*(double)samples) + (newPss*(double)newSamples) )
                    / (samples+newSamples);
            samples += newSamples;
        }
    }

    // Used by reset to count rather than storing extra maps. Be careful.
    public int tmpNumInUse;
    public ProcessState tmpFoundSubProc;

    private final ProcessStats mStats;
    private final String mName;
    private final String mPackage;
    private final int mUid;
    private final int mVersion;
    private final DurationsTable mDurations;
    private final PssTable mPssTable;

    private ProcessState mCommonProcess;
    private int mCurState = STATE_NOTHING;
    private long mStartTime;

    private int mLastPssState = STATE_NOTHING;
    private long mLastPssTime;

    private boolean mActive;
    private int mNumActiveServices;
    private int mNumStartedServices;

    private int mNumExcessiveWake;
    private int mNumExcessiveCpu;

    private int mNumCachedKill;
    private long mMinCachedKillPss;
    private long mAvgCachedKillPss;
    private long mMaxCachedKillPss;

    private boolean mMultiPackage;
    private boolean mDead;

    // Set in computeProcessTimeLocked and used by COMPARATOR to sort. Be careful.
    private long mTmpTotalTime;

    /**
     * Create a new top-level process state, for the initial case where there is only
     * a single package running in a process.  The initial state is not running.
     */
    public ProcessState(ProcessStats processStats, String pkg, int uid, int vers, String name) {
        mStats = processStats;
        mName = name;
        mCommonProcess = this;
        mPackage = pkg;
        mUid = uid;
        mVersion = vers;
        mDurations = new DurationsTable(processStats.mTableData);
        mPssTable = new PssTable(processStats.mTableData);
    }

    /**
     * Create a new per-package process state for an existing top-level process
     * state.  The current running state of the top-level process is also copied,
     * marked as started running at 'now'.
     */
    public ProcessState(ProcessState commonProcess, String pkg, int uid, int vers, String name,
            long now) {
        mStats = commonProcess.mStats;
        mName = name;
        mCommonProcess = commonProcess;
        mPackage = pkg;
        mUid = uid;
        mVersion = vers;
        mCurState = commonProcess.mCurState;
        mStartTime = now;
        mDurations = new DurationsTable(commonProcess.mStats.mTableData);
        mPssTable = new PssTable(commonProcess.mStats.mTableData);
    }

    public ProcessState clone(long now) {
        ProcessState pnew = new ProcessState(this, mPackage, mUid, mVersion, mName, now);
        pnew.mDurations.addDurations(mDurations);
        pnew.mPssTable.copyFrom(mPssTable, PSS_COUNT);
        pnew.mNumExcessiveWake = mNumExcessiveWake;
        pnew.mNumExcessiveCpu = mNumExcessiveCpu;
        pnew.mNumCachedKill = mNumCachedKill;
        pnew.mMinCachedKillPss = mMinCachedKillPss;
        pnew.mAvgCachedKillPss = mAvgCachedKillPss;
        pnew.mMaxCachedKillPss = mMaxCachedKillPss;
        pnew.mActive = mActive;
        pnew.mNumActiveServices = mNumActiveServices;
        pnew.mNumStartedServices = mNumStartedServices;
        return pnew;
    }

    public String getName() {
        return mName;
    }

    public ProcessState getCommonProcess() {
        return mCommonProcess;
    }

    /**
     * Say that we are not part of a shared process, so mCommonProcess = this.
     */
    public void makeStandalone() {
        mCommonProcess = this;
    }

    public String getPackage() {
        return mPackage;
    }

    public int getUid() {
        return mUid;
    }

    public int getVersion() {
        return mVersion;
    }

    public boolean isMultiPackage() {
        return mMultiPackage;
    }

    public void setMultiPackage(boolean val) {
        mMultiPackage = val;
    }
    
    public int getDurationsBucketCount() {
        return mDurations.getKeyCount();
    }

    public void add(ProcessState other) {
        mDurations.addDurations(other.mDurations);
        mPssTable.mergeStats(other.mPssTable);
        mNumExcessiveWake += other.mNumExcessiveWake;
        mNumExcessiveCpu += other.mNumExcessiveCpu;
        if (other.mNumCachedKill > 0) {
            addCachedKill(other.mNumCachedKill, other.mMinCachedKillPss,
                    other.mAvgCachedKillPss, other.mMaxCachedKillPss);
        }
    }

    public void resetSafely(long now) {
        mDurations.resetTable();
        mPssTable.resetTable();
        mStartTime = now;
        mLastPssState = STATE_NOTHING;
        mLastPssTime = 0;
        mNumExcessiveWake = 0;
        mNumExcessiveCpu = 0;
        mNumCachedKill = 0;
        mMinCachedKillPss = mAvgCachedKillPss = mMaxCachedKillPss = 0;
    }

    public void makeDead() {
        mDead = true;
    }

    private void ensureNotDead() {
        if (!mDead) {
            return;
        }
        Slog.w(TAG, "ProcessState dead: name=" + mName
                + " pkg=" + mPackage + " uid=" + mUid + " common.name=" + mCommonProcess.mName);
    }

    public void writeToParcel(Parcel out, long now) {
        out.writeInt(mMultiPackage ? 1 : 0);
        mDurations.writeToParcel(out);
        mPssTable.writeToParcel(out);
        out.writeInt(mNumExcessiveWake);
        out.writeInt(mNumExcessiveCpu);
        out.writeInt(mNumCachedKill);
        if (mNumCachedKill > 0) {
            out.writeLong(mMinCachedKillPss);
            out.writeLong(mAvgCachedKillPss);
            out.writeLong(mMaxCachedKillPss);
        }
    }

    public boolean readFromParcel(Parcel in, boolean fully) {
        boolean multiPackage = in.readInt() != 0;
        if (fully) {
            mMultiPackage = multiPackage;
        }
        if (DEBUG_PARCEL) Slog.d(TAG, "Reading durations table...");
        if (!mDurations.readFromParcel(in)) {
            return false;
        }
        if (DEBUG_PARCEL) Slog.d(TAG, "Reading pss table...");
        if (!mPssTable.readFromParcel(in)) {
            return false;
        }
        mNumExcessiveWake = in.readInt();
        mNumExcessiveCpu = in.readInt();
        mNumCachedKill = in.readInt();
        if (mNumCachedKill > 0) {
            mMinCachedKillPss = in.readLong();
            mAvgCachedKillPss = in.readLong();
            mMaxCachedKillPss = in.readLong();
        } else {
            mMinCachedKillPss = mAvgCachedKillPss = mMaxCachedKillPss = 0;
        }
        return true;
    }

    public void makeActive() {
        ensureNotDead();
        mActive = true;
    }

    public void makeInactive() {
        mActive = false;
    }

    public boolean isInUse() {
        return mActive || mNumActiveServices > 0 || mNumStartedServices > 0
                || mCurState != STATE_NOTHING;
    }

    public boolean isActive() {
        return mActive;
    }

    public boolean hasAnyData() {
        return !(mDurations.getKeyCount() == 0
                && mCurState == STATE_NOTHING
                && mPssTable.getKeyCount() == 0);
    }

    /**
     * Update the current state of the given list of processes.
     *
     * @param state Current ActivityManager.PROCESS_STATE_*
     * @param memFactor Current mem factor constant.
     * @param now Current time.
     * @param pkgList Processes to update.
     */
    public void setState(int state, int memFactor, long now,
            ArrayMap<String, ProcessStateHolder> pkgList) {
        if (state < 0) {
            state = mNumStartedServices > 0
                    ? (STATE_SERVICE_RESTARTING+(memFactor*STATE_COUNT)) : STATE_NOTHING;
        } else {
            state = PROCESS_STATE_TO_STATE[state] + (memFactor*STATE_COUNT);
        }

        // First update the common process.
        mCommonProcess.setState(state, now);

        // If the common process is not multi-package, there is nothing else to do.
        if (!mCommonProcess.mMultiPackage) {
            return;
        }

        if (pkgList != null) {
            for (int ip=pkgList.size()-1; ip>=0; ip--) {
                pullFixedProc(pkgList, ip).setState(state, now);
            }
        }
    }

    public void setState(int state, long now) {
        ensureNotDead();
        if (mCurState != state) {
            //Slog.i(TAG, "Setting state in " + mName + "/" + mPackage + ": " + state);
            commitStateTime(now);
            mCurState = state;
        }
    }

    public void commitStateTime(long now) {
        if (mCurState != STATE_NOTHING) {
            long dur = now - mStartTime;
            if (dur > 0) {
                mDurations.addDuration(mCurState, dur);
            }
        }
        mStartTime = now;
    }

    public void incActiveServices(String serviceName) {
        if (DEBUG && "".equals(mName)) {
            RuntimeException here = new RuntimeException("here");
            here.fillInStackTrace();
            Slog.d(TAG, "incActiveServices: " + this + " service=" + serviceName
                    + " to " + (mNumActiveServices+1), here);
        }
        if (mCommonProcess != this) {
            mCommonProcess.incActiveServices(serviceName);
        }
        mNumActiveServices++;
    }

    public void decActiveServices(String serviceName) {
        if (DEBUG && "".equals(mName)) {
            RuntimeException here = new RuntimeException("here");
            here.fillInStackTrace();
            Slog.d(TAG, "decActiveServices: " + this + " service=" + serviceName
                    + " to " + (mNumActiveServices-1), here);
        }
        if (mCommonProcess != this) {
            mCommonProcess.decActiveServices(serviceName);
        }
        mNumActiveServices--;
        if (mNumActiveServices < 0) {
            Slog.wtfStack(TAG, "Proc active services underrun: pkg=" + mPackage
                    + " uid=" + mUid + " proc=" + mName + " service=" + serviceName);
            mNumActiveServices = 0;
        }
    }

    public void incStartedServices(int memFactor, long now, String serviceName) {
        if (false) {
            RuntimeException here = new RuntimeException("here");
            here.fillInStackTrace();
            Slog.d(TAG, "incStartedServices: " + this + " service=" + serviceName
                    + " to " + (mNumStartedServices+1), here);
        }
        if (mCommonProcess != this) {
            mCommonProcess.incStartedServices(memFactor, now, serviceName);
        }
        mNumStartedServices++;
        if (mNumStartedServices == 1 && mCurState == STATE_NOTHING) {
            setState(STATE_SERVICE_RESTARTING + (memFactor*STATE_COUNT), now);
        }
    }

    public void decStartedServices(int memFactor, long now, String serviceName) {
        if (false) {
            RuntimeException here = new RuntimeException("here");
            here.fillInStackTrace();
            Slog.d(TAG, "decActiveServices: " + this + " service=" + serviceName
                    + " to " + (mNumStartedServices-1), here);
        }
        if (mCommonProcess != this) {
            mCommonProcess.decStartedServices(memFactor, now, serviceName);
        }
        mNumStartedServices--;
        if (mNumStartedServices == 0 && (mCurState%STATE_COUNT) == STATE_SERVICE_RESTARTING) {
            setState(STATE_NOTHING, now);
        } else if (mNumStartedServices < 0) {
            Slog.wtfStack(TAG, "Proc started services underrun: pkg="
                    + mPackage + " uid=" + mUid + " name=" + mName);
            mNumStartedServices = 0;
        }
    }

    public void addPss(long pss, long uss, boolean always,
            ArrayMap<String, ProcessStateHolder> pkgList) {
        ensureNotDead();
        if (!always) {
            if (mLastPssState == mCurState && SystemClock.uptimeMillis()
                    < (mLastPssTime+(30*1000))) {
                return;
            }
        }
        mLastPssState = mCurState;
        mLastPssTime = SystemClock.uptimeMillis();
        if (mCurState != STATE_NOTHING) {
            // First update the common process.
            mCommonProcess.mPssTable.mergeStats(mCurState, 1, pss, pss, pss, uss, uss, uss);

            // If the common process is not multi-package, there is nothing else to do.
            if (!mCommonProcess.mMultiPackage) {
                return;
            }

            if (pkgList != null) {
                for (int ip=pkgList.size()-1; ip>=0; ip--) {
                    pullFixedProc(pkgList, ip).mPssTable.mergeStats(mCurState, 1,
                            pss, pss, pss, uss, uss, uss);
                }
            }
        }
    }

    public void reportExcessiveWake(ArrayMap<String, ProcessStateHolder> pkgList) {
        ensureNotDead();
        mCommonProcess.mNumExcessiveWake++;
        if (!mCommonProcess.mMultiPackage) {
            return;
        }

        for (int ip=pkgList.size()-1; ip>=0; ip--) {
            pullFixedProc(pkgList, ip).mNumExcessiveWake++;
        }
    }

    public void reportExcessiveCpu(ArrayMap<String, ProcessStateHolder> pkgList) {
        ensureNotDead();
        mCommonProcess.mNumExcessiveCpu++;
        if (!mCommonProcess.mMultiPackage) {
            return;
        }

        for (int ip=pkgList.size()-1; ip>=0; ip--) {
            pullFixedProc(pkgList, ip).mNumExcessiveCpu++;
        }
    }

    private void addCachedKill(int num, long minPss, long avgPss, long maxPss) {
        if (mNumCachedKill <= 0) {
            mNumCachedKill = num;
            mMinCachedKillPss = minPss;
            mAvgCachedKillPss = avgPss;
            mMaxCachedKillPss = maxPss;
        } else {
            if (minPss < mMinCachedKillPss) {
                mMinCachedKillPss = minPss;
            }
            if (maxPss > mMaxCachedKillPss) {
                mMaxCachedKillPss = maxPss;
            }
            mAvgCachedKillPss = (long)( ((mAvgCachedKillPss*(double)mNumCachedKill) + avgPss)
                    / (mNumCachedKill+num) );
            mNumCachedKill += num;
        }
    }

    public void reportCachedKill(ArrayMap<String, ProcessStateHolder> pkgList, long pss) {
        ensureNotDead();
        mCommonProcess.addCachedKill(1, pss, pss, pss);
        if (!mCommonProcess.mMultiPackage) {
            return;
        }

        for (int ip=pkgList.size()-1; ip>=0; ip--) {
            pullFixedProc(pkgList, ip).addCachedKill(1, pss, pss, pss);
        }
    }

    public ProcessState pullFixedProc(String pkgName) {
        if (mMultiPackage) {
            // The array map is still pointing to a common process state
            // that is now shared across packages.  Update it to point to
            // the new per-package state.
            SparseArray<PackageState> vpkg = mStats.mPackages.get(pkgName, mUid);
            if (vpkg == null) {
                throw new IllegalStateException("Didn't find package " + pkgName
                        + " / " + mUid);
            }
            PackageState pkg = vpkg.get(mVersion);
            if (pkg == null) {
                throw new IllegalStateException("Didn't find package " + pkgName
                        + " / " + mUid + " vers " + mVersion);
            }
            ProcessState proc = pkg.mProcesses.get(mName);
            if (proc == null) {
                throw new IllegalStateException("Didn't create per-package process "
                        + mName + " in pkg " + pkgName + " / " + mUid + " vers " + mVersion);
            }
            return proc;
        }
        return this;
    }

    private ProcessState pullFixedProc(ArrayMap<String, ProcessStateHolder> pkgList,
            int index) {
        ProcessStateHolder holder = pkgList.valueAt(index);
        ProcessState proc = holder.state;
        if (mDead && proc.mCommonProcess != proc) {
            // Somehow we are contining to use a process state that is dead, because
            // it was not being told it was active during the last commit.  We can recover
            // from this by generating a fresh new state, but this is bad because we
            // are losing whatever data we had in the old process state.
            Log.wtf(TAG, "Pulling dead proc: name=" + mName + " pkg=" + mPackage
                    + " uid=" + mUid + " common.name=" + mCommonProcess.mName);
            proc = mStats.getProcessStateLocked(proc.mPackage, proc.mUid, proc.mVersion,
                    proc.mName);
        }
        if (proc.mMultiPackage) {
            // The array map is still pointing to a common process state
            // that is now shared across packages.  Update it to point to
            // the new per-package state.
            SparseArray<PackageState> vpkg = mStats.mPackages.get(pkgList.keyAt(index),
                    proc.mUid);
            if (vpkg == null) {
                throw new IllegalStateException("No existing package "
                        + pkgList.keyAt(index) + "/" + proc.mUid
                        + " for multi-proc " + proc.mName);
            }
            PackageState pkg = vpkg.get(proc.mVersion);
            if (pkg == null) {
                throw new IllegalStateException("No existing package "
                        + pkgList.keyAt(index) + "/" + proc.mUid
                        + " for multi-proc " + proc.mName + " version " + proc.mVersion);
            }
            String savedName = proc.mName;
            proc = pkg.mProcesses.get(proc.mName);
            if (proc == null) {
                throw new IllegalStateException("Didn't create per-package process "
                        + savedName + " in pkg " + pkg.mPackageName + "/" + pkg.mUid);
            }
            holder.state = proc;
        }
        return proc;
    }

    public long getDuration(int state, long now) {
        long time = mDurations.getValueForId((byte)state);
        if (mCurState == state) {
            time += now - mStartTime;
        }
        return time;
    }

    public long getPssSampleCount(int state) {
        return mPssTable.getValueForId((byte)state, PSS_SAMPLE_COUNT);
    }

    public long getPssMinimum(int state) {
        return mPssTable.getValueForId((byte)state, PSS_MINIMUM);
    }

    public long getPssAverage(int state) {
        return mPssTable.getValueForId((byte)state, PSS_AVERAGE);
    }

    public long getPssMaximum(int state) {
        return mPssTable.getValueForId((byte)state, PSS_MAXIMUM);
    }

    public long getPssUssMinimum(int state) {
        return mPssTable.getValueForId((byte)state, PSS_USS_MINIMUM);
    }

    public long getPssUssAverage(int state) {
        return mPssTable.getValueForId((byte)state, PSS_USS_AVERAGE);
    }

    public long getPssUssMaximum(int state) {
        return mPssTable.getValueForId((byte)state, PSS_USS_MAXIMUM);
    }

    /**
     * Sums up the PSS data and adds it to 'data'.
     * 
     * @param data The aggregate data is added here.
     * @param now SystemClock.uptimeMillis()
     */
    public void aggregatePss(TotalMemoryUseCollection data, long now) {
        final PssAggr fgPss = new PssAggr();
        final PssAggr bgPss = new PssAggr();
        final PssAggr cachedPss = new PssAggr();
        boolean havePss = false;
        for (int i=0; i<mDurations.getKeyCount(); i++) {
            final int key = mDurations.getKeyAt(i);
            int type = SparseMappingTable.getIdFromKey(key);
            int procState = type % STATE_COUNT;
            long samples = getPssSampleCount(type);
            if (samples > 0) {
                long avg = getPssAverage(type);
                havePss = true;
                if (procState <= STATE_IMPORTANT_FOREGROUND) {
                    fgPss.add(avg, samples);
                } else if (procState <= STATE_RECEIVER) {
                    bgPss.add(avg, samples);
                } else {
                    cachedPss.add(avg, samples);
                }
            }
        }
        if (!havePss) {
            return;
        }
        boolean fgHasBg = false;
        boolean fgHasCached = false;
        boolean bgHasCached = false;
        if (fgPss.samples < 3 && bgPss.samples > 0) {
            fgHasBg = true;
            fgPss.add(bgPss.pss, bgPss.samples);
        }
        if (fgPss.samples < 3 && cachedPss.samples > 0) {
            fgHasCached = true;
            fgPss.add(cachedPss.pss, cachedPss.samples);
        }
        if (bgPss.samples < 3 && cachedPss.samples > 0) {
            bgHasCached = true;
            bgPss.add(cachedPss.pss, cachedPss.samples);
        }
        if (bgPss.samples < 3 && !fgHasBg && fgPss.samples > 0) {
            bgPss.add(fgPss.pss, fgPss.samples);
        }
        if (cachedPss.samples < 3 && !bgHasCached && bgPss.samples > 0) {
            cachedPss.add(bgPss.pss, bgPss.samples);
        }
        if (cachedPss.samples < 3 && !fgHasCached && fgPss.samples > 0) {
            cachedPss.add(fgPss.pss, fgPss.samples);
        }
        for (int i=0; i<mDurations.getKeyCount(); i++) {
            final int key = mDurations.getKeyAt(i);
            final int type = SparseMappingTable.getIdFromKey(key);
            long time = mDurations.getValue(key);
            if (mCurState == type) {
                time += now - mStartTime;
            }
            final int procState = type % STATE_COUNT;
            data.processStateTime[procState] += time;
            long samples = getPssSampleCount(type);
            long avg;
            if (samples > 0) {
                avg = getPssAverage(type);
            } else if (procState <= STATE_IMPORTANT_FOREGROUND) {
                samples = fgPss.samples;
                avg = fgPss.pss;
            } else if (procState <= STATE_RECEIVER) {
                samples = bgPss.samples;
                avg = bgPss.pss;
            } else {
                samples = cachedPss.samples;
                avg = cachedPss.pss;
            }
            double newAvg = ( (data.processStatePss[procState]
                    * (double)data.processStateSamples[procState])
                        + (avg*(double)samples)
                    ) / (data.processStateSamples[procState]+samples);
            data.processStatePss[procState] = (long)newAvg;
            data.processStateSamples[procState] += samples;
            data.processStateWeight[procState] += avg * (double)time;
        }
    }

    public long computeProcessTimeLocked(int[] screenStates, int[] memStates,
                int[] procStates, long now) {
        long totalTime = 0;
        for (int is=0; is<screenStates.length; is++) {
            for (int im=0; im<memStates.length; im++) {
                for (int ip=0; ip<procStates.length; ip++) {
                    int bucket = ((screenStates[is] + memStates[im]) * STATE_COUNT)
                            + procStates[ip];
                    totalTime += getDuration(bucket, now);
                }
            }
        }
        mTmpTotalTime = totalTime;
        return totalTime;
    }

    public void dumpSummary(PrintWriter pw, String prefix,
            int[] screenStates, int[] memStates, int[] procStates,
            long now, long totalTime) {
        pw.print(prefix);
        pw.print("* ");
        pw.print(mName);
        pw.print(" / ");
        UserHandle.formatUid(pw, mUid);
        pw.print(" / v");
        pw.print(mVersion);
        pw.println(":");
        dumpProcessSummaryDetails(pw, prefix, "         TOTAL: ", screenStates, memStates,
                procStates, now, totalTime, true);
        dumpProcessSummaryDetails(pw, prefix, "    Persistent: ", screenStates, memStates,
                new int[] { STATE_PERSISTENT }, now, totalTime, true);
        dumpProcessSummaryDetails(pw, prefix, "           Top: ", screenStates, memStates,
                new int[] {STATE_TOP}, now, totalTime, true);
        dumpProcessSummaryDetails(pw, prefix, "        Imp Fg: ", screenStates, memStates,
                new int[] { STATE_IMPORTANT_FOREGROUND }, now, totalTime, true);
        dumpProcessSummaryDetails(pw, prefix, "        Imp Bg: ", screenStates, memStates,
                new int[] {STATE_IMPORTANT_BACKGROUND}, now, totalTime, true);
        dumpProcessSummaryDetails(pw, prefix, "        Backup: ", screenStates, memStates,
                new int[] {STATE_BACKUP}, now, totalTime, true);
        dumpProcessSummaryDetails(pw, prefix, "     Heavy Wgt: ", screenStates, memStates,
                new int[] {STATE_HEAVY_WEIGHT}, now, totalTime, true);
        dumpProcessSummaryDetails(pw, prefix, "       Service: ", screenStates, memStates,
                new int[] {STATE_SERVICE}, now, totalTime, true);
        dumpProcessSummaryDetails(pw, prefix, "    Service Rs: ", screenStates, memStates,
                new int[] {STATE_SERVICE_RESTARTING}, now, totalTime, true);
        dumpProcessSummaryDetails(pw, prefix, "      Receiver: ", screenStates, memStates,
                new int[] {STATE_RECEIVER}, now, totalTime, true);
        dumpProcessSummaryDetails(pw, prefix, "        (Home): ", screenStates, memStates,
                new int[] {STATE_HOME}, now, totalTime, true);
        dumpProcessSummaryDetails(pw, prefix, "    (Last Act): ", screenStates, memStates,
                new int[] {STATE_LAST_ACTIVITY}, now, totalTime, true);
        dumpProcessSummaryDetails(pw, prefix, "      (Cached): ", screenStates, memStates,
                new int[] {STATE_CACHED_ACTIVITY, STATE_CACHED_ACTIVITY_CLIENT,
                        STATE_CACHED_EMPTY}, now, totalTime, true);
    }

    public void dumpProcessState(PrintWriter pw, String prefix,
            int[] screenStates, int[] memStates, int[] procStates, long now) {
        long totalTime = 0;
        int printedScreen = -1;
        for (int is=0; is<screenStates.length; is++) {
            int printedMem = -1;
            for (int im=0; im<memStates.length; im++) {
                for (int ip=0; ip<procStates.length; ip++) {
                    final int iscreen = screenStates[is];
                    final int imem = memStates[im];
                    final int bucket = ((iscreen + imem) * STATE_COUNT) + procStates[ip];
                    long time = mDurations.getValueForId((byte)bucket);
                    String running = "";
                    if (mCurState == bucket) {
                        running = " (running)";
                    }
                    if (time != 0) {
                        pw.print(prefix);
                        if (screenStates.length > 1) {
                            DumpUtils.printScreenLabel(pw, printedScreen != iscreen
                                    ? iscreen : STATE_NOTHING);
                            printedScreen = iscreen;
                        }
                        if (memStates.length > 1) {
                            DumpUtils.printMemLabel(pw,
                                    printedMem != imem ? imem : STATE_NOTHING, '/');
                            printedMem = imem;
                        }
                        pw.print(DumpUtils.STATE_NAMES[procStates[ip]]); pw.print(": ");
                        TimeUtils.formatDuration(time, pw); pw.println(running);
                        totalTime += time;
                    }
                }
            }
        }
        if (totalTime != 0) {
            pw.print(prefix);
            if (screenStates.length > 1) {
                DumpUtils.printScreenLabel(pw, STATE_NOTHING);
            }
            if (memStates.length > 1) {
                DumpUtils.printMemLabel(pw, STATE_NOTHING, '/');
            }
            pw.print("TOTAL  : ");
            TimeUtils.formatDuration(totalTime, pw);
            pw.println();
        }
    }

    public void dumpPss(PrintWriter pw, String prefix,
            int[] screenStates, int[] memStates, int[] procStates) {
        boolean printedHeader = false;
        int printedScreen = -1;
        for (int is=0; is<screenStates.length; is++) {
            int printedMem = -1;
            for (int im=0; im<memStates.length; im++) {
                for (int ip=0; ip<procStates.length; ip++) {
                    final int iscreen = screenStates[is];
                    final int imem = memStates[im];
                    final int bucket = ((iscreen + imem) * STATE_COUNT) + procStates[ip];
                    long count = getPssSampleCount(bucket);
                    if (count > 0) {
                        if (!printedHeader) {
                            pw.print(prefix);
                            pw.print("PSS/USS (");
                            pw.print(mPssTable.getKeyCount());
                            pw.println(" entries):");
                            printedHeader = true;
                        }
                        pw.print(prefix);
                        pw.print("  ");
                        if (screenStates.length > 1) {
                            DumpUtils.printScreenLabel(pw,
                                    printedScreen != iscreen ? iscreen : STATE_NOTHING);
                            printedScreen = iscreen;
                        }
                        if (memStates.length > 1) {
                            DumpUtils.printMemLabel(pw,
                                    printedMem != imem ? imem : STATE_NOTHING, '/');
                            printedMem = imem;
                        }
                        pw.print(DumpUtils.STATE_NAMES[procStates[ip]]); pw.print(": ");
                        pw.print(count);
                        pw.print(" samples ");
                        DebugUtils.printSizeValue(pw, getPssMinimum(bucket) * 1024);
                        pw.print(" ");
                        DebugUtils.printSizeValue(pw, getPssAverage(bucket) * 1024);
                        pw.print(" ");
                        DebugUtils.printSizeValue(pw, getPssMaximum(bucket) * 1024);
                        pw.print(" / ");
                        DebugUtils.printSizeValue(pw, getPssUssMinimum(bucket) * 1024);
                        pw.print(" ");
                        DebugUtils.printSizeValue(pw, getPssUssAverage(bucket) * 1024);
                        pw.print(" ");
                        DebugUtils.printSizeValue(pw, getPssUssMaximum(bucket) * 1024);
                        pw.println();
                    }
                }
            }
        }
        if (mNumExcessiveWake != 0) {
            pw.print(prefix); pw.print("Killed for excessive wake locks: ");
                    pw.print(mNumExcessiveWake); pw.println(" times");
        }
        if (mNumExcessiveCpu != 0) {
            pw.print(prefix); pw.print("Killed for excessive CPU use: ");
                    pw.print(mNumExcessiveCpu); pw.println(" times");
        }
        if (mNumCachedKill != 0) {
            pw.print(prefix); pw.print("Killed from cached state: ");
                    pw.print(mNumCachedKill); pw.print(" times from pss ");
                    DebugUtils.printSizeValue(pw, mMinCachedKillPss * 1024); pw.print("-");
                    DebugUtils.printSizeValue(pw, mAvgCachedKillPss * 1024); pw.print("-");
                    DebugUtils.printSizeValue(pw, mMaxCachedKillPss * 1024); pw.println();
        }
    }

    private void dumpProcessSummaryDetails(PrintWriter pw, String prefix,
            String label, int[] screenStates, int[] memStates, int[] procStates,
            long now, long totalTime, boolean full) {
        ProcessStats.ProcessDataCollection totals = new ProcessStats.ProcessDataCollection(
                screenStates, memStates, procStates);
        computeProcessData(totals, now);
        final double percentage = (double) totals.totalTime / (double) totalTime * 100;
        // We don't print percentages < .01, so just drop those.
        if (percentage >= 0.005 || totals.numPss != 0) {
            if (prefix != null) {
                pw.print(prefix);
            }
            if (label != null) {
                pw.print(label);
            }
            totals.print(pw, totalTime, full);
            if (prefix != null) {
                pw.println();
            }
        }
    }

    public void dumpInternalLocked(PrintWriter pw, String prefix, boolean dumpAll) {
        if (dumpAll) {
            pw.print(prefix); pw.print("myID=");
                    pw.print(Integer.toHexString(System.identityHashCode(this)));
                    pw.print(" mCommonProcess=");
                    pw.print(Integer.toHexString(System.identityHashCode(mCommonProcess)));
                    pw.print(" mPackage="); pw.println(mPackage);
            if (mMultiPackage) {
                pw.print(prefix); pw.print("mMultiPackage="); pw.println(mMultiPackage);
            }
            if (this != mCommonProcess) {
                pw.print(prefix); pw.print("Common Proc: "); pw.print(mCommonProcess.mName);
                        pw.print("/"); pw.print(mCommonProcess.mUid);
                        pw.print(" pkg="); pw.println(mCommonProcess.mPackage);
            }
        }
        if (mActive) {
            pw.print(prefix); pw.print("mActive="); pw.println(mActive);
        }
        if (mDead) {
            pw.print(prefix); pw.print("mDead="); pw.println(mDead);
        }
        if (mNumActiveServices != 0 || mNumStartedServices != 0) {
            pw.print(prefix); pw.print("mNumActiveServices="); pw.print(mNumActiveServices);
                    pw.print(" mNumStartedServices=");
                    pw.println(mNumStartedServices);
        }
    }

    public void computeProcessData(ProcessStats.ProcessDataCollection data, long now) {
        data.totalTime = 0;
        data.numPss = data.minPss = data.avgPss = data.maxPss =
                data.minUss = data.avgUss = data.maxUss = 0;
        for (int is=0; is<data.screenStates.length; is++) {
            for (int im=0; im<data.memStates.length; im++) {
                for (int ip=0; ip<data.procStates.length; ip++) {
                    int bucket = ((data.screenStates[is] + data.memStates[im]) * STATE_COUNT)
                            + data.procStates[ip];
                    data.totalTime += getDuration(bucket, now);
                    long samples = getPssSampleCount(bucket);
                    if (samples > 0) {
                        long minPss = getPssMinimum(bucket);
                        long avgPss = getPssAverage(bucket);
                        long maxPss = getPssMaximum(bucket);
                        long minUss = getPssUssMinimum(bucket);
                        long avgUss = getPssUssAverage(bucket);
                        long maxUss = getPssUssMaximum(bucket);
                        if (data.numPss == 0) {
                            data.minPss = minPss;
                            data.avgPss = avgPss;
                            data.maxPss = maxPss;
                            data.minUss = minUss;
                            data.avgUss = avgUss;
                            data.maxUss = maxUss;
                        } else {
                            if (minPss < data.minPss) {
                                data.minPss = minPss;
                            }
                            data.avgPss = (long)( ((data.avgPss*(double)data.numPss)
                                    + (avgPss*(double)samples)) / (data.numPss+samples) );
                            if (maxPss > data.maxPss) {
                                data.maxPss = maxPss;
                            }
                            if (minUss < data.minUss) {
                                data.minUss = minUss;
                            }
                            data.avgUss = (long)( ((data.avgUss*(double)data.numPss)
                                    + (avgUss*(double)samples)) / (data.numPss+samples) );
                            if (maxUss > data.maxUss) {
                                data.maxUss = maxUss;
                            }
                        }
                        data.numPss += samples;
                    }
                }
            }
        }
    }

    public void dumpCsv(PrintWriter pw,
            boolean sepScreenStates, int[] screenStates, boolean sepMemStates,
            int[] memStates, boolean sepProcStates, int[] procStates, long now) {
        final int NSS = sepScreenStates ? screenStates.length : 1;
        final int NMS = sepMemStates ? memStates.length : 1;
        final int NPS = sepProcStates ? procStates.length : 1;
        for (int iss=0; iss<NSS; iss++) {
            for (int ims=0; ims<NMS; ims++) {
                for (int ips=0; ips<NPS; ips++) {
                    final int vsscreen = sepScreenStates ? screenStates[iss] : 0;
                    final int vsmem = sepMemStates ? memStates[ims] : 0;
                    final int vsproc = sepProcStates ? procStates[ips] : 0;
                    final int NSA = sepScreenStates ? 1 : screenStates.length;
                    final int NMA = sepMemStates ? 1 : memStates.length;
                    final int NPA = sepProcStates ? 1 : procStates.length;
                    long totalTime = 0;
                    for (int isa=0; isa<NSA; isa++) {
                        for (int ima=0; ima<NMA; ima++) {
                            for (int ipa=0; ipa<NPA; ipa++) {
                                final int vascreen = sepScreenStates ? 0 : screenStates[isa];
                                final int vamem = sepMemStates ? 0 : memStates[ima];
                                final int vaproc = sepProcStates ? 0 : procStates[ipa];
                                final int bucket = ((vsscreen + vascreen + vsmem + vamem)
                                        * STATE_COUNT) + vsproc + vaproc;
                                totalTime += getDuration(bucket, now);
                            }
                        }
                    }
                    pw.print(DumpUtils.CSV_SEP);
                    pw.print(totalTime);
                }
            }
        }
    }

    public void dumpPackageProcCheckin(PrintWriter pw, String pkgName, int uid, int vers,
            String itemName, long now) {
        pw.print("pkgproc,");
        pw.print(pkgName);
        pw.print(",");
        pw.print(uid);
        pw.print(",");
        pw.print(vers);
        pw.print(",");
        pw.print(DumpUtils.collapseString(pkgName, itemName));
        dumpAllStateCheckin(pw, now);
        pw.println();
        if (mPssTable.getKeyCount() > 0) {
            pw.print("pkgpss,");
            pw.print(pkgName);
            pw.print(",");
            pw.print(uid);
            pw.print(",");
            pw.print(vers);
            pw.print(",");
            pw.print(DumpUtils.collapseString(pkgName, itemName));
            dumpAllPssCheckin(pw);
            pw.println();
        }
        if (mNumExcessiveWake > 0 || mNumExcessiveCpu > 0 || mNumCachedKill > 0) {
            pw.print("pkgkills,");
            pw.print(pkgName);
            pw.print(",");
            pw.print(uid);
            pw.print(",");
            pw.print(vers);
            pw.print(",");
            pw.print(DumpUtils.collapseString(pkgName, itemName));
            pw.print(",");
            pw.print(mNumExcessiveWake);
            pw.print(",");
            pw.print(mNumExcessiveCpu);
            pw.print(",");
            pw.print(mNumCachedKill);
            pw.print(",");
            pw.print(mMinCachedKillPss);
            pw.print(":");
            pw.print(mAvgCachedKillPss);
            pw.print(":");
            pw.print(mMaxCachedKillPss);
            pw.println();
        }
    }

    public void dumpProcCheckin(PrintWriter pw, String procName, int uid, long now) {
        if (mDurations.getKeyCount() > 0) {
            pw.print("proc,");
            pw.print(procName);
            pw.print(",");
            pw.print(uid);
            dumpAllStateCheckin(pw, now);
            pw.println();
        }
        if (mPssTable.getKeyCount() > 0) {
            pw.print("pss,");
            pw.print(procName);
            pw.print(",");
            pw.print(uid);
            dumpAllPssCheckin(pw);
            pw.println();
        }
        if (mNumExcessiveWake > 0 || mNumExcessiveCpu > 0 || mNumCachedKill > 0) {
            pw.print("kills,");
            pw.print(procName);
            pw.print(",");
            pw.print(uid);
            pw.print(",");
            pw.print(mNumExcessiveWake);
            pw.print(",");
            pw.print(mNumExcessiveCpu);
            pw.print(",");
            pw.print(mNumCachedKill);
            pw.print(",");
            pw.print(mMinCachedKillPss);
            pw.print(":");
            pw.print(mAvgCachedKillPss);
            pw.print(":");
            pw.print(mMaxCachedKillPss);
            pw.println();
        }
    }

    public void dumpAllStateCheckin(PrintWriter pw, long now) {
        boolean didCurState = false;
        for (int i=0; i<mDurations.getKeyCount(); i++) {
            final int key = mDurations.getKeyAt(i);
            final int type = SparseMappingTable.getIdFromKey(key);
            long time = mDurations.getValue(key);
            if (mCurState == type) {
                didCurState = true;
                time += now - mStartTime;
            }
            DumpUtils.printProcStateTagAndValue(pw, type, time);
        }
        if (!didCurState && mCurState != STATE_NOTHING) {
            DumpUtils.printProcStateTagAndValue(pw, mCurState, now - mStartTime);
        }
    }

    public void dumpAllPssCheckin(PrintWriter pw) {
        final int N = mPssTable.getKeyCount();
        for (int i=0; i<N; i++) {
            final int key = mPssTable.getKeyAt(i);
            final int type = SparseMappingTable.getIdFromKey(key);
            pw.print(',');
            DumpUtils.printProcStateTag(pw, type);
            pw.print(':');
            pw.print(mPssTable.getValue(key, PSS_SAMPLE_COUNT));
            pw.print(':');
            pw.print(mPssTable.getValue(key, PSS_MINIMUM));
            pw.print(':');
            pw.print(mPssTable.getValue(key, PSS_AVERAGE));
            pw.print(':');
            pw.print(mPssTable.getValue(key, PSS_MAXIMUM));
            pw.print(':');
            pw.print(mPssTable.getValue(key, PSS_USS_MINIMUM));
            pw.print(':');
            pw.print(mPssTable.getValue(key, PSS_USS_AVERAGE));
            pw.print(':');
            pw.print(mPssTable.getValue(key, PSS_USS_MAXIMUM));
        }
    }

    public String toString() {
        StringBuilder sb = new StringBuilder(128);
        sb.append("ProcessState{").append(Integer.toHexString(System.identityHashCode(this)))
                .append(" ").append(mName).append("/").append(mUid)
                .append(" pkg=").append(mPackage);
        if (mMultiPackage) sb.append(" (multi)");
        if (mCommonProcess != this) sb.append(" (sub)");
        sb.append("}");
        return sb.toString();
    }
}
