19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006-2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.internal.os;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
191059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkeyimport static android.net.NetworkStats.IFACE_ALL;
201059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkeyimport static android.net.NetworkStats.UID_ALL;
211059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkeyimport static android.text.format.DateUtils.SECOND_IN_MILLIS;
22418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkeyimport static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
231afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackborn
243f03496ad97b5f60ab432bca2d17a3e07b4ade47Jaikumar Ganeshimport android.bluetooth.BluetoothDevice;
253f7e35c2c7d3d7f08f50c1d93cd16b1f49354cccAmith Yamasaniimport android.bluetooth.BluetoothHeadset;
261059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkeyimport android.content.res.Resources;
271059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkeyimport android.net.ConnectivityManager;
281059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkeyimport android.net.NetworkStats;
296b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackbornimport android.os.BatteryManager;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.BatteryStats;
318bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackbornimport android.os.FileUtils;
320d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackbornimport android.os.Handler;
330d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackbornimport android.os.Message;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFormatException;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcelable;
37c64edde69d18498fb2954f71a546357b07ab996aEvan Millarimport android.os.Process;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock;
39418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkeyimport android.os.SystemProperties;
407e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackbornimport android.os.WorkSource;
41f37447bad3773b62176baa837908daf6edb44273Amith Yamasaniimport android.telephony.ServiceState;
42e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Savilleimport android.telephony.SignalStrength;
43627bba736d022c39696b7c582a6af5592d2b8c33Dianne Hackbornimport android.telephony.TelephonyManager;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
450ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackbornimport android.util.LogWriter;
461d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackbornimport android.util.PrintWriterPrinter;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Printer;
481afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackbornimport android.util.Slog;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.SparseArray;
50ae3844527a305cef8bbd1c895b79be45a6c51dbcDianne Hackbornimport android.util.TimeUtils;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
521059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkeyimport com.android.internal.R;
531059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkeyimport com.android.internal.net.NetworkStatsFactory;
541059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkeyimport com.android.internal.util.JournaledFile;
551059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkeyimport com.google.android.collect.Sets;
561059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey
573718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasaniimport java.io.BufferedReader;
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File;
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileOutputStream;
613718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasaniimport java.io.FileReader;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException;
631d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackbornimport java.io.PrintWriter;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap;
661059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkeyimport java.util.HashSet;
67c64edde69d18498fb2954f71a546357b07ab996aEvan Millarimport java.util.Iterator;
685a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganeshimport java.util.List;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Map;
704cee725b1fd3958d850fc83214797f76d5f6b468Christopher Tateimport java.util.concurrent.atomic.AtomicInteger;
71ce2ef766cad1bb186ea522f76c4ac6a8bb3dfa87Dianne Hackbornimport java.util.concurrent.locks.ReentrantLock;
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All information we are collecting about things that can happen that impact
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * battery life.  All times are represented in microseconds except where indicated
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise.
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic final class BatteryStatsImpl extends BatteryStats {
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "BatteryStatsImpl";
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final boolean DEBUG = false;
8132907cfb38bda2d3c052cf5139c5b592678fedbbDianne Hackborn    private static final boolean DEBUG_HISTORY = false;
82e8c88e6f764a77d94b0051ea169a82a61fcc0d0eDianne Hackborn    private static final boolean USE_OLD_HISTORY = false;   // for debugging.
835a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
841059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey    // TODO: remove "tcp" from network methods, since we measure total stats.
851059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
875a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh    private static final int MAGIC = 0xBA757475; // 'BATSTATS'
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Current on-disk Parcel version
90df693de4fe12f081555b449e2726e205fbd86572Jeff Brown    private static final int VERSION = 62 + (USE_OLD_HISTORY ? 1000 : 0);
91e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani
926b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn    // Maximum number of items we will record in the history.
937e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    private static final int MAX_HISTORY_ITEMS = 2000;
945a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
95f47d8f272c13f0fd264d5a71bcff1c18da10d854Dianne Hackborn    // No, really, THIS is the maximum number of items we will record in the history.
96f47d8f272c13f0fd264d5a71bcff1c18da10d854Dianne Hackborn    private static final int MAX_MAX_HISTORY_ITEMS = 3000;
97f47d8f272c13f0fd264d5a71bcff1c18da10d854Dianne Hackborn
989e0f5d9a63ba88c2bf69df0557f8c9696db370c4Dianne Hackborn    // The maximum number of names wakelocks we will keep track of
999e0f5d9a63ba88c2bf69df0557f8c9696db370c4Dianne Hackborn    // per uid; once the limit is reached, we batch the remaining wakelocks
1009e0f5d9a63ba88c2bf69df0557f8c9696db370c4Dianne Hackborn    // in to one common name.
1017e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    private static final int MAX_WAKELOCKS_PER_UID = 30;
1025a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
103c24ab866b0d46685f6ddd340b9c84375cf8d6831Dianne Hackborn    // The system process gets more.  It is special.  Oh so special.
104c24ab866b0d46685f6ddd340b9c84375cf8d6831Dianne Hackborn    // With, you know, special needs.  Like this.
105c24ab866b0d46685f6ddd340b9c84375cf8d6831Dianne Hackborn    private static final int MAX_WAKELOCKS_PER_UID_IN_SYSTEM = 50;
106c24ab866b0d46685f6ddd340b9c84375cf8d6831Dianne Hackborn
1079e0f5d9a63ba88c2bf69df0557f8c9696db370c4Dianne Hackborn    private static final String BATCHED_WAKELOCK_NAME = "*overflow*";
1085a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
109e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani    private static int sNumSpeedSteps;
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1111afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackborn    private final JournaledFile mFile;
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1130d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn    static final int MSG_UPDATE_WAKELOCKS = 1;
1140d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn    static final int MSG_REPORT_POWER_CHANGE = 2;
115287952c35e148811c106bc0f5036eabf20f71562Dianne Hackborn    static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
1160d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn
1170d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn    public interface BatteryCallback {
1180d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn        public void batteryNeedsCpuUpdate();
1190d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn        public void batteryPowerChanged(boolean onBattery);
1200d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn    }
1210d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn
1220d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn    final class MyHandler extends Handler {
1230d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn        @Override
1240d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn        public void handleMessage(Message msg) {
1250d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn            BatteryCallback cb = mCallback;
1260d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn            switch (msg.what) {
1270d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn                case MSG_UPDATE_WAKELOCKS:
1280d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn                    if (cb != null) {
1290d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn                        cb.batteryNeedsCpuUpdate();
1300d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn                    }
1310d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn                    break;
1320d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn                case MSG_REPORT_POWER_CHANGE:
1330d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn                    if (cb != null) {
1340d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn                        cb.batteryPowerChanged(msg.arg1 != 0);
1350d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn                    }
1360d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn                    break;
1370d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn            }
1380d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn        }
1390d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn    }
1400d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn
1410d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn    private final MyHandler mHandler;
1420d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn
1430d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn    private BatteryCallback mCallback;
1440d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The statistics we have collected organized by uids.
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final SparseArray<BatteryStatsImpl.Uid> mUidStats =
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        new SparseArray<BatteryStatsImpl.Uid>();
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // A set of pools of currently active timers.  When a timer is queried, we will divide the
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // elapsed time by the number of active timers to arrive at that timer's share of the time.
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // In order to do this, we must refresh each timer whenever the number of active timers
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // changes.
155c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>();
156c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>();
157c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>();
158c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers
159c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            = new SparseArray<ArrayList<StopwatchTimer>>();
16058e0eefeb5e2e270e2b04369bbf29fc22abda8d5Dianne Hackborn    final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<StopwatchTimer>();
16158e0eefeb5e2e270e2b04369bbf29fc22abda8d5Dianne Hackborn    final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<StopwatchTimer>();
16258e0eefeb5e2e270e2b04369bbf29fc22abda8d5Dianne Hackborn    final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<StopwatchTimer>();
1636ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly    final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<StopwatchTimer>();
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1650d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn    // Last partial timers we use for distributing CPU usage.
1660d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn    final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>();
1670d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // These are the objects that will want to do something when the device
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // is unplugged from power.
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>();
1715a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
1726b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn    boolean mShuttingDown;
1735a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
1746b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn    long mHistoryBaseTime;
1756b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn    boolean mHaveBatteryLevel = false;
1766b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn    boolean mRecordingHistory = true;
1776b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn    int mNumHistoryItems;
1780ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn
1791fadab5c36445bb9f0997904dbce44f8e234f847Dianne Hackborn    static final int MAX_HISTORY_BUFFER = 128*1024; // 128KB
1801fadab5c36445bb9f0997904dbce44f8e234f847Dianne Hackborn    static final int MAX_MAX_HISTORY_BUFFER = 144*1024; // 144KB
1810ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn    final Parcel mHistoryBuffer = Parcel.obtain();
1820ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn    final HistoryItem mHistoryLastWritten = new HistoryItem();
1830ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn    final HistoryItem mHistoryLastLastWritten = new HistoryItem();
1841fadab5c36445bb9f0997904dbce44f8e234f847Dianne Hackborn    final HistoryItem mHistoryReadTmp = new HistoryItem();
1850ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn    int mHistoryBufferLastPos = -1;
1860ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn    boolean mHistoryOverflow = false;
1870ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn    long mLastHistoryTime = 0;
1880ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn
1890ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn    final HistoryItem mHistoryCur = new HistoryItem();
1900ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn
1916b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn    HistoryItem mHistory;
1926b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn    HistoryItem mHistoryEnd;
1939adb9c3b10991ef315c270993f4155709c8a232dDianne Hackborn    HistoryItem mHistoryLastEnd;
1946b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn    HistoryItem mHistoryCache;
1950ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn
1960ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn    private HistoryItem mHistoryIterator;
1970ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn    private boolean mReadOverflow;
1980ffc988a7f47013805d5abeed1c20f159b3bd799Dianne Hackborn    private boolean mIteratingHistory;
1995a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mStartCount;
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mBatteryUptime;
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mBatteryLastUptime;
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mBatteryRealtime;
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mBatteryLastRealtime;
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mUptime;
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mUptimeStart;
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mLastUptime;
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mRealtime;
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mRealtimeStart;
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mLastRealtime;
2135a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mScreenOn;
215c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    StopwatchTimer mScreenOnTimer;
2163718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani
217617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn    int mScreenBrightnessBin = -1;
218c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
2195a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
220617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn    Counter mInputEventCounter;
2215a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mPhoneOn;
223c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    StopwatchTimer mPhoneOnTimer;
2245a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
225244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    boolean mAudioOn;
226244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    StopwatchTimer mAudioOnTimer;
2275a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
228244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    boolean mVideoOn;
229244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani    StopwatchTimer mVideoOnTimer;
2305a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
231627bba736d022c39696b7c582a6af5592d2b8c33Dianne Hackborn    int mPhoneSignalStrengthBin = -1;
232e4a5951925f16f18dae91ed65567e96528f17feeDianne Hackborn    int mPhoneSignalStrengthBinRaw = -1;
233c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    final StopwatchTimer[] mPhoneSignalStrengthsTimer =
2345284090631e638b916d9a453212e9dc802656a67Wink Saville            new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
235f37447bad3773b62176baa837908daf6edb44273Amith Yamasani
236f37447bad3773b62176baa837908daf6edb44273Amith Yamasani    StopwatchTimer mPhoneSignalScanningTimer;
237f37447bad3773b62176baa837908daf6edb44273Amith Yamasani
238627bba736d022c39696b7c582a6af5592d2b8c33Dianne Hackborn    int mPhoneDataConnectionType = -1;
2395a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh    final StopwatchTimer[] mPhoneDataConnectionsTimer =
240c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
2415a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
242105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    boolean mWifiOn;
243c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    StopwatchTimer mWifiOnTimer;
244617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn    int mWifiOnUid = -1;
245d4c5f8919b0522bcaab41a5863c313fec52d3a79Eric Shienbrood
24658e0eefeb5e2e270e2b04369bbf29fc22abda8d5Dianne Hackborn    boolean mGlobalWifiRunning;
24758e0eefeb5e2e270e2b04369bbf29fc22abda8d5Dianne Hackborn    StopwatchTimer mGlobalWifiRunningTimer;
2485a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
249105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    boolean mBluetoothOn;
250c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    StopwatchTimer mBluetoothOnTimer;
2513f7e35c2c7d3d7f08f50c1d93cd16b1f49354cccAmith Yamasani
2523f7e35c2c7d3d7f08f50c1d93cd16b1f49354cccAmith Yamasani    /** Bluetooth headset object */
2533f7e35c2c7d3d7f08f50c1d93cd16b1f49354cccAmith Yamasani    BluetoothHeadset mBtHeadset;
2543f7e35c2c7d3d7f08f50c1d93cd16b1f49354cccAmith Yamasani
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * These provide time bases that discount the time the device is plugged
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in to power.
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mOnBattery;
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mOnBatteryInternal;
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mTrackBatteryPastUptime;
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mTrackBatteryUptimeStart;
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mTrackBatteryPastRealtime;
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mTrackBatteryRealtimeStart;
2653718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mUnpluggedBatteryUptime;
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mUnpluggedBatteryRealtime;
2683718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani
269105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    /*
270105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
271105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     */
272633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar    int mDischargeStartLevel;
2736b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn    int mDischargeUnplugLevel;
274633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar    int mDischargeCurrentLevel;
2753bee5af8162c177f8c8f4199489a401058ab26a9Dianne Hackborn    int mLowDischargeAmountSinceCharge;
2763bee5af8162c177f8c8f4199489a401058ab26a9Dianne Hackborn    int mHighDischargeAmountSinceCharge;
277c1b40e361c6cd3bdc53499f17ac09f45e6873059Dianne Hackborn    int mDischargeScreenOnUnplugLevel;
278c1b40e361c6cd3bdc53499f17ac09f45e6873059Dianne Hackborn    int mDischargeScreenOffUnplugLevel;
279c1b40e361c6cd3bdc53499f17ac09f45e6873059Dianne Hackborn    int mDischargeAmountScreenOn;
280c1b40e361c6cd3bdc53499f17ac09f45e6873059Dianne Hackborn    int mDischargeAmountScreenOnSinceCharge;
281c1b40e361c6cd3bdc53499f17ac09f45e6873059Dianne Hackborn    int mDischargeAmountScreenOff;
282c1b40e361c6cd3bdc53499f17ac09f45e6873059Dianne Hackborn    int mDischargeAmountScreenOffSinceCharge;
283244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mLastWriteTime = 0; // Milliseconds
285244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani
2863718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani    // Mobile data transferred while on battery
2873718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani    private long[] mMobileDataTx = new long[4];
2883718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani    private long[] mMobileDataRx = new long[4];
2893718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani    private long[] mTotalDataTx = new long[4];
2903718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani    private long[] mTotalDataRx = new long[4];
2913718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani
2923718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani    private long mRadioDataUptime;
2933718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani    private long mRadioDataStart;
2943718aaabe6259dcf86a3666ff92d16e4be5da555Amith Yamasani
2953f7e35c2c7d3d7f08f50c1d93cd16b1f49354cccAmith Yamasani    private int mBluetoothPingCount;
2963f7e35c2c7d3d7f08f50c1d93cd16b1f49354cccAmith Yamasani    private int mBluetoothPingStart = -1;
2973f7e35c2c7d3d7f08f50c1d93cd16b1f49354cccAmith Yamasani
298f37447bad3773b62176baa837908daf6edb44273Amith Yamasani    private int mPhoneServiceState = -1;
299e4a5951925f16f18dae91ed65567e96528f17feeDianne Hackborn    private int mPhoneServiceStateRaw = -1;
300e4a5951925f16f18dae91ed65567e96528f17feeDianne Hackborn    private int mPhoneSimStateRaw = -1;
301f37447bad3773b62176baa837908daf6edb44273Amith Yamasani
302c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    /*
303c64edde69d18498fb2954f71a546357b07ab996aEvan Millar     * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
304c64edde69d18498fb2954f71a546357b07ab996aEvan Millar     */
3055a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh    private final HashMap<String, SamplingTimer> mKernelWakelockStats =
306c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            new HashMap<String, SamplingTimer>();
3075a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
308c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    public Map<String, ? extends SamplingTimer> getKernelWakelockStats() {
309c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        return mKernelWakelockStats;
310c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    }
3115a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
312c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    private static int sKernelWakelockUpdateVersion = 0;
3135a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
314c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
315c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        Process.PROC_TAB_TERM|Process.PROC_OUT_STRING,                // 0: name
316c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        Process.PROC_TAB_TERM|Process.PROC_OUT_LONG,                  // 1: count
317c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        Process.PROC_TAB_TERM,
318c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        Process.PROC_TAB_TERM,
319c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        Process.PROC_TAB_TERM,
320c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        Process.PROC_TAB_TERM|Process.PROC_OUT_LONG,                  // 5: totalTime
321c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    };
3225a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
32373f534a2dd324d631696ced762f5c0ab1f254f74Todd Poynor    private static final int[] WAKEUP_SOURCES_FORMAT = new int[] {
32473f534a2dd324d631696ced762f5c0ab1f254f74Todd Poynor        Process.PROC_TAB_TERM|Process.PROC_OUT_STRING,                // 0: name
32573f534a2dd324d631696ced762f5c0ab1f254f74Todd Poynor        Process.PROC_TAB_TERM|Process.PROC_COMBINE|
32673f534a2dd324d631696ced762f5c0ab1f254f74Todd Poynor                              Process.PROC_OUT_LONG,                  // 1: count
32773f534a2dd324d631696ced762f5c0ab1f254f74Todd Poynor        Process.PROC_TAB_TERM|Process.PROC_COMBINE,
32873f534a2dd324d631696ced762f5c0ab1f254f74Todd Poynor        Process.PROC_TAB_TERM|Process.PROC_COMBINE,
32973f534a2dd324d631696ced762f5c0ab1f254f74Todd Poynor        Process.PROC_TAB_TERM|Process.PROC_COMBINE,
33073f534a2dd324d631696ced762f5c0ab1f254f74Todd Poynor        Process.PROC_TAB_TERM|Process.PROC_COMBINE,
33173f534a2dd324d631696ced762f5c0ab1f254f74Todd Poynor        Process.PROC_TAB_TERM|Process.PROC_COMBINE
33273f534a2dd324d631696ced762f5c0ab1f254f74Todd Poynor                             |Process.PROC_OUT_LONG,                  // 6: totalTime
33373f534a2dd324d631696ced762f5c0ab1f254f74Todd Poynor    };
33473f534a2dd324d631696ced762f5c0ab1f254f74Todd Poynor
335c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    private final String[] mProcWakelocksName = new String[3];
336c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    private final long[] mProcWakelocksData = new long[3];
3375a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
338c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    /*
339c64edde69d18498fb2954f71a546357b07ab996aEvan Millar     * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added
340c64edde69d18498fb2954f71a546357b07ab996aEvan Millar     * to mKernelWakelockStats.
341c64edde69d18498fb2954f71a546357b07ab996aEvan Millar     */
3425a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh    private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
343c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            new HashMap<String, KernelWakelockStats>();
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34532dbefda71c50bf848da21fb5d1255273439f90dAmith Yamasani    private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>();
3465a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
3471059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey    private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
3481059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey
3491059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey    /** Network ifaces that {@link ConnectivityManager} has claimed as mobile. */
3501059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey    private HashSet<String> mMobileIfaces = Sets.newHashSet();
3511059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // For debugging
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public BatteryStatsImpl() {
3541afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackborn        mFile = null;
3550d903a84d04d241a648ec429e3a0e82c712677fdDianne Hackborn        mHandler = null;
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static interface Unpluggable {
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void unplug(long batteryUptime, long batteryRealtime);
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void plug(long batteryUptime, long batteryRealtime);
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3625a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
364617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn     * State for keeping track of counting information.
365617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn     */
366e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani    public static class Counter extends BatteryStats.Counter implements Unpluggable {
3674cee725b1fd3958d850fc83214797f76d5f6b468Christopher Tate        final AtomicInteger mCount = new AtomicInteger();
3686b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn        final ArrayList<Unpluggable> mUnpluggables;
369617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        int mLoadedCount;
370617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        int mLastCount;
371617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        int mUnpluggedCount;
372617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        int mPluggedCount;
3735a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
374617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        Counter(ArrayList<Unpluggable> unpluggables, Parcel in) {
3756b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn            mUnpluggables = unpluggables;
3764cee725b1fd3958d850fc83214797f76d5f6b468Christopher Tate            mPluggedCount = in.readInt();
3774cee725b1fd3958d850fc83214797f76d5f6b468Christopher Tate            mCount.set(mPluggedCount);
378617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn            mLoadedCount = in.readInt();
3793bee5af8162c177f8c8f4199489a401058ab26a9Dianne Hackborn            mLastCount = 0;
380617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn            mUnpluggedCount = in.readInt();
381617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn            unpluggables.add(this);
382617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        }
383617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn
384617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        Counter(ArrayList<Unpluggable> unpluggables) {
3856b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn            mUnpluggables = unpluggables;
386617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn            unpluggables.add(this);
387617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        }
3885a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
389617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        public void writeToParcel(Parcel out) {
3904cee725b1fd3958d850fc83214797f76d5f6b468Christopher Tate            out.writeInt(mCount.get());
391617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn            out.writeInt(mLoadedCount);
392617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn            out.writeInt(mUnpluggedCount);
393617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        }
394617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn
395617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        public void unplug(long batteryUptime, long batteryRealtime) {
3964cee725b1fd3958d850fc83214797f76d5f6b468Christopher Tate            mUnpluggedCount = mPluggedCount;
3974cee725b1fd3958d850fc83214797f76d5f6b468Christopher Tate            mCount.set(mPluggedCount);
398617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        }
399617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn
400617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        public void plug(long batteryUptime, long batteryRealtime) {
4014cee725b1fd3958d850fc83214797f76d5f6b468Christopher Tate            mPluggedCount = mCount.get();
402617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        }
4035a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
404617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        /**
405617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn         * Writes a possibly null Counter to a Parcel.
406617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn         *
407617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn         * @param out the Parcel to be written to.
408617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn         * @param counter a Counter, or null.
409617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn         */
410617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        public static void writeCounterToParcel(Parcel out, Counter counter) {
411617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn            if (counter == null) {
412617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn                out.writeInt(0); // indicates null
413617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn                return;
414617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn            }
415617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn            out.writeInt(1); // indicates non-null
416617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn
417617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn            counter.writeToParcel(out);
418617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        }
419617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn
420617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        @Override
421c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        public int getCountLocked(int which) {
422617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn            int val;
423617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn            if (which == STATS_LAST) {
424617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn                val = mLastCount;
425617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn            } else {
4264cee725b1fd3958d850fc83214797f76d5f6b468Christopher Tate                val = mCount.get();
4276b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn                if (which == STATS_SINCE_UNPLUGGED) {
428617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn                    val -= mUnpluggedCount;
4296b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn                } else if (which != STATS_SINCE_CHARGED) {
430617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn                    val -= mLoadedCount;
431617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn                }
432617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn            }
433617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn
434617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn            return val;
435617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        }
436617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn
437617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        public void logState(Printer pw, String prefix) {
4384cee725b1fd3958d850fc83214797f76d5f6b468Christopher Tate            pw.println(prefix + "mCount=" + mCount.get()
439617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn                    + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
440617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn                    + " mUnpluggedCount=" + mUnpluggedCount
441617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn                    + " mPluggedCount=" + mPluggedCount);
442617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        }
4435a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
4444cee725b1fd3958d850fc83214797f76d5f6b468Christopher Tate        void stepAtomic() {
4454cee725b1fd3958d850fc83214797f76d5f6b468Christopher Tate            mCount.incrementAndGet();
446617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        }
447617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn
4486b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn        /**
4496b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn         * Clear state of this counter.
4506b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn         */
4516b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn        void reset(boolean detachIfReset) {
4526b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn            mCount.set(0);
4536b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn            mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
4546b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn            if (detachIfReset) {
4556b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn                detach();
4566b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn            }
4576b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn        }
4585a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
4596b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn        void detach() {
4606b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn            mUnpluggables.remove(this);
4616b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn        }
4625a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
463617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        void writeSummaryFromParcelLocked(Parcel out) {
4644cee725b1fd3958d850fc83214797f76d5f6b468Christopher Tate            int count = mCount.get();
4654cee725b1fd3958d850fc83214797f76d5f6b468Christopher Tate            out.writeInt(count);
466617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        }
467617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn
468617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        void readSummaryFromParcelLocked(Parcel in) {
4694cee725b1fd3958d850fc83214797f76d5f6b468Christopher Tate            mLoadedCount = in.readInt();
4704cee725b1fd3958d850fc83214797f76d5f6b468Christopher Tate            mCount.set(mLoadedCount);
4713bee5af8162c177f8c8f4199489a401058ab26a9Dianne Hackborn            mLastCount = 0;
4724cee725b1fd3958d850fc83214797f76d5f6b468Christopher Tate            mUnpluggedCount = mPluggedCount = mLoadedCount;
473617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn        }
474617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn    }
475e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani
476e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani    public static class SamplingCounter extends Counter {
477e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani
478e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani        SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
479e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani            super(unpluggables, in);
480e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani        }
481e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani
482e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani        SamplingCounter(ArrayList<Unpluggable> unpluggables) {
483e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani            super(unpluggables);
484e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani        }
485e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani
4864cee725b1fd3958d850fc83214797f76d5f6b468Christopher Tate        public void addCountAtomic(long count) {
4874cee725b1fd3958d850fc83214797f76d5f6b468Christopher Tate            mCount.addAndGet((int)count);
488e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani        }
489e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani    }
490e43530ab571e901f94361078c7c1f970a0bd27f2Amith Yamasani
491617f877c06c82584a38f41bb60d836e08c5e3bdaDianne Hackborn    /**
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * State for keeping track of timing information.
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
494c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    public static abstract class Timer extends BatteryStats.Timer implements Unpluggable {
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int mType;
4966b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn        final ArrayList<Unpluggable> mUnpluggables;
4975a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int mCount;
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int mLoadedCount;
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int mLastCount;
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int mUnpluggedCount;
5025a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Times are in microseconds for better accuracy when dividing by the
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // lock count, and are in "battery realtime" units.
5055a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * The total time we have accumulated since the start of the original
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * boot, to the last time something interesting happened in the
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * current run.
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long mTotalTime;
5125a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * The total time we loaded for the previous runs.  Subtract this from
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * mTotalTime to find the time for the current run of the system.
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long mLoadedTime;
5185a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * The run time of the last run of the system, as loaded from the
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * saved data.
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long mLastTime;
5245a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * The value of mTotalTime when unplug() was last called.  Subtract
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * this from mTotalTime to find the time since the last unplug from
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * power.
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long mUnpluggedTime;
5315a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
532244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani        /**
533244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani         * Constructs from a parcel.
534244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani         * @param type
535244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani         * @param unpluggables
536244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani         * @param powerType
537244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani         * @param in
538244fa5c05b2cc8c4c0754aeed4ee42c588ea89d1Amith Yamasani         */
539c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) {
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mType = type;
5416b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn            mUnpluggables = unpluggables;
5425a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCount = in.readInt();
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLoadedCount = in.readInt();
5453bee5af8162c177f8c8f4199489a401058ab26a9Dianne Hackborn            mLastCount = 0;
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mUnpluggedCount = in.readInt();
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mTotalTime = in.readLong();
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLoadedTime = in.readLong();
5493bee5af8162c177f8c8f4199489a401058ab26a9Dianne Hackborn            mLastTime = 0;
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mUnpluggedTime = in.readLong();
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            unpluggables.add(this);
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
554c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        Timer(int type, ArrayList<Unpluggable> unpluggables) {
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mType = type;
5566b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn            mUnpluggables = unpluggables;
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            unpluggables.add(this);
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
559c64edde69d18498fb2954f71a546357b07ab996aEvan Millar
560c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        protected abstract long computeRunTimeLocked(long curBatteryRealtime);
5615a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
562c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        protected abstract int computeCurrentCountLocked();
5635a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
5646b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn        /**
5656b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn         * Clear state of this timer.  Returns true if the timer is inactive
5666b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn         * so can be completely dropped.
5676b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn         */
5689adb9c3b10991ef315c270993f4155709c8a232dDianne Hackborn        boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
5696b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn            mTotalTime = mLoadedTime = mLastTime = 0;
5706b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn            mCount = mLoadedCount = mLastCount = 0;
5716b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn            if (detachIfReset) {
5726b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn                detach();
5736b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn            }
5746b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn            return true;
5756b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn        }
5765a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
5776b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn        void detach() {
5786b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn            mUnpluggables.remove(this);
5796b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn        }
5805a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void writeToParcel(Parcel out, long batteryRealtime) {
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeInt(mCount);
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeInt(mLoadedCount);
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeInt(mUnpluggedCount);
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeLong(computeRunTimeLocked(batteryRealtime));
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeLong(mLoadedTime);
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeLong(mUnpluggedTime);
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void unplug(long batteryUptime, long batteryRealtime) {
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG && mType < 0) {
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " old mUnpluggedTime=" + mUnpluggedTime
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " old mUnpluggedCount=" + mUnpluggedCount);
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mUnpluggedTime = computeRunTimeLocked(batteryRealtime);
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mUnpluggedCount = mCount;
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG && mType < 0) {
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.v(TAG, "unplug #" + mType
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + ": new mUnpluggedTime=" + mUnpluggedTime
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " new mUnpluggedCount=" + mUnpluggedCount);
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void plug(long batteryUptime, long batteryRealtime) {
606c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            if (DEBUG && mType < 0) {
607c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime
608c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                        + " old mTotalTime=" + mTotalTime);
609c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            }
610c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mTotalTime = computeRunTimeLocked(batteryRealtime);
611c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mCount = computeCurrentCountLocked();
612c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            if (DEBUG && mType < 0) {
613c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                Log.v(TAG, "plug #" + mType
614c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                        + ": new mTotalTime=" + mTotalTime);
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6175a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Writes a possibly null Timer to a Parcel.
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param out the Parcel to be written to.
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param timer a Timer, or null.
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public static void writeTimerToParcel(Parcel out, Timer timer,
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                long batteryRealtime) {
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (timer == null) {
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                out.writeInt(0); // indicates null
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeInt(1); // indicates non-null
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            timer.writeToParcel(out, batteryRealtime);
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
636c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        public long getTotalTimeLocked(long batteryRealtime, int which) {
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            long val;
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (which == STATS_LAST) {
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                val = mLastTime;
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                val = computeRunTimeLocked(batteryRealtime);
6426b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn                if (which == STATS_SINCE_UNPLUGGED) {
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    val -= mUnpluggedTime;
6446b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn                } else if (which != STATS_SINCE_CHARGED) {
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    val -= mLoadedTime;
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return val;
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
653c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        public int getCountLocked(int which) {
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int val;
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (which == STATS_LAST) {
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                val = mLastCount;
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
658c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                val = computeCurrentCountLocked();
6596b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn                if (which == STATS_SINCE_UNPLUGGED) {
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    val -= mUnpluggedCount;
6616b7b4845212b3a439c527f2e1eca205b6b45fcebDianne Hackborn                } else if (which != STATS_SINCE_CHARGED) {
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    val -= mLoadedCount;
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return val;
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
669627bba736d022c39696b7c582a6af5592d2b8c33Dianne Hackborn        public void logState(Printer pw, String prefix) {
670c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            pw.println(prefix + " mCount=" + mCount
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " mUnpluggedCount=" + mUnpluggedCount);
673627bba736d022c39696b7c582a6af5592d2b8c33Dianne Hackborn            pw.println(prefix + "mTotalTime=" + mTotalTime
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " mLoadedTime=" + mLoadedTime);
675627bba736d022c39696b7c582a6af5592d2b8c33Dianne Hackborn            pw.println(prefix + "mLastTime=" + mLastTime
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " mUnpluggedTime=" + mUnpluggedTime);
677c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        }
6785a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
6795a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
680c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
681c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            long runTime = computeRunTimeLocked(batteryRealtime);
682c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            // Divide by 1000 for backwards compatibility
683c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            out.writeLong((runTime + 500) / 1000);
684c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            out.writeInt(mCount);
685c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        }
686c64edde69d18498fb2954f71a546357b07ab996aEvan Millar
687c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        void readSummaryFromParcelLocked(Parcel in) {
688c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            // Multiply by 1000 for backwards compatibility
689c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mTotalTime = mLoadedTime = in.readLong() * 1000;
6903bee5af8162c177f8c8f4199489a401058ab26a9Dianne Hackborn            mLastTime = 0;
691c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mUnpluggedTime = mTotalTime;
692c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mCount = mLoadedCount = in.readInt();
6933bee5af8162c177f8c8f4199489a401058ab26a9Dianne Hackborn            mLastCount = 0;
694c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mUnpluggedCount = mCount;
695c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        }
696c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    }
6975a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
698c64edde69d18498fb2954f71a546357b07ab996aEvan Millar    public static final class SamplingTimer extends Timer {
6995a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
700c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        /**
701c64edde69d18498fb2954f71a546357b07ab996aEvan Millar         * The most recent reported count from /proc/wakelocks.
702c64edde69d18498fb2954f71a546357b07ab996aEvan Millar         */
703c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        int mCurrentReportedCount;
704c64edde69d18498fb2954f71a546357b07ab996aEvan Millar
705c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        /**
706c64edde69d18498fb2954f71a546357b07ab996aEvan Millar         * The reported count from /proc/wakelocks when unplug() was last
707c64edde69d18498fb2954f71a546357b07ab996aEvan Millar         * called.
708c64edde69d18498fb2954f71a546357b07ab996aEvan Millar         */
709c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        int mUnpluggedReportedCount;
710c64edde69d18498fb2954f71a546357b07ab996aEvan Millar
711c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        /**
712c64edde69d18498fb2954f71a546357b07ab996aEvan Millar         * The most recent reported total_time from /proc/wakelocks.
7135a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh         */
714c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        long mCurrentReportedTotalTime;
715c64edde69d18498fb2954f71a546357b07ab996aEvan Millar
716c64edde69d18498fb2954f71a546357b07ab996aEvan Millar
717c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        /**
718c64edde69d18498fb2954f71a546357b07ab996aEvan Millar         * The reported total_time from /proc/wakelocks when unplug() was last
719c64edde69d18498fb2954f71a546357b07ab996aEvan Millar         * called.
720c64edde69d18498fb2954f71a546357b07ab996aEvan Millar         */
721c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        long mUnpluggedReportedTotalTime;
722c64edde69d18498fb2954f71a546357b07ab996aEvan Millar
723c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        /**
724c64edde69d18498fb2954f71a546357b07ab996aEvan Millar         * Whether we are currently in a discharge cycle.
725c64edde69d18498fb2954f71a546357b07ab996aEvan Millar         */
726c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        boolean mInDischarge;
727c64edde69d18498fb2954f71a546357b07ab996aEvan Millar
728c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        /**
729c64edde69d18498fb2954f71a546357b07ab996aEvan Millar         * Whether we are currently recording reported values.
730c64edde69d18498fb2954f71a546357b07ab996aEvan Millar         */
731c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        boolean mTrackingReportedValues;
7325a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
733c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        /*
734c64edde69d18498fb2954f71a546357b07ab996aEvan Millar         * A sequnce counter, incremented once for each update of the stats.
735c64edde69d18498fb2954f71a546357b07ab996aEvan Millar         */
736c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        int mUpdateVersion;
7375a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
738c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) {
739c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            super(0, unpluggables, in);
740c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mCurrentReportedCount = in.readInt();
741c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mUnpluggedReportedCount = in.readInt();
742c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mCurrentReportedTotalTime = in.readLong();
743c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mUnpluggedReportedTotalTime = in.readLong();
744c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mTrackingReportedValues = in.readInt() == 1;
745c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mInDischarge = inDischarge;
746c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        }
7475a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
7485a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh        SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge,
749c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                boolean trackReportedValues) {
750c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            super(0, unpluggables);
751c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mTrackingReportedValues = trackReportedValues;
752c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mInDischarge = inDischarge;
753c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        }
7545a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
755c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        public void setStale() {
756c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mTrackingReportedValues = false;
757c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mUnpluggedReportedTotalTime = 0;
758c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mUnpluggedReportedCount = 0;
759c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        }
7605a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
761c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        public void setUpdateVersion(int version) {
762c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mUpdateVersion = version;
763c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        }
7645a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
765c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        public int getUpdateVersion() {
766c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            return mUpdateVersion;
767c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        }
7685a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
769c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        public void updateCurrentReportedCount(int count) {
770c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            if (mInDischarge && mUnpluggedReportedCount == 0) {
771c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                // Updating the reported value for the first time.
772c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                mUnpluggedReportedCount = count;
773c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                // If we are receiving an update update mTrackingReportedValues;
774c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                mTrackingReportedValues = true;
775c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            }
776c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mCurrentReportedCount = count;
777c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        }
7785a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
779c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        public void updateCurrentReportedTotalTime(long totalTime) {
780c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            if (mInDischarge && mUnpluggedReportedTotalTime == 0) {
781c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                // Updating the reported value for the first time.
782c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                mUnpluggedReportedTotalTime = totalTime;
783c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                // If we are receiving an update update mTrackingReportedValues;
784c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                mTrackingReportedValues = true;
785c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            }
786c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mCurrentReportedTotalTime = totalTime;
787c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        }
7885a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
789c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        public void unplug(long batteryUptime, long batteryRealtime) {
790c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            super.unplug(batteryUptime, batteryRealtime);
791c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            if (mTrackingReportedValues) {
792c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
793c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                mUnpluggedReportedCount = mCurrentReportedCount;
794c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            }
795c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mInDischarge = true;
796c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        }
797c64edde69d18498fb2954f71a546357b07ab996aEvan Millar
798c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        public void plug(long batteryUptime, long batteryRealtime) {
799c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            super.plug(batteryUptime, batteryRealtime);
800c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            mInDischarge = false;
801c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        }
8025a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
803c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        public void logState(Printer pw, String prefix) {
804c64edde69d18498fb2954f71a546357b07ab996aEvan Millar            super.logState(pw, prefix);
8055a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh            pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
806c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                    + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
807c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                    + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
808c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                    + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
809c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        }
8105a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh
811c64edde69d18498fb2954f71a546357b07ab996aEvan Millar        protected long computeRunTimeLocked(long curBatteryRealtime) {
8125a1e4cf83f5be1b5d79e2643fa791aa269b6a4bcJaikumar Ganesh            return mTotalTime + (mInDischarge && mTrackingReportedValues
813c64edde69d18498fb2954f71a546357b07ab996aEvan Millar                    ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
814