1d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn/*
2d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn * Copyright (C) 2013 The Android Open Source Project
3d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn *
4d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
5d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn * you may not use this file except in compliance with the License.
6d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn * You may obtain a copy of the License at
7d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn *
8d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
9d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn *
10d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn * Unless required by applicable law or agreed to in writing, software
11d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
12d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn * See the License for the specific language governing permissions and
14d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn * limitations under the License.
15d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn */
16d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
17d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornpackage com.android.server.am;
18d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
198a0de58ece89c467c8e7415097d193e5f8db9db8Dianne Hackbornimport android.content.pm.PackageManager;
208a0de58ece89c467c8e7415097d193e5f8db9db8Dianne Hackbornimport android.os.Binder;
21d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornimport android.os.Parcel;
2223fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackbornimport android.os.ParcelFileDescriptor;
23d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornimport android.os.RemoteException;
24d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornimport android.os.SystemClock;
25d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornimport android.os.SystemProperties;
26d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornimport android.util.ArrayMap;
27d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornimport android.util.AtomicFile;
28d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornimport android.util.Slog;
29d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornimport android.util.SparseArray;
3053459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackbornimport android.util.TimeUtils;
3123fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackbornimport com.android.internal.app.IProcessStats;
32d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornimport com.android.internal.app.ProcessStats;
33d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornimport com.android.internal.os.BackgroundThread;
34d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
35d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornimport java.io.File;
36d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornimport java.io.FileDescriptor;
37d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornimport java.io.FileInputStream;
38d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornimport java.io.FileOutputStream;
39d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornimport java.io.IOException;
4053459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackbornimport java.io.InputStream;
41d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornimport java.io.PrintWriter;
42d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornimport java.util.ArrayList;
43d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornimport java.util.Collections;
4423fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackbornimport java.util.List;
45d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackbornimport java.util.concurrent.locks.ReentrantLock;
46d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
4723fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackbornpublic final class ProcessStatsService extends IProcessStats.Stub {
48d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    static final String TAG = "ProcessStatsService";
49d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    static final boolean DEBUG = false;
50d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
51d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    // Most data is kept in a sparse data structure: an integer array which integer
52d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    // holds the type of the entry, and the identifier for a long array that data
53d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    // exists in and the offset into the array to find it.  The constants below
54d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    // define the encoding of that data in an integer.
55d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
566d9ef38b0603133ee1a9c7bd63f1d971ae1d62adDianne Hackborn    static final int MAX_HISTORIC_STATES = 8;   // Maximum number of historic states we will keep.
57d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    static final String STATE_FILE_PREFIX = "state-"; // Prefix to use for state filenames.
58d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    static final String STATE_FILE_SUFFIX = ".bin"; // Suffix to use for state filenames.
59d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    static final String STATE_FILE_CHECKIN_SUFFIX = ".ci"; // State files that have checked in.
60d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    static long WRITE_PERIOD = 30*60*1000;      // Write file every 30 minutes or so.
61d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
628a0de58ece89c467c8e7415097d193e5f8db9db8Dianne Hackborn    final ActivityManagerService mAm;
63d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    final File mBaseDir;
64d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    ProcessStats mProcessStats;
65d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    AtomicFile mFile;
66d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    boolean mCommitPending;
67d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    boolean mShuttingDown;
68d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    int mLastMemOnlyState = -1;
69d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    boolean mMemFactorLowered;
70d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
71d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    final ReentrantLock mWriteLock = new ReentrantLock();
72d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    final Object mPendingWriteLock = new Object();
73d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    AtomicFile mPendingWriteFile;
74d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    Parcel mPendingWrite;
75d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    boolean mPendingWriteCommitted;
76d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    long mLastWriteTime;
77d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
788a0de58ece89c467c8e7415097d193e5f8db9db8Dianne Hackborn    public ProcessStatsService(ActivityManagerService am, File file) {
798a0de58ece89c467c8e7415097d193e5f8db9db8Dianne Hackborn        mAm = am;
80d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        mBaseDir = file;
81d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        mBaseDir.mkdirs();
82d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        mProcessStats = new ProcessStats(true);
83d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        updateFile();
84d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        SystemProperties.addChangeCallback(new Runnable() {
85d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            @Override public void run() {
868a0de58ece89c467c8e7415097d193e5f8db9db8Dianne Hackborn                synchronized (mAm) {
87d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    if (mProcessStats.evaluateSystemProperties(false)) {
88d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        mProcessStats.mFlags |= ProcessStats.FLAG_SYSPROPS;
89d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        writeStateLocked(true, true);
90d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        mProcessStats.evaluateSystemProperties(true);
91d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    }
92d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                }
93d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
94d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        });
95d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
96d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
97d94d533b5a9ec44899a4bc0e09796a5ec82a250eDianne Hackborn    @Override
98d94d533b5a9ec44899a4bc0e09796a5ec82a250eDianne Hackborn    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
99d94d533b5a9ec44899a4bc0e09796a5ec82a250eDianne Hackborn            throws RemoteException {
100d94d533b5a9ec44899a4bc0e09796a5ec82a250eDianne Hackborn        try {
101d94d533b5a9ec44899a4bc0e09796a5ec82a250eDianne Hackborn            return super.onTransact(code, data, reply, flags);
102d94d533b5a9ec44899a4bc0e09796a5ec82a250eDianne Hackborn        } catch (RuntimeException e) {
103d94d533b5a9ec44899a4bc0e09796a5ec82a250eDianne Hackborn            if (!(e instanceof SecurityException)) {
104d94d533b5a9ec44899a4bc0e09796a5ec82a250eDianne Hackborn                Slog.wtf(TAG, "Process Stats Crash", e);
105d94d533b5a9ec44899a4bc0e09796a5ec82a250eDianne Hackborn            }
106d94d533b5a9ec44899a4bc0e09796a5ec82a250eDianne Hackborn            throw e;
107d94d533b5a9ec44899a4bc0e09796a5ec82a250eDianne Hackborn        }
108d94d533b5a9ec44899a4bc0e09796a5ec82a250eDianne Hackborn    }
109d94d533b5a9ec44899a4bc0e09796a5ec82a250eDianne Hackborn
110d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    public ProcessStats.ProcessState getProcessStateLocked(String packageName,
1118472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn            int uid, int versionCode, String processName) {
1128472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn        return mProcessStats.getProcessStateLocked(packageName, uid, versionCode, processName);
113d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
114d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
115d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    public ProcessStats.ServiceState getServiceStateLocked(String packageName, int uid,
1168472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn            int versionCode, String processName, String className) {
1178472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn        return mProcessStats.getServiceStateLocked(packageName, uid, versionCode, processName,
1188472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                className);
119d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
120d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
121d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    public boolean isMemFactorLowered() {
122d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        return mMemFactorLowered;
123d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
124d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
125d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    public boolean setMemFactorLocked(int memFactor, boolean screenOn, long now) {
126d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        mMemFactorLowered = memFactor < mLastMemOnlyState;
127d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        mLastMemOnlyState = memFactor;
128d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        if (screenOn) {
129d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            memFactor += ProcessStats.ADJ_SCREEN_ON;
130d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        }
131d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        if (memFactor != mProcessStats.mMemFactor) {
132d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            if (mProcessStats.mMemFactor != ProcessStats.STATE_NOTHING) {
133d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                mProcessStats.mMemFactorDurations[mProcessStats.mMemFactor]
134d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        += now - mProcessStats.mStartTime;
135d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
136d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            mProcessStats.mMemFactor = memFactor;
137d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            mProcessStats.mStartTime = now;
1388472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn            final ArrayMap<String, SparseArray<SparseArray<ProcessStats.PackageState>>> pmap
139d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    = mProcessStats.mPackages.getMap();
1408472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn            for (int ipkg=pmap.size()-1; ipkg>=0; ipkg--) {
1418472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                final SparseArray<SparseArray<ProcessStats.PackageState>> uids = pmap.valueAt(ipkg);
1428472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                for (int iuid=uids.size()-1; iuid>=0; iuid--) {
1438472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                    final SparseArray<ProcessStats.PackageState> vers = uids.valueAt(iuid);
1448472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                    for (int iver=vers.size()-1; iver>=0; iver--) {
1458472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                        final ProcessStats.PackageState pkg = vers.valueAt(iver);
1468472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                        final ArrayMap<String, ProcessStats.ServiceState> services = pkg.mServices;
1478472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                        for (int isvc=services.size()-1; isvc>=0; isvc--) {
1488472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                            final ProcessStats.ServiceState service = services.valueAt(isvc);
14925e1ecaabbde4741663c8e5a777d9df9b939572cDianne Hackborn                            if (service.isRestarting()) {
15025e1ecaabbde4741663c8e5a777d9df9b939572cDianne Hackborn                                service.setRestarting(true, memFactor, now);
15125e1ecaabbde4741663c8e5a777d9df9b939572cDianne Hackborn                            } else if (service.isInUse()) {
1528472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                if (service.mStartedState != ProcessStats.STATE_NOTHING) {
1538472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                    service.setStarted(true, memFactor, now);
1548472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                }
1558472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                if (service.mBoundState != ProcessStats.STATE_NOTHING) {
1568472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                    service.setBound(true, memFactor, now);
1578472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                }
1588472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                if (service.mExecState != ProcessStats.STATE_NOTHING) {
1598472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                    service.setExecuting(true, memFactor, now);
1608472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                }
161d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            }
162d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        }
163d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    }
164d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                }
165d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
166d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            return true;
167d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        }
168d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        return false;
169d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
170d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
171d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    public int getMemFactorLocked() {
172d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        return mProcessStats.mMemFactor != ProcessStats.STATE_NOTHING ? mProcessStats.mMemFactor : 0;
173d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
174d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
175f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn    public void addSysMemUsageLocked(long cachedMem, long freeMem, long zramMem, long kernelMem,
176f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn            long nativeMem) {
177f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn        mProcessStats.addSysMemUsage(cachedMem, freeMem, zramMem, kernelMem, nativeMem);
178f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn    }
179f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn
180d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    public boolean shouldWriteNowLocked(long now) {
181d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        if (now > (mLastWriteTime+WRITE_PERIOD)) {
182d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            if (SystemClock.elapsedRealtime()
183f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                    > (mProcessStats.mTimePeriodStartRealtime+ProcessStats.COMMIT_PERIOD) &&
184f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                    SystemClock.uptimeMillis()
185f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                    > (mProcessStats.mTimePeriodStartUptime+ProcessStats.COMMIT_UPTIME_PERIOD)) {
186d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                mCommitPending = true;
187d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
188d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            return true;
189d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        }
190d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        return false;
191d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
192d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
193d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    public void shutdownLocked() {
194d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        Slog.w(TAG, "Writing process stats before shutdown...");
195d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        mProcessStats.mFlags |= ProcessStats.FLAG_SHUTDOWN;
196d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        writeStateSyncLocked();
197d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        mShuttingDown = true;
198d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
199d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
200d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    public void writeStateAsyncLocked() {
201d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        writeStateLocked(false);
202d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
203d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
204d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    public void writeStateSyncLocked() {
205d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        writeStateLocked(true);
206d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
207d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
208d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    private void writeStateLocked(boolean sync) {
209d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        if (mShuttingDown) {
210d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            return;
211d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        }
212d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        boolean commitPending = mCommitPending;
213d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        mCommitPending = false;
214d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        writeStateLocked(sync, commitPending);
215d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
216d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
217d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    public void writeStateLocked(boolean sync, final boolean commit) {
218d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        synchronized (mPendingWriteLock) {
219d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            long now = SystemClock.uptimeMillis();
220d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            if (mPendingWrite == null || !mPendingWriteCommitted) {
221d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                mPendingWrite = Parcel.obtain();
222d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
223f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                mProcessStats.mTimePeriodEndUptime = now;
224d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                if (commit) {
225d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    mProcessStats.mFlags |= ProcessStats.FLAG_COMPLETE;
226d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                }
22723fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn                mProcessStats.writeToParcel(mPendingWrite, 0);
228d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                mPendingWriteFile = new AtomicFile(mFile.getBaseFile());
229d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                mPendingWriteCommitted = commit;
230d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
231d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            if (commit) {
232d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                mProcessStats.resetSafely();
233d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                updateFile();
234d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
235d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            mLastWriteTime = SystemClock.uptimeMillis();
236d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            Slog.i(TAG, "Prepared write state in " + (SystemClock.uptimeMillis()-now) + "ms");
237d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            if (!sync) {
238d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                BackgroundThread.getHandler().post(new Runnable() {
239d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    @Override public void run() {
240d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        performWriteState();
241d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    }
242d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                });
243d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                return;
244d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
245d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        }
246d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
247d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        performWriteState();
248d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
249d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
250d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    private void updateFile() {
251d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        mFile = new AtomicFile(new File(mBaseDir, STATE_FILE_PREFIX
252d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                + mProcessStats.mTimePeriodStartClockStr + STATE_FILE_SUFFIX));
253d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        mLastWriteTime = SystemClock.uptimeMillis();
254d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
255d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
256d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    void performWriteState() {
257d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        if (DEBUG) Slog.d(TAG, "Performing write to " + mFile.getBaseFile());
258d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        Parcel data;
259d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        AtomicFile file;
260d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        synchronized (mPendingWriteLock) {
261d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            data = mPendingWrite;
262d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            file = mPendingWriteFile;
263d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            mPendingWriteCommitted = false;
264d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            if (data == null) {
265d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                return;
266d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
267d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            mPendingWrite = null;
268d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            mPendingWriteFile = null;
269d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            mWriteLock.lock();
270d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        }
271d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
272d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        FileOutputStream stream = null;
273d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        try {
274d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            stream = file.startWrite();
275d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            stream.write(data.marshall());
276d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            stream.flush();
277d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            file.finishWrite(stream);
278d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            if (DEBUG) Slog.d(TAG, "Write completed successfully!");
279d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        } catch (IOException e) {
280d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            Slog.w(TAG, "Error writing process statistics", e);
281d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            file.failWrite(stream);
282d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        } finally {
283d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            data.recycle();
284d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            trimHistoricStatesWriteLocked();
285d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            mWriteLock.unlock();
286d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        }
287d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
288d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
289d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    boolean readLocked(ProcessStats stats, AtomicFile file) {
290d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        try {
291d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            FileInputStream stream = file.openRead();
29260444fd594ac92aa48e229c600c2ce7de4caf2d1Dianne Hackborn            stats.read(stream);
293d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            stream.close();
294d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            if (stats.mReadError != null) {
295d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                Slog.w(TAG, "Ignoring existing stats; " + stats.mReadError);
296d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                if (DEBUG) {
297d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    ArrayMap<String, SparseArray<ProcessStats.ProcessState>> procMap
298d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            = stats.mProcesses.getMap();
299d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    final int NPROC = procMap.size();
300d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    for (int ip=0; ip<NPROC; ip++) {
301d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        Slog.w(TAG, "Process: " + procMap.keyAt(ip));
302d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        SparseArray<ProcessStats.ProcessState> uids = procMap.valueAt(ip);
303d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        final int NUID = uids.size();
304d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        for (int iu=0; iu<NUID; iu++) {
305d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            Slog.w(TAG, "  Uid " + uids.keyAt(iu) + ": " + uids.valueAt(iu));
306d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        }
307d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    }
3088472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                    ArrayMap<String, SparseArray<SparseArray<ProcessStats.PackageState>>> pkgMap
309d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            = stats.mPackages.getMap();
310d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    final int NPKG = pkgMap.size();
311d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    for (int ip=0; ip<NPKG; ip++) {
312d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        Slog.w(TAG, "Package: " + pkgMap.keyAt(ip));
3138472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                        SparseArray<SparseArray<ProcessStats.PackageState>> uids
3148472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                = pkgMap.valueAt(ip);
315d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        final int NUID = uids.size();
316d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        for (int iu=0; iu<NUID; iu++) {
317d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            Slog.w(TAG, "  Uid: " + uids.keyAt(iu));
3188472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                            SparseArray<ProcessStats.PackageState> vers = uids.valueAt(iu);
3198472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                            final int NVERS = vers.size();
3208472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                            for (int iv=0; iv<NVERS; iv++) {
3218472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                Slog.w(TAG, "    Vers: " + vers.keyAt(iv));
3228472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                ProcessStats.PackageState pkgState = vers.valueAt(iv);
3238472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                final int NPROCS = pkgState.mProcesses.size();
3248472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                for (int iproc=0; iproc<NPROCS; iproc++) {
3258472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                    Slog.w(TAG, "      Process " + pkgState.mProcesses.keyAt(iproc)
3268472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                            + ": " + pkgState.mProcesses.valueAt(iproc));
3278472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                }
3288472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                final int NSRVS = pkgState.mServices.size();
3298472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                for (int isvc=0; isvc<NSRVS; isvc++) {
3308472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                    Slog.w(TAG, "      Service " + pkgState.mServices.keyAt(isvc)
3318472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                            + ": " + pkgState.mServices.valueAt(isvc));
3328472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn
3338472e6189cd4e0520c047bdb28457abc728b373fDianne Hackborn                                }
334d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            }
335d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        }
336d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    }
337d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                }
338d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                return false;
339d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
340d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        } catch (Throwable e) {
341d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            stats.mReadError = "caught exception: " + e;
342d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            Slog.e(TAG, "Error reading process statistics", e);
343d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            return false;
344d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        }
345d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        return true;
346d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
347d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
34853459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn    private ArrayList<String> getCommittedFiles(int minNum, boolean inclCurrent,
34953459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn            boolean inclCheckedIn) {
350d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        File[] files = mBaseDir.listFiles();
351d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        if (files == null || files.length <= minNum) {
352d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            return null;
353d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        }
354d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        ArrayList<String> filesArray = new ArrayList<String>(files.length);
355d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        String currentFile = mFile.getBaseFile().getPath();
356d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        if (DEBUG) Slog.d(TAG, "Collecting " + files.length + " files except: " + currentFile);
357d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        for (int i=0; i<files.length; i++) {
358d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            File file = files[i];
359d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            String fileStr = file.getPath();
360d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            if (DEBUG) Slog.d(TAG, "Collecting: " + fileStr);
36153459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn            if (!inclCheckedIn && fileStr.endsWith(STATE_FILE_CHECKIN_SUFFIX)) {
362d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                if (DEBUG) Slog.d(TAG, "Skipping: already checked in");
363d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                continue;
364d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
36553459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn            if (!inclCurrent && fileStr.equals(currentFile)) {
366d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                if (DEBUG) Slog.d(TAG, "Skipping: current stats");
367d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                continue;
368d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
369d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            filesArray.add(fileStr);
370d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        }
371d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        Collections.sort(filesArray);
372d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        return filesArray;
373d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
374d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
375d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    public void trimHistoricStatesWriteLocked() {
37653459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn        ArrayList<String> filesArray = getCommittedFiles(MAX_HISTORIC_STATES, false, true);
377d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        if (filesArray == null) {
378d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            return;
379d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        }
380d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        while (filesArray.size() > MAX_HISTORIC_STATES) {
381d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            String file = filesArray.remove(0);
382d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            Slog.i(TAG, "Pruning old procstats: " + file);
383d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            (new File(file)).delete();
384d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        }
385d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
386d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
387d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    boolean dumpFilteredProcessesCsvLocked(PrintWriter pw, String header,
388d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            boolean sepScreenStates, int[] screenStates, boolean sepMemStates, int[] memStates,
389d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            boolean sepProcStates, int[] procStates, long now, String reqPackage) {
390d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        ArrayList<ProcessStats.ProcessState> procs = mProcessStats.collectProcessesLocked(
391164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn                screenStates, memStates, procStates, procStates, now, reqPackage, false);
392d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        if (procs.size() > 0) {
393d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            if (header != null) {
394d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                pw.println(header);
395d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
396d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            ProcessStats.dumpProcessListCsv(pw, procs, sepScreenStates, screenStates,
397d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    sepMemStates, memStates, sepProcStates, procStates, now);
398d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            return true;
399d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        }
400d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        return false;
401d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
402d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
403d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    static int[] parseStateList(String[] states, int mult, String arg, boolean[] outSep,
404d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            String[] outError) {
405d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        ArrayList<Integer> res = new ArrayList<Integer>();
406d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        int lastPos = 0;
407d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        for (int i=0; i<=arg.length(); i++) {
408d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            char c = i < arg.length() ? arg.charAt(i) : 0;
409d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            if (c != ',' && c != '+' && c != ' ' && c != 0) {
410d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                continue;
411d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
412d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            boolean isSep = c == ',';
413d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            if (lastPos == 0) {
414d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                // We now know the type of op.
415d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                outSep[0] = isSep;
416d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            } else if (c != 0 && outSep[0] != isSep) {
417d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                outError[0] = "inconsistent separators (can't mix ',' with '+')";
418d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                return null;
419d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
420d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            if (lastPos < (i-1)) {
421d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                String str = arg.substring(lastPos, i);
422d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                for (int j=0; j<states.length; j++) {
423d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    if (str.equals(states[j])) {
424d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        res.add(j);
425d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        str = null;
426d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        break;
427d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    }
428d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                }
429d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                if (str != null) {
430d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    outError[0] = "invalid word \"" + str + "\"";
431d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    return null;
432d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                }
433d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
434d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            lastPos = i + 1;
435d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        }
436d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
437d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        int[] finalRes = new int[res.size()];
438d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        for (int i=0; i<res.size(); i++) {
439d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            finalRes[i] = res.get(i) * mult;
440d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        }
441d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        return finalRes;
442d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
443d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
44423fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn    public byte[] getCurrentStats(List<ParcelFileDescriptor> historic) {
44553459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn        mAm.mContext.enforceCallingOrSelfPermission(
44653459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                android.Manifest.permission.PACKAGE_USAGE_STATS, null);
44723fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn        Parcel current = Parcel.obtain();
44823fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn        mWriteLock.lock();
44923fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn        try {
4508a0de58ece89c467c8e7415097d193e5f8db9db8Dianne Hackborn            synchronized (mAm) {
451f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                long now = SystemClock.uptimeMillis();
452d6d54a469476f7756b1ce64d10688ec43857ce5aDianne Hackborn                mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
453f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                mProcessStats.mTimePeriodEndUptime = now;
454f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                mProcessStats.writeToParcel(current, now, 0);
45523fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn            }
45623fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn            if (historic != null) {
45753459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                ArrayList<String> files = getCommittedFiles(0, false, true);
45823fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn                if (files != null) {
45923fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn                    for (int i=files.size()-1; i>=0; i--) {
46023fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn                        try {
46123fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn                            ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
46223fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn                                    new File(files.get(i)), ParcelFileDescriptor.MODE_READ_ONLY);
46323fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn                            historic.add(pfd);
46423fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn                        } catch (IOException e) {
46523fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn                            Slog.w(TAG, "Failure opening procstat file " + files.get(i), e);
46623fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn                        }
46723fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn                    }
46823fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn                }
46923fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn            }
47023fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn        } finally {
47123fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn            mWriteLock.unlock();
47223fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn        }
47323fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn        return current.marshall();
47423fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn    }
47523fb6e84182f325f036b1735b817ecc253e2bd19Dianne Hackborn
47653459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn    public ParcelFileDescriptor getStatsOverTime(long minTime) {
47753459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn        mAm.mContext.enforceCallingOrSelfPermission(
47853459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                android.Manifest.permission.PACKAGE_USAGE_STATS, null);
47953459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn        mWriteLock.lock();
48053459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn        try {
48153459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn            Parcel current = Parcel.obtain();
48253459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn            long curTime;
48353459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn            synchronized (mAm) {
484f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                long now = SystemClock.uptimeMillis();
48553459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
486f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                mProcessStats.mTimePeriodEndUptime = now;
487f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                mProcessStats.writeToParcel(current, now, 0);
48853459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                curTime = mProcessStats.mTimePeriodEndRealtime
48953459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                        - mProcessStats.mTimePeriodStartRealtime;
49053459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn            }
49153459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn            if (curTime < minTime) {
49253459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                // Need to add in older stats to reach desired time.
49353459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                ArrayList<String> files = getCommittedFiles(0, false, true);
494cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn                if (files != null && files.size() > 0) {
49553459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                    current.setDataPosition(0);
49653459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                    ProcessStats stats = ProcessStats.CREATOR.createFromParcel(current);
49753459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                    current.recycle();
49859da67900d85fd2c246996bce08109a0ba49a282Dianne Hackborn                    int i = files.size()-1;
49959da67900d85fd2c246996bce08109a0ba49a282Dianne Hackborn                    while (i >= 0 && (stats.mTimePeriodEndRealtime
50053459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                            - stats.mTimePeriodStartRealtime) < minTime) {
50153459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                        AtomicFile file = new AtomicFile(new File(files.get(i)));
50259da67900d85fd2c246996bce08109a0ba49a282Dianne Hackborn                        i--;
50353459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                        ProcessStats moreStats = new ProcessStats(false);
50453459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                        readLocked(moreStats, file);
50553459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                        if (moreStats.mReadError == null) {
50653459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                            stats.add(moreStats);
50753459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                            StringBuilder sb = new StringBuilder();
50853459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                            sb.append("Added stats: ");
50953459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                            sb.append(moreStats.mTimePeriodStartClockStr);
51053459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                            sb.append(", over ");
51153459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                            TimeUtils.formatDuration(moreStats.mTimePeriodEndRealtime
51253459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                                    - moreStats.mTimePeriodStartRealtime, sb);
51353459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                            Slog.i(TAG, sb.toString());
51453459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                        } else {
51559da67900d85fd2c246996bce08109a0ba49a282Dianne Hackborn                            Slog.w(TAG, "Failure reading " + files.get(i+1) + "; "
51653459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                                    + moreStats.mReadError);
51753459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                            continue;
51853459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                        }
51953459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                    }
52053459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                    current = Parcel.obtain();
52153459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                    stats.writeToParcel(current, 0);
52253459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                }
52353459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn            }
52453459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn            final byte[] outData = current.marshall();
52553459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn            current.recycle();
52653459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn            final ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe();
52753459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn            Thread thr = new Thread("ProcessStats pipe output") {
52853459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                public void run() {
52953459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                    FileOutputStream fout = new ParcelFileDescriptor.AutoCloseOutputStream(fds[1]);
53053459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                    try {
53153459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                        fout.write(outData);
53253459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                        fout.close();
53353459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                    } catch (IOException e) {
53453459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                        Slog.w(TAG, "Failure writing pipe", e);
53553459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                    }
53653459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                }
53753459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn            };
53853459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn            thr.start();
53953459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn            return fds[0];
54053459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn        } catch (IOException e) {
54153459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn            Slog.w(TAG, "Failed building output pipe", e);
54253459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn        } finally {
54353459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn            mWriteLock.unlock();
54453459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn        }
54553459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn        return null;
54653459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn    }
54753459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn
54869cb00b8dda60eff7449b69723f4e73a28e944f8Dianne Hackborn    public int getCurrentMemoryState() {
54969cb00b8dda60eff7449b69723f4e73a28e944f8Dianne Hackborn        synchronized (mAm) {
55069cb00b8dda60eff7449b69723f4e73a28e944f8Dianne Hackborn            return mLastMemOnlyState;
55169cb00b8dda60eff7449b69723f4e73a28e944f8Dianne Hackborn        }
55269cb00b8dda60eff7449b69723f4e73a28e944f8Dianne Hackborn    }
55369cb00b8dda60eff7449b69723f4e73a28e944f8Dianne Hackborn
554237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn    private void dumpAggregatedStats(PrintWriter pw, long aggregateHours, long now,
555237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn            String reqPackage, boolean isCompact, boolean dumpDetails, boolean dumpFullDetails,
556237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn            boolean dumpAll, boolean activeOnly) {
557237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn        ParcelFileDescriptor pfd = getStatsOverTime(aggregateHours*60*60*1000
558237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn                - (ProcessStats.COMMIT_PERIOD/2));
559237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn        if (pfd == null) {
560237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn            pw.println("Unable to build stats!");
561237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn            return;
562237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn        }
563237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn        ProcessStats stats = new ProcessStats(false);
564237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn        InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
565237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn        stats.read(stream);
566237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn        if (stats.mReadError != null) {
567237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn            pw.print("Failure reading: "); pw.println(stats.mReadError);
568237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn            return;
569237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn        }
570237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn        if (isCompact) {
571237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn            stats.dumpCheckinLocked(pw, reqPackage);
572237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn        } else {
573237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn            if (dumpDetails || dumpFullDetails) {
574237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn                stats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpAll, activeOnly);
575237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn            } else {
576237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn                stats.dumpSummaryLocked(pw, reqPackage, now, activeOnly);
577237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn            }
578237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn        }
579237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn    }
580237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn
581d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    static private void dumpHelp(PrintWriter pw) {
582d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        pw.println("Process stats (procstats) dump options:");
583d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        pw.println("    [--checkin|-c|--csv] [--csv-screen] [--csv-proc] [--csv-mem]");
584f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn        pw.println("    [--details] [--full-details] [--current] [--hours N] [--last N]");
585d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn        pw.println("    [--max N] --active] [--commit] [--reset] [--clear] [--write] [-h]");
5861a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn        pw.println("    [--start-testing] [--stop-testing] [<package.name>]");
587d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        pw.println("  --checkin: perform a checkin: print and delete old committed states.");
588d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn        pw.println("  -c: print only state in checkin format.");
589d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        pw.println("  --csv: output data suitable for putting in a spreadsheet.");
590d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        pw.println("  --csv-screen: on, off.");
591d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        pw.println("  --csv-mem: norm, mod, low, crit.");
592d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        pw.println("  --csv-proc: pers, top, fore, vis, precept, backup,");
593d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        pw.println("    service, home, prev, cached");
594164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn        pw.println("  --details: dump per-package details, not just summary.");
595164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn        pw.println("  --full-details: dump all timing and active state details.");
596d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        pw.println("  --current: only dump current state.");
597cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn        pw.println("  --hours: aggregate over about N last hours.");
598f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn        pw.println("  --last: only show the last committed stats at index N (starting at 1).");
599d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn        pw.println("  --max: for -a, max num of historical batches to print.");
600164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn        pw.println("  --active: only show currently active processes/services.");
601d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        pw.println("  --commit: commit current stats to disk and reset to start new stats.");
6020d97cd1f6a370b8e371d8b6d88d47e9aaf2bbe32Dianne Hackborn        pw.println("  --reset: reset current stats, without committing.");
60353459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn        pw.println("  --clear: clear all stats; does both --reset and deletes old stats.");
604d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        pw.println("  --write: write current in-memory stats to disk.");
605d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        pw.println("  --read: replace current stats with last-written stats.");
6061a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn        pw.println("  --start-testing: clear all stats and starting high frequency pss sampling.");
6071a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn        pw.println("  --stop-testing: stop high frequency pss sampling.");
608d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        pw.println("  -a: print everything.");
609d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        pw.println("  -h: print this help text.");
610d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        pw.println("  <package.name>: optional name of package to filter output by.");
611d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
612d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
6138a0de58ece89c467c8e7415097d193e5f8db9db8Dianne Hackborn    @Override
6148a0de58ece89c467c8e7415097d193e5f8db9db8Dianne Hackborn    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
6158a0de58ece89c467c8e7415097d193e5f8db9db8Dianne Hackborn        if (mAm.checkCallingPermission(android.Manifest.permission.DUMP)
6168a0de58ece89c467c8e7415097d193e5f8db9db8Dianne Hackborn                != PackageManager.PERMISSION_GRANTED) {
6178a0de58ece89c467c8e7415097d193e5f8db9db8Dianne Hackborn            pw.println("Permission Denial: can't dump procstats from from pid="
6188a0de58ece89c467c8e7415097d193e5f8db9db8Dianne Hackborn                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6198a0de58ece89c467c8e7415097d193e5f8db9db8Dianne Hackborn                    + " without permission " + android.Manifest.permission.DUMP);
6208a0de58ece89c467c8e7415097d193e5f8db9db8Dianne Hackborn            return;
6218a0de58ece89c467c8e7415097d193e5f8db9db8Dianne Hackborn        }
6228a0de58ece89c467c8e7415097d193e5f8db9db8Dianne Hackborn
62308b36a47cf3ca9f58683aa906b9fdf7778fb6840Dianne Hackborn        long ident = Binder.clearCallingIdentity();
62408b36a47cf3ca9f58683aa906b9fdf7778fb6840Dianne Hackborn        try {
62508b36a47cf3ca9f58683aa906b9fdf7778fb6840Dianne Hackborn            dumpInner(fd, pw, args);
62608b36a47cf3ca9f58683aa906b9fdf7778fb6840Dianne Hackborn        } finally {
62708b36a47cf3ca9f58683aa906b9fdf7778fb6840Dianne Hackborn            Binder.restoreCallingIdentity(ident);
62808b36a47cf3ca9f58683aa906b9fdf7778fb6840Dianne Hackborn        }
62908b36a47cf3ca9f58683aa906b9fdf7778fb6840Dianne Hackborn    }
63008b36a47cf3ca9f58683aa906b9fdf7778fb6840Dianne Hackborn
63108b36a47cf3ca9f58683aa906b9fdf7778fb6840Dianne Hackborn    private void dumpInner(FileDescriptor fd, PrintWriter pw, String[] args) {
632d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        final long now = SystemClock.uptimeMillis();
633d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
634d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        boolean isCheckin = false;
635d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        boolean isCompact = false;
636d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        boolean isCsv = false;
637d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        boolean currentOnly = false;
638d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        boolean dumpDetails = false;
63953459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn        boolean dumpFullDetails = false;
640d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        boolean dumpAll = false;
6411a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn        boolean quit = false;
642cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn        int aggregateHours = 0;
643f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn        int lastIndex = 0;
644d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn        int maxNum = 2;
645164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn        boolean activeOnly = false;
646d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        String reqPackage = null;
647d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        boolean csvSepScreenStats = false;
648d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        int[] csvScreenStats = new int[] { ProcessStats.ADJ_SCREEN_OFF, ProcessStats.ADJ_SCREEN_ON};
649d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        boolean csvSepMemStats = false;
650d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        int[] csvMemStats = new int[] { ProcessStats.ADJ_MEM_FACTOR_CRITICAL};
651d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        boolean csvSepProcStats = true;
652d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        int[] csvProcStats = ProcessStats.ALL_PROC_STATES;
653d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        if (args != null) {
654d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            for (int i=0; i<args.length; i++) {
655d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                String arg = args[i];
656d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                if ("--checkin".equals(arg)) {
657d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    isCheckin = true;
658d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                } else if ("-c".equals(arg)) {
659d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    isCompact = true;
660d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                } else if ("--csv".equals(arg)) {
661d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    isCsv = true;
662d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                } else if ("--csv-screen".equals(arg)) {
663d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    i++;
664d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    if (i >= args.length) {
665d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        pw.println("Error: argument required for --csv-screen");
666d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        dumpHelp(pw);
667d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        return;
668d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    }
669d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    boolean[] sep = new boolean[1];
670d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    String[] error = new String[1];
671d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    csvScreenStats = parseStateList(ProcessStats.ADJ_SCREEN_NAMES_CSV, ProcessStats.ADJ_SCREEN_MOD,
672d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            args[i], sep, error);
673d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    if (csvScreenStats == null) {
674d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        pw.println("Error in \"" + args[i] + "\": " + error[0]);
675d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        dumpHelp(pw);
676d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        return;
677d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    }
678d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    csvSepScreenStats = sep[0];
679d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                } else if ("--csv-mem".equals(arg)) {
680d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    i++;
681d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    if (i >= args.length) {
682d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        pw.println("Error: argument required for --csv-mem");
683d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        dumpHelp(pw);
684d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        return;
685d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    }
686d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    boolean[] sep = new boolean[1];
687d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    String[] error = new String[1];
688d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    csvMemStats = parseStateList(ProcessStats.ADJ_MEM_NAMES_CSV, 1, args[i], sep, error);
689d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    if (csvMemStats == null) {
690d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        pw.println("Error in \"" + args[i] + "\": " + error[0]);
691d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        dumpHelp(pw);
692d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        return;
693d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    }
694d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    csvSepMemStats = sep[0];
695d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                } else if ("--csv-proc".equals(arg)) {
696d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    i++;
697d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    if (i >= args.length) {
698d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        pw.println("Error: argument required for --csv-proc");
699d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        dumpHelp(pw);
700d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        return;
701d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    }
702d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    boolean[] sep = new boolean[1];
703d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    String[] error = new String[1];
704d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    csvProcStats = parseStateList(ProcessStats.STATE_NAMES_CSV, 1, args[i], sep, error);
705d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    if (csvProcStats == null) {
706d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        pw.println("Error in \"" + args[i] + "\": " + error[0]);
707d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        dumpHelp(pw);
708d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        return;
709d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    }
710d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    csvSepProcStats = sep[0];
711d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                } else if ("--details".equals(arg)) {
712d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    dumpDetails = true;
71353459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                } else if ("--full-details".equals(arg)) {
71453459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                    dumpFullDetails = true;
715cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn                } else if ("--hours".equals(arg)) {
716cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn                    i++;
717cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn                    if (i >= args.length) {
718cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn                        pw.println("Error: argument required for --hours");
719cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn                        dumpHelp(pw);
720cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn                        return;
721cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn                    }
722cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn                    try {
723cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn                        aggregateHours = Integer.parseInt(args[i]);
724cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn                    } catch (NumberFormatException e) {
725cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn                        pw.println("Error: --hours argument not an int -- " + args[i]);
726cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn                        dumpHelp(pw);
727cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn                        return;
728cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn                    }
729f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                } else if ("--last".equals(arg)) {
730f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                    i++;
731f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                    if (i >= args.length) {
732f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                        pw.println("Error: argument required for --last");
733f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                        dumpHelp(pw);
734f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                        return;
735f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                    }
736f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                    try {
737f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                        lastIndex = Integer.parseInt(args[i]);
738f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                    } catch (NumberFormatException e) {
739f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                        pw.println("Error: --last argument not an int -- " + args[i]);
740f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                        dumpHelp(pw);
741f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                        return;
742f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                    }
743d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                } else if ("--max".equals(arg)) {
744d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    i++;
745d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    if (i >= args.length) {
746d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        pw.println("Error: argument required for --max");
747d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        dumpHelp(pw);
748d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        return;
749d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    }
750d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    try {
751d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        maxNum = Integer.parseInt(args[i]);
752d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    } catch (NumberFormatException e) {
753d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        pw.println("Error: --max argument not an int -- " + args[i]);
754d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        dumpHelp(pw);
755d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        return;
756d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    }
757164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn                } else if ("--active".equals(arg)) {
758164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn                    activeOnly = true;
759164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn                    currentOnly = true;
760d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                } else if ("--current".equals(arg)) {
761d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    currentOnly = true;
762d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                } else if ("--commit".equals(arg)) {
76350ef0b62f076c509d5edaef5588080d685f063e8Dianne Hackborn                    synchronized (mAm) {
76450ef0b62f076c509d5edaef5588080d685f063e8Dianne Hackborn                        mProcessStats.mFlags |= ProcessStats.FLAG_COMPLETE;
76550ef0b62f076c509d5edaef5588080d685f063e8Dianne Hackborn                        writeStateLocked(true, true);
76650ef0b62f076c509d5edaef5588080d685f063e8Dianne Hackborn                        pw.println("Process stats committed.");
7671a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn                        quit = true;
76850ef0b62f076c509d5edaef5588080d685f063e8Dianne Hackborn                    }
7690d97cd1f6a370b8e371d8b6d88d47e9aaf2bbe32Dianne Hackborn                } else if ("--reset".equals(arg)) {
7700d97cd1f6a370b8e371d8b6d88d47e9aaf2bbe32Dianne Hackborn                    synchronized (mAm) {
7710d97cd1f6a370b8e371d8b6d88d47e9aaf2bbe32Dianne Hackborn                        mProcessStats.resetSafely();
7720d97cd1f6a370b8e371d8b6d88d47e9aaf2bbe32Dianne Hackborn                        pw.println("Process stats reset.");
7731a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn                        quit = true;
7740d97cd1f6a370b8e371d8b6d88d47e9aaf2bbe32Dianne Hackborn                    }
77553459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                } else if ("--clear".equals(arg)) {
77653459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                    synchronized (mAm) {
77753459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                        mProcessStats.resetSafely();
77853459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                        ArrayList<String> files = getCommittedFiles(0, true, true);
77953459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                        if (files != null) {
78053459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                            for (int fi=0; fi<files.size(); fi++) {
78153459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                                (new File(files.get(fi))).delete();
78253459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                            }
78353459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                        }
78453459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                        pw.println("All process stats cleared.");
7851a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn                        quit = true;
78653459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                    }
787d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                } else if ("--write".equals(arg)) {
78850ef0b62f076c509d5edaef5588080d685f063e8Dianne Hackborn                    synchronized (mAm) {
78950ef0b62f076c509d5edaef5588080d685f063e8Dianne Hackborn                        writeStateSyncLocked();
79050ef0b62f076c509d5edaef5588080d685f063e8Dianne Hackborn                        pw.println("Process stats written.");
7911a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn                        quit = true;
79250ef0b62f076c509d5edaef5588080d685f063e8Dianne Hackborn                    }
793d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                } else if ("--read".equals(arg)) {
79450ef0b62f076c509d5edaef5588080d685f063e8Dianne Hackborn                    synchronized (mAm) {
79550ef0b62f076c509d5edaef5588080d685f063e8Dianne Hackborn                        readLocked(mProcessStats, mFile);
79650ef0b62f076c509d5edaef5588080d685f063e8Dianne Hackborn                        pw.println("Process stats read.");
7971a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn                        quit = true;
7981a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn                    }
7991a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn                } else if ("--start-testing".equals(arg)) {
8001a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn                    synchronized (mAm) {
8011a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn                        mAm.setTestPssMode(true);
8021a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn                        pw.println("Started high frequency sampling.");
8031a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn                        quit = true;
8041a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn                    }
8051a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn                } else if ("--stop-testing".equals(arg)) {
8061a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn                    synchronized (mAm) {
8071a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn                        mAm.setTestPssMode(false);
8081a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn                        pw.println("Stopped high frequency sampling.");
8091a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn                        quit = true;
81050ef0b62f076c509d5edaef5588080d685f063e8Dianne Hackborn                    }
811d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                } else if ("-h".equals(arg)) {
812d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    dumpHelp(pw);
813d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    return;
814d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                } else if ("-a".equals(arg)) {
815d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    dumpDetails = true;
816d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    dumpAll = true;
817d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                } else if (arg.length() > 0 && arg.charAt(0) == '-'){
818d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    pw.println("Unknown option: " + arg);
819d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    dumpHelp(pw);
820d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    return;
821d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                } else {
822d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    // Not an option, last argument must be a package name.
823daa0d5c9296515fe05cae65926a66dee609f382aDianne Hackborn                    reqPackage = arg;
824daa0d5c9296515fe05cae65926a66dee609f382aDianne Hackborn                    // Include all details, since we know we are only going to
825daa0d5c9296515fe05cae65926a66dee609f382aDianne Hackborn                    // be dumping a smaller set of data.  In fact only the details
826ab4a81b3c625e33d04ae8070fcce6b6baee6522cDianne Hackborn                    // contain per-package data, so this is needed to be able
827daa0d5c9296515fe05cae65926a66dee609f382aDianne Hackborn                    // to dump anything at all when filtering by package.
828daa0d5c9296515fe05cae65926a66dee609f382aDianne Hackborn                    dumpDetails = true;
829d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                }
830d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
831d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        }
832d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
8331a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn        if (quit) {
8341a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn            return;
8351a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn        }
8361a4b5a4f02e7d8ff8ff645377d97e6062d36aeaaDianne Hackborn
837d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        if (isCsv) {
838d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            pw.print("Processes running summed over");
839d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            if (!csvSepScreenStats) {
840d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                for (int i=0; i<csvScreenStats.length; i++) {
841d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    pw.print(" ");
842d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    ProcessStats.printScreenLabelCsv(pw, csvScreenStats[i]);
843d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                }
844d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
845d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            if (!csvSepMemStats) {
846d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                for (int i=0; i<csvMemStats.length; i++) {
847d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    pw.print(" ");
848d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    ProcessStats.printMemLabelCsv(pw, csvMemStats[i]);
849d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                }
850d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
851d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            if (!csvSepProcStats) {
852d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                for (int i=0; i<csvProcStats.length; i++) {
853d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    pw.print(" ");
854d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    pw.print(ProcessStats.STATE_NAMES_CSV[csvProcStats[i]]);
855d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                }
856d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
857d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            pw.println();
8588a0de58ece89c467c8e7415097d193e5f8db9db8Dianne Hackborn            synchronized (mAm) {
859d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                dumpFilteredProcessesCsvLocked(pw, null,
860d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        csvSepScreenStats, csvScreenStats, csvSepMemStats, csvMemStats,
861d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        csvSepProcStats, csvProcStats, now, reqPackage);
862d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                /*
863d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                dumpFilteredProcessesCsvLocked(pw, "Processes running while critical mem:",
864d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        false, new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
865d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        true, new int[] {ADJ_MEM_FACTOR_CRITICAL},
866d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        true, new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
867d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME,
868d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                STATE_PREVIOUS, STATE_CACHED},
869d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        now, reqPackage);
870d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                dumpFilteredProcessesCsvLocked(pw, "Processes running over all mem:",
871d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        false, new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
872d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        false, new int[] {ADJ_MEM_FACTOR_CRITICAL, ADJ_MEM_FACTOR_LOW,
873d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                ADJ_MEM_FACTOR_MODERATE, ADJ_MEM_FACTOR_MODERATE},
874d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        true, new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
875d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME,
876d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                STATE_PREVIOUS, STATE_CACHED},
877d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        now, reqPackage);
878d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                */
879d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
880d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            return;
881cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn        } else if (aggregateHours != 0) {
882daa0d5c9296515fe05cae65926a66dee609f382aDianne Hackborn            pw.print("AGGREGATED OVER LAST "); pw.print(aggregateHours); pw.println(" HOURS:");
883237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn            dumpAggregatedStats(pw, aggregateHours, now, reqPackage, isCompact,
884237cefbcee8721e3268ba778297a0ad48e67f079Dianne Hackborn                    dumpDetails, dumpFullDetails, dumpAll, activeOnly);
88553459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn            return;
886f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn        } else if (lastIndex > 0) {
887f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn            pw.print("LAST STATS AT INDEX "); pw.print(lastIndex); pw.println(":");
888f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn            ArrayList<String> files = getCommittedFiles(0, false, true);
889f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn            if (lastIndex >= files.size()) {
890f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                pw.print("Only have "); pw.print(files.size()); pw.println(" data sets");
891f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                return;
892f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn            }
893f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn            AtomicFile file = new AtomicFile(new File(files.get(lastIndex)));
894f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn            ProcessStats processStats = new ProcessStats(false);
895f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn            readLocked(processStats, file);
896f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn            if (processStats.mReadError != null) {
897f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                if (isCheckin || isCompact) pw.print("err,");
898f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                pw.print("Failure reading "); pw.print(files.get(lastIndex));
899f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                pw.print("; "); pw.println(processStats.mReadError);
900f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                return;
901f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn            }
902f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn            String fileStr = file.getBaseFile().getPath();
903f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn            boolean checkedIn = fileStr.endsWith(STATE_FILE_CHECKIN_SUFFIX);
904f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn            if (isCheckin || isCompact) {
905f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                // Don't really need to lock because we uniquely own this object.
906f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                processStats.dumpCheckinLocked(pw, reqPackage);
907f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn            } else {
908f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                pw.print("COMMITTED STATS FROM ");
909f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                pw.print(processStats.mTimePeriodStartClockStr);
910f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                if (checkedIn) pw.print(" (checked in)");
911f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                pw.println(":");
912f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                if (dumpDetails || dumpFullDetails) {
913f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                    processStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpAll,
914f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                            activeOnly);
915f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                    if (dumpAll) {
916f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                        pw.print("  mFile="); pw.println(mFile.getBaseFile());
917f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                    }
918f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                } else {
919f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                    processStats.dumpSummaryLocked(pw, reqPackage, now, activeOnly);
920f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                }
921f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn            }
922f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn            return;
923d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        }
924d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn
925d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        boolean sepNeeded = false;
926daa0d5c9296515fe05cae65926a66dee609f382aDianne Hackborn        if (dumpAll || isCheckin) {
927d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            mWriteLock.lock();
928d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            try {
92953459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                ArrayList<String> files = getCommittedFiles(0, false, !isCheckin);
930d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                if (files != null) {
931d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    int start = isCheckin ? 0 : (files.size() - maxNum);
932d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    if (start < 0) {
933d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        start = 0;
934d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    }
935d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    for (int i=start; i<files.size(); i++) {
936d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        if (DEBUG) Slog.d(TAG, "Retrieving state: " + files.get(i));
937d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        try {
938d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            AtomicFile file = new AtomicFile(new File(files.get(i)));
939d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            ProcessStats processStats = new ProcessStats(false);
940d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            readLocked(processStats, file);
941d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            if (processStats.mReadError != null) {
942d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                if (isCheckin || isCompact) pw.print("err,");
943d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                pw.print("Failure reading "); pw.print(files.get(i));
944d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                pw.print("; "); pw.println(processStats.mReadError);
945d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                if (DEBUG) Slog.d(TAG, "Deleting state: " + files.get(i));
946d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                (new File(files.get(i))).delete();
947d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                continue;
948d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            }
949d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            String fileStr = file.getBaseFile().getPath();
950d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            boolean checkedIn = fileStr.endsWith(STATE_FILE_CHECKIN_SUFFIX);
951d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            if (isCheckin || isCompact) {
952d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                // Don't really need to lock because we uniquely own this object.
953d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                processStats.dumpCheckinLocked(pw, reqPackage);
954d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            } else {
955d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                if (sepNeeded) {
956d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                    pw.println();
957d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                } else {
958d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                    sepNeeded = true;
959d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                }
960d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                pw.print("COMMITTED STATS FROM ");
961d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                pw.print(processStats.mTimePeriodStartClockStr);
962d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                if (checkedIn) pw.print(" (checked in)");
963d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                pw.println(":");
964d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                // Don't really need to lock because we uniquely own this object.
965ae36b236d2b8d040f142bee169742da2f392efaaDianne Hackborn                                // Always dump summary here, dumping all details is just too
966ae36b236d2b8d040f142bee169742da2f392efaaDianne Hackborn                                // much crud.
96753459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                                if (dumpFullDetails) {
968f7097a5b697fedb6976774e55a51471405a23c0eDianne Hackborn                                    processStats.dumpLocked(pw, reqPackage, now, false, false,
969164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn                                            activeOnly);
97053459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                                } else {
971164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn                                    processStats.dumpSummaryLocked(pw, reqPackage, now, activeOnly);
97253459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                                }
973d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            }
974d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            if (isCheckin) {
975d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                // Rename file suffix to mark that it has checked in.
976d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                file.getBaseFile().renameTo(new File(
977d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                                        fileStr + STATE_FILE_CHECKIN_SUFFIX));
978d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            }
979d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        } catch (Throwable e) {
980d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            pw.print("**** FAILURE DUMPING STATE: "); pw.println(files.get(i));
981d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            e.printStackTrace(pw);
982d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        }
983d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    }
984d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                }
985d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            } finally {
986d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                mWriteLock.unlock();
987d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
988d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        }
989d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        if (!isCheckin) {
9908a0de58ece89c467c8e7415097d193e5f8db9db8Dianne Hackborn            synchronized (mAm) {
991d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                if (isCompact) {
992d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    mProcessStats.dumpCheckinLocked(pw, reqPackage);
993d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                } else {
994d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    if (sepNeeded) {
995d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        pw.println();
996d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    }
997daa0d5c9296515fe05cae65926a66dee609f382aDianne Hackborn                    pw.println("CURRENT STATS:");
99853459a7020dbcd036e2d3418e35ebb96fadc29e3Dianne Hackborn                    if (dumpDetails || dumpFullDetails) {
999164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn                        mProcessStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpAll,
1000164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn                                activeOnly);
1001d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        if (dumpAll) {
1002d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                            pw.print("  mFile="); pw.println(mFile.getBaseFile());
1003d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                        }
1004d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    } else {
1005164371fb759bad6854570af0fca60d9a01e17235Dianne Hackborn                        mProcessStats.dumpSummaryLocked(pw, reqPackage, now, activeOnly);
1006d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                    }
1007d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    sepNeeded = true;
1008d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn                }
1009d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn            }
1010d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn            if (!currentOnly) {
1011d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                if (sepNeeded) {
1012d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                    pw.println();
1013d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                }
1014d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                pw.println("AGGREGATED OVER LAST 24 HOURS:");
1015d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                dumpAggregatedStats(pw, 24, now, reqPackage, isCompact,
1016d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        dumpDetails, dumpFullDetails, dumpAll, activeOnly);
1017d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                pw.println();
1018d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                pw.println("AGGREGATED OVER LAST 3 HOURS:");
1019d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                dumpAggregatedStats(pw, 3, now, reqPackage, isCompact,
1020d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn                        dumpDetails, dumpFullDetails, dumpAll, activeOnly);
1021d052a9416ae3f7e42fc1e7de0740021df385ee48Dianne Hackborn            }
1022d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn        }
1023d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn    }
1024d2932243e3313b59e7538641731aa98852bc5ac7Dianne Hackborn}
1025