14eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato/*
24eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Copyright (C) 2013 The Android Open Source Project
34eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato *
44eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
54eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * you may not use this file except in compliance with the License.
64eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * You may obtain a copy of the License at
74eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato *
84eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
94eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato *
104eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Unless required by applicable law or agreed to in writing, software
114eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
124eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * See the License for the specific language governing permissions and
144eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * limitations under the License.
154eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */
164eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
174eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratopackage com.android.internal.app.procstats;
184eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
194eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
204eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport android.os.Parcel;
214eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport android.os.Parcelable;
224eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport android.os.SystemClock;
234eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport android.os.SystemProperties;
244eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport android.os.UserHandle;
254eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport android.text.format.DateFormat;
264eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport android.util.ArrayMap;
274eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport android.util.ArraySet;
284eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport android.util.DebugUtils;
294eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport android.util.Log;
304eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport android.util.Slog;
314eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport android.util.SparseArray;
324eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport android.util.TimeUtils;
334eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
344eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport com.android.internal.app.procstats.ProcessStats;
354eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport static com.android.internal.app.procstats.ProcessStats.STATE_NOTHING;
364eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
374eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport java.io.IOException;
384eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport java.io.InputStream;
394eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport java.io.PrintWriter;
404eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport java.util.ArrayList;
414eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport java.util.Arrays;
424eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport java.util.Collections;
434eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport java.util.Comparator;
444eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport java.util.Objects;
454eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
464eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratopublic final class ServiceState {
474eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private static final String TAG = "ProcessStats";
484eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private static final boolean DEBUG = false;
494eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
504eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public static final int SERVICE_RUN = 0;
514eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public static final int SERVICE_STARTED = 1;
524eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public static final int SERVICE_BOUND = 2;
534eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public static final int SERVICE_EXEC = 3;
544eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public static final int SERVICE_COUNT = 4;
554eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
564eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private final String mPackage;
574eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private final String mProcessName;
584eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private final String mName;
594eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private final DurationsTable mDurations;
604eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
614eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private ProcessState mProc;
624eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private Object mOwner;
634eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
644eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private int mRunCount;
654eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private int mRunState = STATE_NOTHING;
664eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private long mRunStartTime;
674eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
684eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private boolean mStarted;
694eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private boolean mRestarting;
704eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private int mStartedCount;
714eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private int mStartedState = STATE_NOTHING;
724eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private long mStartedStartTime;
734eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
744eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private int mBoundCount;
754eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private int mBoundState = STATE_NOTHING;
764eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private long mBoundStartTime;
774eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
784eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private int mExecCount;
794eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private int mExecState = STATE_NOTHING;
804eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private long mExecStartTime;
814eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
824eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public ServiceState(ProcessStats processStats, String pkg, String name,
834eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            String processName, ProcessState proc) {
844eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mPackage = pkg;
854eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mName = name;
864eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mProcessName = processName;
874eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mProc = proc;
884eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mDurations = new DurationsTable(processStats.mTableData);
894eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
904eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
914eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public String getPackage() {
924eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        return mPackage;
934eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
944eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
954eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public String getProcessName() {
964eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        return mProcessName;
974eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
984eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
994eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public String getName() {
1004eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        return mName;
1014eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
1024eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
1034eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public ProcessState getProcess() {
1044eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        return mProc;
1054eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
1064eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
1074eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public void setProcess(ProcessState proc) {
1084eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mProc = proc;
1094eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
1104eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
1114eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public void setMemFactor(int memFactor, long now) {
1124eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (isRestarting()) {
1134eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            setRestarting(true, memFactor, now);
1144eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        } else if (isInUse()) {
1154eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            if (mStartedState != ProcessStats.STATE_NOTHING) {
1164eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                setStarted(true, memFactor, now);
1174eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            }
1184eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            if (mBoundState != ProcessStats.STATE_NOTHING) {
1194eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                setBound(true, memFactor, now);
1204eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            }
1214eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            if (mExecState != ProcessStats.STATE_NOTHING) {
1224eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                setExecuting(true, memFactor, now);
1234eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            }
1244eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
1254eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
1264eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
1274eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public void applyNewOwner(Object newOwner) {
1284eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (mOwner != newOwner) {
1294eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            if (mOwner == null) {
1304eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                mOwner = newOwner;
1314eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                mProc.incActiveServices(mName);
1324eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            } else {
1334eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                // There was already an old owner, reset this object for its
1344eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                // new owner.
1354eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                mOwner = newOwner;
1364eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                if (mStarted || mBoundState != STATE_NOTHING || mExecState != STATE_NOTHING) {
1374eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    long now = SystemClock.uptimeMillis();
1384eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    if (mStarted) {
1394eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        if (DEBUG) Slog.d(TAG, "Service has new owner " + newOwner
1404eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                                + " from " + mOwner + " while started: pkg="
1414eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                                + mPackage + " service=" + mName + " proc=" + mProc);
1424eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        setStarted(false, 0, now);
1434eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    }
1444eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    if (mBoundState != STATE_NOTHING) {
1454eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        if (DEBUG) Slog.d(TAG, "Service has new owner " + newOwner
1464eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                                + " from " + mOwner + " while bound: pkg="
1474eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                                + mPackage + " service=" + mName + " proc=" + mProc);
1484eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        setBound(false, 0, now);
1494eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    }
1504eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    if (mExecState != STATE_NOTHING) {
1514eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        if (DEBUG) Slog.d(TAG, "Service has new owner " + newOwner
1524eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                                + " from " + mOwner + " while executing: pkg="
1534eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                                + mPackage + " service=" + mName + " proc=" + mProc);
1544eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        setExecuting(false, 0, now);
1554eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    }
1564eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                }
1574eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            }
1584eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
1594eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
1604eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
1614eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public void clearCurrentOwner(Object owner, boolean silently) {
1624eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (mOwner == owner) {
1634eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            mProc.decActiveServices(mName);
1644eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            if (mStarted || mBoundState != STATE_NOTHING || mExecState != STATE_NOTHING) {
1654eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                long now = SystemClock.uptimeMillis();
1664eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                if (mStarted) {
1674eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    if (!silently) {
1684eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        Slog.wtfStack(TAG, "Service owner " + owner
1694eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                                + " cleared while started: pkg=" + mPackage + " service="
1704eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                                + mName + " proc=" + mProc);
1714eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    }
1724eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    setStarted(false, 0, now);
1734eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                }
1744eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                if (mBoundState != STATE_NOTHING) {
1754eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    if (!silently) {
1764eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        Slog.wtfStack(TAG, "Service owner " + owner
1774eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                                + " cleared while bound: pkg=" + mPackage + " service="
1784eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                                + mName + " proc=" + mProc);
1794eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    }
1804eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    setBound(false, 0, now);
1814eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                }
1824eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                if (mExecState != STATE_NOTHING) {
1834eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    if (!silently) {
1844eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        Slog.wtfStack(TAG, "Service owner " + owner
1854eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                                + " cleared while exec: pkg=" + mPackage + " service="
1864eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                                + mName + " proc=" + mProc);
1874eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    }
1884eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    setExecuting(false, 0, now);
1894eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                }
1904eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            }
1914eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            mOwner = null;
1924eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
1934eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
1944eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
1954eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public boolean isInUse() {
1964eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        return mOwner != null || mRestarting;
1974eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
1984eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
1994eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public boolean isRestarting() {
2004eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        return mRestarting;
2014eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
2024eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
2034eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public void add(ServiceState other) {
2044eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mDurations.addDurations(other.mDurations);
2054eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mRunCount += other.mRunCount;
2064eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mStartedCount += other.mStartedCount;
2074eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mBoundCount += other.mBoundCount;
2084eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mExecCount += other.mExecCount;
2094eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
2104eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
2114eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public void resetSafely(long now) {
2124eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mDurations.resetTable();
2134eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mRunCount = mRunState != STATE_NOTHING ? 1 : 0;
2144eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mStartedCount = mStartedState != STATE_NOTHING ? 1 : 0;
2154eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mBoundCount = mBoundState != STATE_NOTHING ? 1 : 0;
2164eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mExecCount = mExecState != STATE_NOTHING ? 1 : 0;
2174eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mRunStartTime = mStartedStartTime = mBoundStartTime = mExecStartTime = now;
2184eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
2194eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
2204eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public void writeToParcel(Parcel out, long now) {
2214eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mDurations.writeToParcel(out);
2224eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        out.writeInt(mRunCount);
2234eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        out.writeInt(mStartedCount);
2244eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        out.writeInt(mBoundCount);
2254eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        out.writeInt(mExecCount);
2264eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
2274eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
2284eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public boolean readFromParcel(Parcel in) {
2294eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (!mDurations.readFromParcel(in)) {
2304eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            return false;
2314eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
2324eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mRunCount = in.readInt();
2334eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mStartedCount = in.readInt();
2344eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mBoundCount = in.readInt();
2354eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mExecCount = in.readInt();
2364eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        return true;
2374eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
2384eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
2394eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public void commitStateTime(long now) {
2404eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (mRunState != STATE_NOTHING) {
2414eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            mDurations.addDuration(SERVICE_RUN + (mRunState*SERVICE_COUNT),
2424eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    now - mRunStartTime);
2434eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            mRunStartTime = now;
2444eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
2454eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (mStartedState != STATE_NOTHING) {
2464eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            mDurations.addDuration(SERVICE_STARTED + (mStartedState*SERVICE_COUNT),
2474eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    now - mStartedStartTime);
2484eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            mStartedStartTime = now;
2494eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
2504eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (mBoundState != STATE_NOTHING) {
2514eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            mDurations.addDuration(SERVICE_BOUND + (mBoundState*SERVICE_COUNT),
2524eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    now - mBoundStartTime);
2534eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            mBoundStartTime = now;
2544eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
2554eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (mExecState != STATE_NOTHING) {
2564eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            mDurations.addDuration(SERVICE_EXEC + (mExecState*SERVICE_COUNT),
2574eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    now - mExecStartTime);
2584eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            mExecStartTime = now;
2594eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
2604eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
2614eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
2624eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private void updateRunning(int memFactor, long now) {
2634eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        final int state = (mStartedState != STATE_NOTHING || mBoundState != STATE_NOTHING
2644eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                || mExecState != STATE_NOTHING) ? memFactor : STATE_NOTHING;
2654eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (mRunState != state) {
2664eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            if (mRunState != STATE_NOTHING) {
2674eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                mDurations.addDuration(SERVICE_RUN + (mRunState*SERVICE_COUNT),
2684eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        now - mRunStartTime);
2694eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            } else if (state != STATE_NOTHING) {
2704eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                mRunCount++;
2714eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            }
2724eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            mRunState = state;
2734eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            mRunStartTime = now;
2744eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
2754eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
2764eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
2774eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public void setStarted(boolean started, int memFactor, long now) {
2784eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (mOwner == null) {
2794eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            Slog.wtf(TAG, "Starting service " + this + " without owner");
2804eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
2814eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mStarted = started;
2824eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        updateStartedState(memFactor, now);
2834eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
2844eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
2854eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public void setRestarting(boolean restarting, int memFactor, long now) {
2864eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        mRestarting = restarting;
2874eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        updateStartedState(memFactor, now);
2884eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
2894eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
2904eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public void updateStartedState(int memFactor, long now) {
2914eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        final boolean wasStarted = mStartedState != STATE_NOTHING;
2924eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        final boolean started = mStarted || mRestarting;
2934eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        final int state = started ? memFactor : STATE_NOTHING;
2944eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (mStartedState != state) {
2954eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            if (mStartedState != STATE_NOTHING) {
2964eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                mDurations.addDuration(SERVICE_STARTED + (mStartedState*SERVICE_COUNT),
2974eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        now - mStartedStartTime);
2984eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            } else if (started) {
2994eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                mStartedCount++;
3004eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            }
3014eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            mStartedState = state;
3024eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            mStartedStartTime = now;
3034eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            mProc = mProc.pullFixedProc(mPackage);
3044eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            if (wasStarted != started) {
3054eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                if (started) {
3064eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    mProc.incStartedServices(memFactor, now, mName);
3074eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                } else {
3084eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    mProc.decStartedServices(memFactor, now, mName);
3094eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                }
3104eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            }
3114eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            updateRunning(memFactor, now);
3124eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
3134eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
3144eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
3154eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public void setBound(boolean bound, int memFactor, long now) {
3164eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (mOwner == null) {
3174eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            Slog.wtf(TAG, "Binding service " + this + " without owner");
3184eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
3194eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        final int state = bound ? memFactor : STATE_NOTHING;
3204eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (mBoundState != state) {
3214eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            if (mBoundState != STATE_NOTHING) {
3224eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                mDurations.addDuration(SERVICE_BOUND + (mBoundState*SERVICE_COUNT),
3234eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        now - mBoundStartTime);
3244eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            } else if (bound) {
3254eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                mBoundCount++;
3264eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            }
3274eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            mBoundState = state;
3284eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            mBoundStartTime = now;
3294eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            updateRunning(memFactor, now);
3304eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
3314eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
3324eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
3334eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public void setExecuting(boolean executing, int memFactor, long now) {
3344eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (mOwner == null) {
3354eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            Slog.wtf(TAG, "Executing service " + this + " without owner");
3364eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
3374eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        final int state = executing ? memFactor : STATE_NOTHING;
3384eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (mExecState != state) {
3394eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            if (mExecState != STATE_NOTHING) {
3404eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                mDurations.addDuration(SERVICE_EXEC + (mExecState*SERVICE_COUNT),
3414eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        now - mExecStartTime);
3424eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            } else if (executing) {
3434eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                mExecCount++;
3444eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            }
3454eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            mExecState = state;
3464eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            mExecStartTime = now;
3474eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            updateRunning(memFactor, now);
3484eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
3494eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
3504eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
3514eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public long getDuration(int opType, int curState, long startTime, int memFactor,
3524eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            long now) {
3534eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        int state = opType + (memFactor*SERVICE_COUNT);
3544eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        long time = mDurations.getValueForId((byte)state);
3554eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (curState == memFactor) {
3564eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            time += now - startTime;
3574eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
3584eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        return time;
3594eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
3604eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
3614eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public void dumpStats(PrintWriter pw, String prefix, String prefixInner, String headerPrefix,
3624eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            long now, long totalTime, boolean dumpSummary, boolean dumpAll) {
3634eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        dumpStats(pw, prefix, prefixInner, headerPrefix, "Running",
3644eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                mRunCount, ServiceState.SERVICE_RUN, mRunState,
3654eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                mRunStartTime, now, totalTime, !dumpSummary || dumpAll);
3664eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        dumpStats(pw, prefix, prefixInner, headerPrefix, "Started",
3674eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                mStartedCount, ServiceState.SERVICE_STARTED, mStartedState,
3684eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                mStartedStartTime, now, totalTime, !dumpSummary || dumpAll);
3694eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        dumpStats(pw, prefix, prefixInner, headerPrefix, "Bound",
3704eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                mBoundCount, ServiceState.SERVICE_BOUND, mBoundState,
3714eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                mBoundStartTime, now, totalTime, !dumpSummary || dumpAll);
3724eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        dumpStats(pw, prefix, prefixInner, headerPrefix, "Executing",
3734eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                mExecCount, ServiceState.SERVICE_EXEC, mExecState,
3744eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                mExecStartTime, now, totalTime, !dumpSummary || dumpAll);
3754eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (dumpAll) {
3764eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            if (mOwner != null) {
3774eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                pw.print("        mOwner="); pw.println(mOwner);
3784eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            }
3794eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            if (mStarted || mRestarting) {
3804eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                pw.print("        mStarted="); pw.print(mStarted);
3814eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                pw.print(" mRestarting="); pw.println(mRestarting);
3824eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            }
3834eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
3844eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
3854eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
3864eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private void dumpStats(PrintWriter pw, String prefix, String prefixInner,
3874eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            String headerPrefix, String header,
3884eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            int count, int serviceType, int state, long startTime, long now, long totalTime,
3894eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            boolean dumpAll) {
3904eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (count != 0) {
3914eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            if (dumpAll) {
3924eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                pw.print(prefix); pw.print(header);
3934eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                pw.print(" op count "); pw.print(count); pw.println(":");
3944eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                dumpTime(pw, prefixInner, serviceType, state, startTime, now);
3954eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            } else {
3964eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                long myTime = dumpTime(null, null, serviceType, state, startTime, now);
3974eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                pw.print(prefix); pw.print(headerPrefix); pw.print(header);
3984eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                pw.print(" count "); pw.print(count);
3994eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                pw.print(" / time ");
4004eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                DumpUtils.printPercent(pw, (double)myTime/(double)totalTime);
4014eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                pw.println();
4024eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            }
4034eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
4044eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
4054eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
4064eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public long dumpTime(PrintWriter pw, String prefix,
4074eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            int serviceType, int curState, long curStartTime, long now) {
4084eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        long totalTime = 0;
4094eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        int printedScreen = -1;
4104eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        for (int iscreen=0; iscreen<ProcessStats.ADJ_COUNT; iscreen+=ProcessStats.ADJ_SCREEN_MOD) {
4114eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            int printedMem = -1;
4124eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            for (int imem=0; imem<ProcessStats.ADJ_MEM_FACTOR_COUNT; imem++) {
4134eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                int state = imem+iscreen;
4144eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                long time = getDuration(serviceType, curState, curStartTime, state, now);
4154eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                String running = "";
4164eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                if (curState == state && pw != null) {
4174eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    running = " (running)";
4184eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                }
4194eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                if (time != 0) {
4204eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    if (pw != null) {
4214eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        pw.print(prefix);
4224eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        DumpUtils.printScreenLabel(pw, printedScreen != iscreen
4234eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                                ? iscreen : STATE_NOTHING);
4244eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        printedScreen = iscreen;
4254eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        DumpUtils.printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING,
4264eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                                (char)0);
4274eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        printedMem = imem;
4284eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        pw.print(": ");
4294eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                        TimeUtils.formatDuration(time, pw); pw.println(running);
4304eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    }
4314eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                    totalTime += time;
4324eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                }
4334eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            }
4344eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
4354eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (totalTime != 0 && pw != null) {
4364eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            pw.print(prefix);
4374eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            pw.print("    TOTAL: ");
4384eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            TimeUtils.formatDuration(totalTime, pw);
4394eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            pw.println();
4404eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
4414eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        return totalTime;
4424eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
4434eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
4444eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public void dumpTimesCheckin(PrintWriter pw, String pkgName, int uid, int vers,
4454eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            String serviceName, long now) {
4464eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        dumpTimeCheckin(pw, "pkgsvc-run", pkgName, uid, vers, serviceName,
4474eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                ServiceState.SERVICE_RUN, mRunCount, mRunState, mRunStartTime, now);
4484eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        dumpTimeCheckin(pw, "pkgsvc-start", pkgName, uid, vers, serviceName,
4494eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                ServiceState.SERVICE_STARTED, mStartedCount, mStartedState, mStartedStartTime, now);
4504eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        dumpTimeCheckin(pw, "pkgsvc-bound", pkgName, uid, vers, serviceName,
4514eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                ServiceState.SERVICE_BOUND, mBoundCount, mBoundState, mBoundStartTime, now);
4524eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        dumpTimeCheckin(pw, "pkgsvc-exec", pkgName, uid, vers, serviceName,
4534eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                ServiceState.SERVICE_EXEC, mExecCount, mExecState, mExecStartTime, now);
4544eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
4554eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
4564eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    private void dumpTimeCheckin(PrintWriter pw, String label, String packageName,
4574eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            int uid, int vers, String serviceName, int serviceType, int opCount,
4584eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            int curState, long curStartTime, long now) {
4594eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (opCount <= 0) {
4604eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            return;
4614eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
4624eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        pw.print(label);
4634eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        pw.print(",");
4644eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        pw.print(packageName);
4654eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        pw.print(",");
4664eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        pw.print(uid);
4674eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        pw.print(",");
4684eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        pw.print(vers);
4694eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        pw.print(",");
4704eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        pw.print(serviceName);
4714eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        pw.print(",");
4724eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        pw.print(opCount);
4734eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        boolean didCurState = false;
4744eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        final int N = mDurations.getKeyCount();
4754eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        for (int i=0; i<N; i++) {
4764eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            final int key = mDurations.getKeyAt(i);
4774eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            long time = mDurations.getValue(key);
4784eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            int type = SparseMappingTable.getIdFromKey(key);
4794eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            int memFactor = type / ServiceState.SERVICE_COUNT;
4804eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            type %= ServiceState.SERVICE_COUNT;
4814eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            if (type != serviceType) {
4824eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                continue;
4834eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            }
4844eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            if (curState == memFactor) {
4854eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                didCurState = true;
4864eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                time += now - curStartTime;
4874eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            }
4884eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            DumpUtils.printAdjTagAndValue(pw, memFactor, time);
4894eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
4904eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        if (!didCurState && curState != STATE_NOTHING) {
4914eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato            DumpUtils.printAdjTagAndValue(pw, curState, now - curStartTime);
4924eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        }
4934eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        pw.println();
4944eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
4954eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
4964eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato
4974eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    public String toString() {
4984eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato        return "ServiceState{" + Integer.toHexString(System.identityHashCode(this))
4994eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                + " " + mName + " pkg=" + mPackage + " proc="
5004eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato                + Integer.toHexString(System.identityHashCode(this)) + "}";
5014eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato    }
5024eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato}
503