blob: 872861024cdd8144bfd904790e1c021317db8bd4 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.os;
18
Jeff Sharkey418d12d2011-12-13 15:38:03 -080019import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070020
Jaikumar Ganesh3f034962010-09-27 17:02:23 -070021import android.bluetooth.BluetoothDevice;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -070022import android.bluetooth.BluetoothHeadset;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070023import android.net.ConnectivityManager;
24import android.net.NetworkStats;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070025import android.os.BatteryManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import android.os.BatteryStats;
Dianne Hackborn8bdf5932010-10-15 12:54:40 -070027import android.os.FileUtils;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070028import android.os.Handler;
Jeff Brown6f357d32014-01-15 20:40:55 -080029import android.os.Looper;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070030import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.os.Parcel;
32import android.os.ParcelFormatException;
33import android.os.Parcelable;
Evan Millarc64edde2009-04-18 12:26:32 -070034import android.os.Process;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import android.os.SystemClock;
Jeff Sharkey418d12d2011-12-13 15:38:03 -080036import android.os.SystemProperties;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070037import android.os.WorkSource;
Amith Yamasanif37447b2009-10-08 18:28:01 -070038import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070039import android.telephony.SignalStrength;
Dianne Hackborn627bba72009-03-24 22:32:56 -070040import android.telephony.TelephonyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.util.Log;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070042import android.util.LogWriter;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070043import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.util.Printer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070045import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.util.SparseArray;
Dianne Hackbornae384452011-06-28 12:33:48 -070047import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070049import com.android.internal.annotations.GuardedBy;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070050import com.android.internal.net.NetworkStatsFactory;
Dianne Hackborn8c841092013-06-24 13:46:13 -070051import com.android.internal.util.FastPrintWriter;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070052import com.android.internal.util.JournaledFile;
53import com.google.android.collect.Sets;
54
Amith Yamasani3718aaa2009-06-09 06:32:35 -070055import java.io.BufferedReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056import java.io.File;
57import java.io.FileInputStream;
58import java.io.FileOutputStream;
Amith Yamasani3718aaa2009-06-09 06:32:35 -070059import java.io.FileReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070061import java.io.PrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import java.util.ArrayList;
63import java.util.HashMap;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070064import java.util.HashSet;
Evan Millarc64edde2009-04-18 12:26:32 -070065import java.util.Iterator;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070066import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import java.util.Map;
Christopher Tate4cee7252010-03-19 14:50:40 -070068import java.util.concurrent.atomic.AtomicInteger;
Dianne Hackbornce2ef762010-09-20 11:39:14 -070069import java.util.concurrent.locks.ReentrantLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070
71/**
72 * All information we are collecting about things that can happen that impact
73 * battery life. All times are represented in microseconds except where indicated
74 * otherwise.
75 */
76public final class BatteryStatsImpl extends BatteryStats {
77 private static final String TAG = "BatteryStatsImpl";
78 private static final boolean DEBUG = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070079 private static final boolean DEBUG_HISTORY = false;
Dianne Hackborne8c88e62011-08-17 19:09:09 -070080 private static final boolean USE_OLD_HISTORY = false; // for debugging.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070081
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070082 // TODO: remove "tcp" from network methods, since we measure total stats.
83
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070085 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086
87 // Current on-disk Parcel version
Jeff Brown81b7caf2013-10-29 18:28:57 -070088 private static final int VERSION = 67 + (USE_OLD_HISTORY ? 1000 : 0);
Amith Yamasanie43530a2009-08-21 13:11:37 -070089
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070090 // Maximum number of items we will record in the history.
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070091 private static final int MAX_HISTORY_ITEMS = 2000;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070092
Dianne Hackbornf47d8f22010-10-08 10:46:55 -070093 // No, really, THIS is the maximum number of items we will record in the history.
94 private static final int MAX_MAX_HISTORY_ITEMS = 3000;
95
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -080096 // The maximum number of names wakelocks we will keep track of
97 // per uid; once the limit is reached, we batch the remaining wakelocks
98 // in to one common name.
Dianne Hackbornaf17baa2013-05-09 15:27:47 -070099 private static final int MAX_WAKELOCKS_PER_UID = 50;
Dianne Hackbornc24ab862011-10-18 15:55:03 -0700100
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800101 private static final String BATCHED_WAKELOCK_NAME = "*overflow*";
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700102
Amith Yamasanie43530a2009-08-21 13:11:37 -0700103 private static int sNumSpeedSteps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700105 private final JournaledFile mFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700107 static final int MSG_UPDATE_WAKELOCKS = 1;
108 static final int MSG_REPORT_POWER_CHANGE = 2;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700109 static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700110
111 public interface BatteryCallback {
112 public void batteryNeedsCpuUpdate();
113 public void batteryPowerChanged(boolean onBattery);
114 }
115
116 final class MyHandler extends Handler {
Jeff Brown6f357d32014-01-15 20:40:55 -0800117 public MyHandler(Looper looper) {
118 super(looper, null, true);
119 }
120
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700121 @Override
122 public void handleMessage(Message msg) {
123 BatteryCallback cb = mCallback;
124 switch (msg.what) {
125 case MSG_UPDATE_WAKELOCKS:
126 if (cb != null) {
127 cb.batteryNeedsCpuUpdate();
128 }
129 break;
130 case MSG_REPORT_POWER_CHANGE:
131 if (cb != null) {
132 cb.batteryPowerChanged(msg.arg1 != 0);
133 }
134 break;
135 }
136 }
137 }
138
139 private final MyHandler mHandler;
140
141 private BatteryCallback mCallback;
142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 /**
144 * The statistics we have collected organized by uids.
145 */
146 final SparseArray<BatteryStatsImpl.Uid> mUidStats =
147 new SparseArray<BatteryStatsImpl.Uid>();
148
149 // A set of pools of currently active timers. When a timer is queried, we will divide the
150 // elapsed time by the number of active timers to arrive at that timer's share of the time.
151 // In order to do this, we must refresh each timer whenever the number of active timers
152 // changes.
Evan Millarc64edde2009-04-18 12:26:32 -0700153 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>();
154 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>();
155 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>();
156 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers
157 = new SparseArray<ArrayList<StopwatchTimer>>();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700158 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<StopwatchTimer>();
159 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<StopwatchTimer>();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700160 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<StopwatchTimer>();
Nick Pelly6ccaa542012-06-15 15:22:47 -0700161 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<StopwatchTimer>();
Robert Greenwalta029ea12013-09-25 16:38:12 -0700162 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers =
163 new SparseArray<ArrayList<StopwatchTimer>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700165 // Last partial timers we use for distributing CPU usage.
166 final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>();
167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 // These are the objects that will want to do something when the device
169 // is unplugged from power.
170 final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700171
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700172 boolean mShuttingDown;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700173
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700174 long mHistoryBaseTime;
175 boolean mHaveBatteryLevel = false;
176 boolean mRecordingHistory = true;
177 int mNumHistoryItems;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700178
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700179 static final int MAX_HISTORY_BUFFER = 128*1024; // 128KB
180 static final int MAX_MAX_HISTORY_BUFFER = 144*1024; // 144KB
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700181 final Parcel mHistoryBuffer = Parcel.obtain();
182 final HistoryItem mHistoryLastWritten = new HistoryItem();
183 final HistoryItem mHistoryLastLastWritten = new HistoryItem();
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700184 final HistoryItem mHistoryReadTmp = new HistoryItem();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700185 int mHistoryBufferLastPos = -1;
186 boolean mHistoryOverflow = false;
187 long mLastHistoryTime = 0;
188
189 final HistoryItem mHistoryCur = new HistoryItem();
190
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700191 HistoryItem mHistory;
192 HistoryItem mHistoryEnd;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700193 HistoryItem mHistoryLastEnd;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700194 HistoryItem mHistoryCache;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700195
196 private HistoryItem mHistoryIterator;
197 private boolean mReadOverflow;
198 private boolean mIteratingHistory;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700199
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200 int mStartCount;
201
202 long mBatteryUptime;
203 long mBatteryLastUptime;
204 long mBatteryRealtime;
205 long mBatteryLastRealtime;
206
207 long mUptime;
208 long mUptimeStart;
209 long mLastUptime;
210 long mRealtime;
211 long mRealtimeStart;
212 long mLastRealtime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 boolean mScreenOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700215 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700216
Dianne Hackborn617f8772009-03-31 15:04:46 -0700217 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700218 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700219
Dianne Hackborn617f8772009-03-31 15:04:46 -0700220 Counter mInputEventCounter;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700221
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800222 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700223 StopwatchTimer mPhoneOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700224
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700225 boolean mAudioOn;
226 StopwatchTimer mAudioOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700227
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700228 boolean mVideoOn;
229 StopwatchTimer mVideoOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700230
Dianne Hackborn627bba72009-03-24 22:32:56 -0700231 int mPhoneSignalStrengthBin = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800232 int mPhoneSignalStrengthBinRaw = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700233 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
Wink Saville52840902011-02-18 12:40:47 -0800234 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700235
236 StopwatchTimer mPhoneSignalScanningTimer;
237
Dianne Hackborn627bba72009-03-24 22:32:56 -0700238 int mPhoneDataConnectionType = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700239 final StopwatchTimer[] mPhoneDataConnectionsTimer =
Evan Millarc64edde2009-04-18 12:26:32 -0700240 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700241
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700242 final LongSamplingCounter[] mNetworkActivityCounters =
243 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
244
The Android Open Source Project10592532009-03-18 17:39:46 -0700245 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700246 StopwatchTimer mWifiOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700247 int mWifiOnUid = -1;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700248
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700249 boolean mGlobalWifiRunning;
250 StopwatchTimer mGlobalWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700251
The Android Open Source Project10592532009-03-18 17:39:46 -0700252 boolean mBluetoothOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700253 StopwatchTimer mBluetoothOnTimer;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700254
255 /** Bluetooth headset object */
256 BluetoothHeadset mBtHeadset;
257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258 /**
259 * These provide time bases that discount the time the device is plugged
260 * in to power.
261 */
262 boolean mOnBattery;
263 boolean mOnBatteryInternal;
264 long mTrackBatteryPastUptime;
265 long mTrackBatteryUptimeStart;
266 long mTrackBatteryPastRealtime;
267 long mTrackBatteryRealtimeStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700268
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269 long mUnpluggedBatteryUptime;
270 long mUnpluggedBatteryRealtime;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700271
The Android Open Source Project10592532009-03-18 17:39:46 -0700272 /*
273 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
274 */
Evan Millar633a1742009-04-02 16:36:33 -0700275 int mDischargeStartLevel;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700276 int mDischargeUnplugLevel;
Evan Millar633a1742009-04-02 16:36:33 -0700277 int mDischargeCurrentLevel;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700278 int mLowDischargeAmountSinceCharge;
279 int mHighDischargeAmountSinceCharge;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800280 int mDischargeScreenOnUnplugLevel;
281 int mDischargeScreenOffUnplugLevel;
282 int mDischargeAmountScreenOn;
283 int mDischargeAmountScreenOnSinceCharge;
284 int mDischargeAmountScreenOff;
285 int mDischargeAmountScreenOffSinceCharge;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800287 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700288
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700289 private long mRadioDataUptime;
290 private long mRadioDataStart;
291
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700292 private int mBluetoothPingCount;
293 private int mBluetoothPingStart = -1;
294
Amith Yamasanif37447b2009-10-08 18:28:01 -0700295 private int mPhoneServiceState = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800296 private int mPhoneServiceStateRaw = -1;
297 private int mPhoneSimStateRaw = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -0700298
Evan Millarc64edde2009-04-18 12:26:32 -0700299 /*
300 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
301 */
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700302 private final HashMap<String, SamplingTimer> mKernelWakelockStats =
Evan Millarc64edde2009-04-18 12:26:32 -0700303 new HashMap<String, SamplingTimer>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700304
Evan Millarc64edde2009-04-18 12:26:32 -0700305 public Map<String, ? extends SamplingTimer> getKernelWakelockStats() {
306 return mKernelWakelockStats;
307 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700308
Evan Millarc64edde2009-04-18 12:26:32 -0700309 private static int sKernelWakelockUpdateVersion = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700310
Evan Millarc64edde2009-04-18 12:26:32 -0700311 private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
Dianne Hackborn13ac0412013-06-25 19:34:49 -0700312 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING| // 0: name
313 Process.PROC_QUOTES,
Evan Millarc64edde2009-04-18 12:26:32 -0700314 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count
315 Process.PROC_TAB_TERM,
316 Process.PROC_TAB_TERM,
317 Process.PROC_TAB_TERM,
318 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime
319 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700320
Todd Poynor73f534a2012-06-19 11:07:26 -0700321 private static final int[] WAKEUP_SOURCES_FORMAT = new int[] {
322 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name
323 Process.PROC_TAB_TERM|Process.PROC_COMBINE|
324 Process.PROC_OUT_LONG, // 1: count
325 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
326 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
327 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
328 Process.PROC_TAB_TERM|Process.PROC_COMBINE,
329 Process.PROC_TAB_TERM|Process.PROC_COMBINE
330 |Process.PROC_OUT_LONG, // 6: totalTime
331 };
332
Evan Millarc64edde2009-04-18 12:26:32 -0700333 private final String[] mProcWakelocksName = new String[3];
334 private final long[] mProcWakelocksData = new long[3];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700335
Evan Millarc64edde2009-04-18 12:26:32 -0700336 /*
337 * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added
338 * to mKernelWakelockStats.
339 */
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700340 private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
Evan Millarc64edde2009-04-18 12:26:32 -0700341 new HashMap<String, KernelWakelockStats>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700343 private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700344
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700345 private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700346 private NetworkStats mLastSnapshot;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700347
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700348 @GuardedBy("this")
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700349 private HashSet<String> mMobileIfaces = Sets.newHashSet();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700350 @GuardedBy("this")
351 private HashSet<String> mWifiIfaces = Sets.newHashSet();
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700352
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800353 // For debugging
354 public BatteryStatsImpl() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700355 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700356 mHandler = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357 }
358
359 public static interface Unpluggable {
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800360 void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime);
361 void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800362 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700363
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800364 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700365 * State for keeping track of counting information.
366 */
Amith Yamasanie43530a2009-08-21 13:11:37 -0700367 public static class Counter extends BatteryStats.Counter implements Unpluggable {
Christopher Tate4cee7252010-03-19 14:50:40 -0700368 final AtomicInteger mCount = new AtomicInteger();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700369 final ArrayList<Unpluggable> mUnpluggables;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700370 int mLoadedCount;
371 int mLastCount;
372 int mUnpluggedCount;
373 int mPluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700374
Dianne Hackborn617f8772009-03-31 15:04:46 -0700375 Counter(ArrayList<Unpluggable> unpluggables, Parcel in) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700376 mUnpluggables = unpluggables;
Christopher Tate4cee7252010-03-19 14:50:40 -0700377 mPluggedCount = in.readInt();
378 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700379 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700380 mLastCount = 0;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700381 mUnpluggedCount = in.readInt();
382 unpluggables.add(this);
383 }
384
385 Counter(ArrayList<Unpluggable> unpluggables) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700386 mUnpluggables = unpluggables;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700387 unpluggables.add(this);
388 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700389
Dianne Hackborn617f8772009-03-31 15:04:46 -0700390 public void writeToParcel(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700391 out.writeInt(mCount.get());
Dianne Hackborn617f8772009-03-31 15:04:46 -0700392 out.writeInt(mLoadedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700393 out.writeInt(mUnpluggedCount);
394 }
395
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800396 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700397 mUnpluggedCount = mPluggedCount;
398 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700399 }
400
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800401 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700402 mPluggedCount = mCount.get();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700403 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700404
Dianne Hackborn617f8772009-03-31 15:04:46 -0700405 /**
406 * Writes a possibly null Counter to a Parcel.
407 *
408 * @param out the Parcel to be written to.
409 * @param counter a Counter, or null.
410 */
411 public static void writeCounterToParcel(Parcel out, Counter counter) {
412 if (counter == null) {
413 out.writeInt(0); // indicates null
414 return;
415 }
416 out.writeInt(1); // indicates non-null
417
418 counter.writeToParcel(out);
419 }
420
421 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700422 public int getCountLocked(int which) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700423 int val;
424 if (which == STATS_LAST) {
425 val = mLastCount;
426 } else {
Christopher Tate4cee7252010-03-19 14:50:40 -0700427 val = mCount.get();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700428 if (which == STATS_SINCE_UNPLUGGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700429 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700430 } else if (which != STATS_SINCE_CHARGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700431 val -= mLoadedCount;
432 }
433 }
434
435 return val;
436 }
437
438 public void logState(Printer pw, String prefix) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700439 pw.println(prefix + "mCount=" + mCount.get()
Dianne Hackborn617f8772009-03-31 15:04:46 -0700440 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
441 + " mUnpluggedCount=" + mUnpluggedCount
442 + " mPluggedCount=" + mPluggedCount);
443 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700444
Christopher Tate4cee7252010-03-19 14:50:40 -0700445 void stepAtomic() {
446 mCount.incrementAndGet();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700447 }
448
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700449 /**
450 * Clear state of this counter.
451 */
452 void reset(boolean detachIfReset) {
453 mCount.set(0);
454 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
455 if (detachIfReset) {
456 detach();
457 }
458 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700459
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700460 void detach() {
461 mUnpluggables.remove(this);
462 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700463
Dianne Hackborn617f8772009-03-31 15:04:46 -0700464 void writeSummaryFromParcelLocked(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700465 int count = mCount.get();
466 out.writeInt(count);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700467 }
468
469 void readSummaryFromParcelLocked(Parcel in) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700470 mLoadedCount = in.readInt();
471 mCount.set(mLoadedCount);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700472 mLastCount = 0;
Christopher Tate4cee7252010-03-19 14:50:40 -0700473 mUnpluggedCount = mPluggedCount = mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700474 }
475 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700476
477 public static class SamplingCounter extends Counter {
Amith Yamasanie43530a2009-08-21 13:11:37 -0700478 SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
479 super(unpluggables, in);
480 }
481
482 SamplingCounter(ArrayList<Unpluggable> unpluggables) {
483 super(unpluggables);
484 }
485
Christopher Tate4cee7252010-03-19 14:50:40 -0700486 public void addCountAtomic(long count) {
487 mCount.addAndGet((int)count);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700488 }
489 }
490
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700491 public static class LongSamplingCounter implements Unpluggable {
492 final ArrayList<Unpluggable> mUnpluggables;
493 long mCount;
494 long mLoadedCount;
495 long mLastCount;
496 long mUnpluggedCount;
497 long mPluggedCount;
498
499 LongSamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
500 mUnpluggables = unpluggables;
501 mPluggedCount = in.readLong();
502 mCount = mPluggedCount;
503 mLoadedCount = in.readLong();
504 mLastCount = 0;
505 mUnpluggedCount = in.readLong();
506 unpluggables.add(this);
507 }
508
509 LongSamplingCounter(ArrayList<Unpluggable> unpluggables) {
510 mUnpluggables = unpluggables;
511 unpluggables.add(this);
512 }
513
514 public void writeToParcel(Parcel out) {
515 out.writeLong(mCount);
516 out.writeLong(mLoadedCount);
517 out.writeLong(mUnpluggedCount);
518 }
519
520 @Override
521 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
522 mUnpluggedCount = mPluggedCount;
523 mCount = mPluggedCount;
524 }
525
526 @Override
527 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
528 mPluggedCount = mCount;
529 }
530
531 public long getCountLocked(int which) {
532 long val;
533 if (which == STATS_LAST) {
534 val = mLastCount;
535 } else {
536 val = mCount;
537 if (which == STATS_SINCE_UNPLUGGED) {
538 val -= mUnpluggedCount;
539 } else if (which != STATS_SINCE_CHARGED) {
540 val -= mLoadedCount;
541 }
542 }
543
544 return val;
545 }
546
547 void addCountLocked(long count) {
548 mCount += count;
549 }
550
551 /**
552 * Clear state of this counter.
553 */
554 void reset(boolean detachIfReset) {
555 mCount = 0;
556 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
557 if (detachIfReset) {
558 detach();
559 }
560 }
561
562 void detach() {
563 mUnpluggables.remove(this);
564 }
565
566 void writeSummaryFromParcelLocked(Parcel out) {
567 out.writeLong(mCount);
568 }
569
570 void readSummaryFromParcelLocked(Parcel in) {
571 mLoadedCount = in.readLong();
572 mCount = mLoadedCount;
573 mLastCount = 0;
574 mUnpluggedCount = mPluggedCount = mLoadedCount;
575 }
576 }
577
Dianne Hackborn617f8772009-03-31 15:04:46 -0700578 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579 * State for keeping track of timing information.
580 */
Evan Millarc64edde2009-04-18 12:26:32 -0700581 public static abstract class Timer extends BatteryStats.Timer implements Unpluggable {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582 final int mType;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700583 final ArrayList<Unpluggable> mUnpluggables;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700584
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585 int mCount;
586 int mLoadedCount;
587 int mLastCount;
588 int mUnpluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800590 // Times are in microseconds for better accuracy when dividing by the
591 // lock count, and are in "battery realtime" units.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 /**
594 * The total time we have accumulated since the start of the original
595 * boot, to the last time something interesting happened in the
596 * current run.
597 */
598 long mTotalTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700599
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600 /**
601 * The total time we loaded for the previous runs. Subtract this from
602 * mTotalTime to find the time for the current run of the system.
603 */
604 long mLoadedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800606 /**
607 * The run time of the last run of the system, as loaded from the
608 * saved data.
609 */
610 long mLastTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700611
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800612 /**
613 * The value of mTotalTime when unplug() was last called. Subtract
614 * this from mTotalTime to find the time since the last unplug from
615 * power.
616 */
617 long mUnpluggedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700618
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700619 /**
620 * Constructs from a parcel.
621 * @param type
622 * @param unpluggables
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700623 * @param in
624 */
Evan Millarc64edde2009-04-18 12:26:32 -0700625 Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800626 mType = type;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700627 mUnpluggables = unpluggables;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 mCount = in.readInt();
630 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700631 mLastCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800632 mUnpluggedCount = in.readInt();
633 mTotalTime = in.readLong();
634 mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700635 mLastTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800636 mUnpluggedTime = in.readLong();
637 unpluggables.add(this);
638 }
639
Evan Millarc64edde2009-04-18 12:26:32 -0700640 Timer(int type, ArrayList<Unpluggable> unpluggables) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800641 mType = type;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700642 mUnpluggables = unpluggables;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800643 unpluggables.add(this);
644 }
Evan Millarc64edde2009-04-18 12:26:32 -0700645
646 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700647
Evan Millarc64edde2009-04-18 12:26:32 -0700648 protected abstract int computeCurrentCountLocked();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700649
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700650 /**
651 * Clear state of this timer. Returns true if the timer is inactive
652 * so can be completely dropped.
653 */
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700654 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700655 mTotalTime = mLoadedTime = mLastTime = 0;
656 mCount = mLoadedCount = mLastCount = 0;
657 if (detachIfReset) {
658 detach();
659 }
660 return true;
661 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700662
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700663 void detach() {
664 mUnpluggables.remove(this);
665 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700666
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800667 public void writeToParcel(Parcel out, long batteryRealtime) {
668 out.writeInt(mCount);
669 out.writeInt(mLoadedCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800670 out.writeInt(mUnpluggedCount);
671 out.writeLong(computeRunTimeLocked(batteryRealtime));
672 out.writeLong(mLoadedTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800673 out.writeLong(mUnpluggedTime);
674 }
675
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800676 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800677 if (DEBUG && mType < 0) {
678 Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime
679 + " old mUnpluggedTime=" + mUnpluggedTime
680 + " old mUnpluggedCount=" + mUnpluggedCount);
681 }
682 mUnpluggedTime = computeRunTimeLocked(batteryRealtime);
683 mUnpluggedCount = mCount;
684 if (DEBUG && mType < 0) {
685 Log.v(TAG, "unplug #" + mType
686 + ": new mUnpluggedTime=" + mUnpluggedTime
687 + " new mUnpluggedCount=" + mUnpluggedCount);
688 }
689 }
690
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800691 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -0700692 if (DEBUG && mType < 0) {
693 Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime
694 + " old mTotalTime=" + mTotalTime);
695 }
696 mTotalTime = computeRunTimeLocked(batteryRealtime);
697 mCount = computeCurrentCountLocked();
698 if (DEBUG && mType < 0) {
699 Log.v(TAG, "plug #" + mType
700 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800701 }
702 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700703
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704 /**
705 * Writes a possibly null Timer to a Parcel.
706 *
707 * @param out the Parcel to be written to.
708 * @param timer a Timer, or null.
709 */
710 public static void writeTimerToParcel(Parcel out, Timer timer,
711 long batteryRealtime) {
712 if (timer == null) {
713 out.writeInt(0); // indicates null
714 return;
715 }
716 out.writeInt(1); // indicates non-null
717
718 timer.writeToParcel(out, batteryRealtime);
719 }
720
721 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700722 public long getTotalTimeLocked(long batteryRealtime, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 long val;
724 if (which == STATS_LAST) {
725 val = mLastTime;
726 } else {
727 val = computeRunTimeLocked(batteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700728 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800729 val -= mUnpluggedTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700730 } else if (which != STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800731 val -= mLoadedTime;
732 }
733 }
734
735 return val;
736 }
737
738 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700739 public int getCountLocked(int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800740 int val;
741 if (which == STATS_LAST) {
742 val = mLastCount;
743 } else {
Evan Millarc64edde2009-04-18 12:26:32 -0700744 val = computeCurrentCountLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700745 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800746 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700747 } else if (which != STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748 val -= mLoadedCount;
749 }
750 }
751
752 return val;
753 }
754
Dianne Hackborn627bba72009-03-24 22:32:56 -0700755 public void logState(Printer pw, String prefix) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -0700756 pw.println(prefix + "mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800757 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
758 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700759 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800760 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700761 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800762 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -0700763 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700764
765
Evan Millarc64edde2009-04-18 12:26:32 -0700766 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
767 long runTime = computeRunTimeLocked(batteryRealtime);
768 // Divide by 1000 for backwards compatibility
769 out.writeLong((runTime + 500) / 1000);
Evan Millarc64edde2009-04-18 12:26:32 -0700770 out.writeInt(mCount);
Evan Millarc64edde2009-04-18 12:26:32 -0700771 }
772
773 void readSummaryFromParcelLocked(Parcel in) {
774 // Multiply by 1000 for backwards compatibility
775 mTotalTime = mLoadedTime = in.readLong() * 1000;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700776 mLastTime = 0;
Evan Millarc64edde2009-04-18 12:26:32 -0700777 mUnpluggedTime = mTotalTime;
778 mCount = mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700779 mLastCount = 0;
Evan Millarc64edde2009-04-18 12:26:32 -0700780 mUnpluggedCount = mCount;
781 }
782 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700783
Evan Millarc64edde2009-04-18 12:26:32 -0700784 public static final class SamplingTimer extends Timer {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700785
Evan Millarc64edde2009-04-18 12:26:32 -0700786 /**
787 * The most recent reported count from /proc/wakelocks.
788 */
789 int mCurrentReportedCount;
790
791 /**
792 * The reported count from /proc/wakelocks when unplug() was last
793 * called.
794 */
795 int mUnpluggedReportedCount;
796
797 /**
798 * The most recent reported total_time from /proc/wakelocks.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700799 */
Evan Millarc64edde2009-04-18 12:26:32 -0700800 long mCurrentReportedTotalTime;
801
802
803 /**
804 * The reported total_time from /proc/wakelocks when unplug() was last
805 * called.
806 */
807 long mUnpluggedReportedTotalTime;
808
809 /**
810 * Whether we are currently in a discharge cycle.
811 */
812 boolean mInDischarge;
813
814 /**
815 * Whether we are currently recording reported values.
816 */
817 boolean mTrackingReportedValues;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700818
Evan Millarc64edde2009-04-18 12:26:32 -0700819 /*
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800820 * A sequence counter, incremented once for each update of the stats.
Evan Millarc64edde2009-04-18 12:26:32 -0700821 */
822 int mUpdateVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700823
Evan Millarc64edde2009-04-18 12:26:32 -0700824 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) {
825 super(0, unpluggables, in);
826 mCurrentReportedCount = in.readInt();
827 mUnpluggedReportedCount = in.readInt();
828 mCurrentReportedTotalTime = in.readLong();
829 mUnpluggedReportedTotalTime = in.readLong();
830 mTrackingReportedValues = in.readInt() == 1;
831 mInDischarge = inDischarge;
832 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700833
834 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge,
Evan Millarc64edde2009-04-18 12:26:32 -0700835 boolean trackReportedValues) {
836 super(0, unpluggables);
837 mTrackingReportedValues = trackReportedValues;
838 mInDischarge = inDischarge;
839 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700840
Evan Millarc64edde2009-04-18 12:26:32 -0700841 public void setStale() {
842 mTrackingReportedValues = false;
843 mUnpluggedReportedTotalTime = 0;
844 mUnpluggedReportedCount = 0;
845 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700846
Evan Millarc64edde2009-04-18 12:26:32 -0700847 public void setUpdateVersion(int version) {
848 mUpdateVersion = version;
849 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700850
Evan Millarc64edde2009-04-18 12:26:32 -0700851 public int getUpdateVersion() {
852 return mUpdateVersion;
853 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700854
Evan Millarc64edde2009-04-18 12:26:32 -0700855 public void updateCurrentReportedCount(int count) {
856 if (mInDischarge && mUnpluggedReportedCount == 0) {
857 // Updating the reported value for the first time.
858 mUnpluggedReportedCount = count;
859 // If we are receiving an update update mTrackingReportedValues;
860 mTrackingReportedValues = true;
861 }
862 mCurrentReportedCount = count;
863 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700864
Evan Millarc64edde2009-04-18 12:26:32 -0700865 public void updateCurrentReportedTotalTime(long totalTime) {
866 if (mInDischarge && mUnpluggedReportedTotalTime == 0) {
867 // Updating the reported value for the first time.
868 mUnpluggedReportedTotalTime = totalTime;
869 // If we are receiving an update update mTrackingReportedValues;
870 mTrackingReportedValues = true;
871 }
872 mCurrentReportedTotalTime = totalTime;
873 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700874
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800875 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
876 super.unplug(elapsedRealtime, batteryUptime, batteryRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -0700877 if (mTrackingReportedValues) {
878 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
879 mUnpluggedReportedCount = mCurrentReportedCount;
880 }
881 mInDischarge = true;
882 }
883
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800884 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
885 super.plug(elapsedRealtime, batteryUptime, batteryRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -0700886 mInDischarge = false;
887 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700888
Evan Millarc64edde2009-04-18 12:26:32 -0700889 public void logState(Printer pw, String prefix) {
890 super.logState(pw, prefix);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700891 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
Evan Millarc64edde2009-04-18 12:26:32 -0700892 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
893 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
894 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
895 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700896
Evan Millarc64edde2009-04-18 12:26:32 -0700897 protected long computeRunTimeLocked(long curBatteryRealtime) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700898 return mTotalTime + (mInDischarge && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -0700899 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
900 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700901
Evan Millarc64edde2009-04-18 12:26:32 -0700902 protected int computeCurrentCountLocked() {
903 return mCount + (mInDischarge && mTrackingReportedValues
904 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
905 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700906
Evan Millarc64edde2009-04-18 12:26:32 -0700907 public void writeToParcel(Parcel out, long batteryRealtime) {
908 super.writeToParcel(out, batteryRealtime);
909 out.writeInt(mCurrentReportedCount);
910 out.writeInt(mUnpluggedReportedCount);
911 out.writeLong(mCurrentReportedTotalTime);
912 out.writeLong(mUnpluggedReportedTotalTime);
913 out.writeInt(mTrackingReportedValues ? 1 : 0);
914 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700915
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700916 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
917 super.reset(stats, detachIfReset);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700918 setStale();
919 return true;
920 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700921
Evan Millarc64edde2009-04-18 12:26:32 -0700922 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
923 super.writeSummaryFromParcelLocked(out, batteryRealtime);
924 out.writeLong(mCurrentReportedTotalTime);
925 out.writeInt(mCurrentReportedCount);
926 out.writeInt(mTrackingReportedValues ? 1 : 0);
927 }
928
929 void readSummaryFromParcelLocked(Parcel in) {
930 super.readSummaryFromParcelLocked(in);
931 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
932 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
933 mTrackingReportedValues = in.readInt() == 1;
934 }
935 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700936
Evan Millarc64edde2009-04-18 12:26:32 -0700937 /**
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800938 * A timer that increments in batches. It does not run for durations, but just jumps
939 * for a pre-determined amount.
940 */
941 public static final class BatchTimer extends Timer {
942 final Uid mUid;
943
944 /**
945 * The last time at which we updated the timer. This is in elapsed realtime microseconds.
946 */
947 long mLastAddedTime;
948
949 /**
950 * The last duration that we added to the timer. This is in microseconds.
951 */
952 long mLastAddedDuration;
953
954 /**
955 * Whether we are currently in a discharge cycle.
956 */
957 boolean mInDischarge;
958
959 BatchTimer(Uid uid, int type, ArrayList<Unpluggable> unpluggables,
960 boolean inDischarge, Parcel in) {
961 super(type, unpluggables, in);
962 mUid = uid;
963 mLastAddedTime = in.readLong();
964 mLastAddedDuration = in.readLong();
965 mInDischarge = inDischarge;
966 }
967
968 BatchTimer(Uid uid, int type, ArrayList<Unpluggable> unpluggables,
969 boolean inDischarge) {
970 super(type, unpluggables);
971 mUid = uid;
972 mInDischarge = inDischarge;
973 }
974
975 @Override
976 public void writeToParcel(Parcel out, long batteryRealtime) {
977 super.writeToParcel(out, batteryRealtime);
978 out.writeLong(mLastAddedTime);
979 out.writeLong(mLastAddedDuration);
980 }
981
982 @Override
983 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
984 recomputeLastDuration(SystemClock.elapsedRealtime() * 1000, false);
985 mInDischarge = false;
986 super.plug(elapsedRealtime, batteryUptime, batteryRealtime);
987 }
988
989 @Override
990 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
991 recomputeLastDuration(elapsedRealtime, false);
992 mInDischarge = true;
993 // If we are still within the last added duration, then re-added whatever remains.
994 if (mLastAddedTime == elapsedRealtime) {
995 mTotalTime += mLastAddedDuration;
996 }
997 super.unplug(elapsedRealtime, batteryUptime, batteryRealtime);
998 }
999
1000 @Override
1001 public void logState(Printer pw, String prefix) {
1002 super.logState(pw, prefix);
1003 pw.println(prefix + "mLastAddedTime=" + mLastAddedTime
1004 + " mLastAddedDuration=" + mLastAddedDuration);
1005 }
1006
1007 private long computeOverage(long curTime) {
1008 if (mLastAddedTime > 0) {
1009 return mLastTime + mLastAddedDuration - curTime;
1010 }
1011 return 0;
1012 }
1013
1014 private void recomputeLastDuration(long curTime, boolean abort) {
1015 final long overage = computeOverage(curTime);
1016 if (overage > 0) {
1017 // Aborting before the duration ran out -- roll back the remaining
1018 // duration. Only do this if currently discharging; otherwise we didn't
1019 // actually add the time.
1020 if (mInDischarge) {
1021 mTotalTime -= overage;
1022 }
1023 if (abort) {
1024 mLastAddedTime = 0;
1025 } else {
1026 mLastAddedTime = curTime;
1027 mLastAddedDuration -= overage;
1028 }
1029 }
1030 }
1031
1032 public void addDuration(BatteryStatsImpl stats, long durationMillis) {
1033 final long now = SystemClock.elapsedRealtime() * 1000;
1034 recomputeLastDuration(now, true);
1035 mLastAddedTime = now;
1036 mLastAddedDuration = durationMillis * 1000;
1037 if (mInDischarge) {
1038 mTotalTime += mLastAddedDuration;
1039 mCount++;
1040 }
1041 }
1042
1043 public void abortLastDuration(BatteryStatsImpl stats) {
1044 final long now = SystemClock.elapsedRealtime() * 1000;
1045 recomputeLastDuration(now, true);
1046 }
1047
1048 @Override
1049 protected int computeCurrentCountLocked() {
1050 return mCount;
1051 }
1052
1053 @Override
1054 protected long computeRunTimeLocked(long curBatteryRealtime) {
1055 final long overage = computeOverage(SystemClock.elapsedRealtime() * 1000);
1056 if (overage > 0) {
1057 return mTotalTime = overage;
1058 }
1059 return mTotalTime;
1060 }
1061
1062 @Override
1063 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
1064 final long now = SystemClock.elapsedRealtime() * 1000;
1065 recomputeLastDuration(now, true);
1066 boolean stillActive = mLastAddedTime == now;
1067 super.reset(stats, !stillActive && detachIfReset);
1068 return !stillActive;
1069 }
1070 }
1071
1072 /**
Evan Millarc64edde2009-04-18 12:26:32 -07001073 * State for keeping track of timing information.
1074 */
1075 public static final class StopwatchTimer extends Timer {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001076 final Uid mUid;
Evan Millarc64edde2009-04-18 12:26:32 -07001077 final ArrayList<StopwatchTimer> mTimerPool;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001078
Evan Millarc64edde2009-04-18 12:26:32 -07001079 int mNesting;
1080
Evan Millarc64edde2009-04-18 12:26:32 -07001081 /**
1082 * The last time at which we updated the timer. If mNesting is > 0,
1083 * subtract this from the current battery time to find the amount of
1084 * time we have been running since we last computed an update.
1085 */
1086 long mUpdateTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001087
Evan Millarc64edde2009-04-18 12:26:32 -07001088 /**
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001089 * The total time at which the timer was acquired, to determine if it
Evan Millarc64edde2009-04-18 12:26:32 -07001090 * was actually held for an interesting duration.
1091 */
1092 long mAcquireTime;
Evan Millarc64edde2009-04-18 12:26:32 -07001093
Amith Yamasanif37447b2009-10-08 18:28:01 -07001094 long mTimeout;
1095
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001096 /**
1097 * For partial wake locks, keep track of whether we are in the list
1098 * to consume CPU cycles.
1099 */
1100 boolean mInList;
1101
1102 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Evan Millarc64edde2009-04-18 12:26:32 -07001103 ArrayList<Unpluggable> unpluggables, Parcel in) {
1104 super(type, unpluggables, in);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001105 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001106 mTimerPool = timerPool;
1107 mUpdateTime = in.readLong();
1108 }
1109
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001110 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Evan Millarc64edde2009-04-18 12:26:32 -07001111 ArrayList<Unpluggable> unpluggables) {
1112 super(type, unpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001113 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001114 mTimerPool = timerPool;
1115 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001116
Amith Yamasanif37447b2009-10-08 18:28:01 -07001117 void setTimeout(long timeout) {
1118 mTimeout = timeout;
1119 }
1120
Evan Millarc64edde2009-04-18 12:26:32 -07001121 public void writeToParcel(Parcel out, long batteryRealtime) {
1122 super.writeToParcel(out, batteryRealtime);
1123 out.writeLong(mUpdateTime);
1124 }
1125
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001126 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -07001127 if (mNesting > 0) {
1128 if (DEBUG && mType < 0) {
1129 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
1130 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001131 super.plug(elapsedRealtime, batteryUptime, batteryRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -07001132 mUpdateTime = batteryRealtime;
1133 if (DEBUG && mType < 0) {
1134 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
1135 }
1136 }
1137 }
1138
1139 public void logState(Printer pw, String prefix) {
1140 super.logState(pw, prefix);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07001141 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001142 + " mAcquireTime=" + mAcquireTime);
1143 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001145 void startRunningLocked(BatteryStatsImpl stats) {
1146 if (mNesting++ == 0) {
1147 mUpdateTime = stats.getBatteryRealtimeLocked(
1148 SystemClock.elapsedRealtime() * 1000);
1149 if (mTimerPool != null) {
1150 // Accumulate time to all currently active timers before adding
1151 // this new one to the pool.
1152 refreshTimersLocked(stats, mTimerPool);
1153 // Add this timer to the active pool
1154 mTimerPool.add(this);
1155 }
1156 // Increment the count
1157 mCount++;
1158 mAcquireTime = mTotalTime;
1159 if (DEBUG && mType < 0) {
1160 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
1161 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
1162 + " mAcquireTime=" + mAcquireTime);
1163 }
1164 }
1165 }
1166
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001167 boolean isRunningLocked() {
1168 return mNesting > 0;
1169 }
1170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001171 void stopRunningLocked(BatteryStatsImpl stats) {
1172 // Ignore attempt to stop a timer that isn't running
1173 if (mNesting == 0) {
1174 return;
1175 }
1176 if (--mNesting == 0) {
1177 if (mTimerPool != null) {
1178 // Accumulate time to all active counters, scaled by the total
1179 // active in the pool, before taking this one out of the pool.
1180 refreshTimersLocked(stats, mTimerPool);
1181 // Remove this timer from the active pool
1182 mTimerPool.remove(this);
1183 } else {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001184 final long realtime = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001185 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
1186 mNesting = 1;
1187 mTotalTime = computeRunTimeLocked(batteryRealtime);
1188 mNesting = 0;
1189 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001190
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001191 if (DEBUG && mType < 0) {
1192 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
1193 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
1194 + " mAcquireTime=" + mAcquireTime);
1195 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001196
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001197 if (mTotalTime == mAcquireTime) {
1198 // If there was no change in the time, then discard this
1199 // count. A somewhat cheezy strategy, but hey.
1200 mCount--;
1201 }
1202 }
1203 }
1204
1205 // Update the total time for all other running Timers with the same type as this Timer
1206 // due to a change in timer count
1207 private static void refreshTimersLocked(final BatteryStatsImpl stats,
Evan Millarc64edde2009-04-18 12:26:32 -07001208 final ArrayList<StopwatchTimer> pool) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001209 final long realtime = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001210 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
1211 final int N = pool.size();
1212 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -07001213 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001214 long heldTime = batteryRealtime - t.mUpdateTime;
1215 if (heldTime > 0) {
1216 t.mTotalTime += heldTime / N;
1217 }
1218 t.mUpdateTime = batteryRealtime;
1219 }
1220 }
1221
Evan Millarc64edde2009-04-18 12:26:32 -07001222 @Override
1223 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07001224 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
1225 curBatteryRealtime = mUpdateTime + mTimeout;
1226 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001227 return mTotalTime + (mNesting > 0
1228 ? (curBatteryRealtime - mUpdateTime)
1229 / (mTimerPool != null ? mTimerPool.size() : 1)
1230 : 0);
1231 }
1232
Evan Millarc64edde2009-04-18 12:26:32 -07001233 @Override
1234 protected int computeCurrentCountLocked() {
1235 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001236 }
1237
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001238 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001239 boolean canDetach = mNesting <= 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001240 super.reset(stats, canDetach && detachIfReset);
1241 if (mNesting > 0) {
1242 mUpdateTime = stats.getBatteryRealtimeLocked(
1243 SystemClock.elapsedRealtime() * 1000);
1244 }
1245 mAcquireTime = mTotalTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001246 return canDetach;
1247 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001248
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001249 void detach() {
1250 super.detach();
1251 if (mTimerPool != null) {
1252 mTimerPool.remove(this);
1253 }
1254 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001256 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -07001257 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001258 mNesting = 0;
1259 }
1260 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001261
Evan Millarc64edde2009-04-18 12:26:32 -07001262 private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001263
Todd Poynor73f534a2012-06-19 11:07:26 -07001264 FileInputStream is;
Johannes Carlsson3372f2e2010-06-30 08:45:55 +02001265 byte[] buffer = new byte[8192];
Evan Millarc64edde2009-04-18 12:26:32 -07001266 int len;
Todd Poynor73f534a2012-06-19 11:07:26 -07001267 boolean wakeup_sources = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001268
Evan Millarc64edde2009-04-18 12:26:32 -07001269 try {
Todd Poynor73f534a2012-06-19 11:07:26 -07001270 try {
1271 is = new FileInputStream("/proc/wakelocks");
1272 } catch (java.io.FileNotFoundException e) {
1273 try {
1274 is = new FileInputStream("/d/wakeup_sources");
1275 wakeup_sources = true;
1276 } catch (java.io.FileNotFoundException e2) {
1277 return null;
Evan Millarc64edde2009-04-18 12:26:32 -07001278 }
1279 }
Todd Poynor73f534a2012-06-19 11:07:26 -07001280
1281 len = is.read(buffer);
1282 is.close();
Evan Millarc64edde2009-04-18 12:26:32 -07001283 } catch (java.io.IOException e) {
1284 return null;
1285 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001286
Todd Poynor73f534a2012-06-19 11:07:26 -07001287 if (len > 0) {
1288 int i;
1289 for (i=0; i<len; i++) {
1290 if (buffer[i] == '\0') {
1291 len = i;
1292 break;
1293 }
1294 }
1295 }
1296
1297 return parseProcWakelocks(buffer, len, wakeup_sources);
Evan Millarc64edde2009-04-18 12:26:32 -07001298 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001299
Evan Millarc64edde2009-04-18 12:26:32 -07001300 private final Map<String, KernelWakelockStats> parseProcWakelocks(
Todd Poynor73f534a2012-06-19 11:07:26 -07001301 byte[] wlBuffer, int len, boolean wakeup_sources) {
Evan Millarc64edde2009-04-18 12:26:32 -07001302 String name;
1303 int count;
1304 long totalTime;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001305 int startIndex;
1306 int endIndex;
Evan Millarc64edde2009-04-18 12:26:32 -07001307 int numUpdatedWlNames = 0;
1308
1309 // Advance past the first line.
1310 int i;
1311 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++);
1312 startIndex = endIndex = i + 1;
1313
1314 synchronized(this) {
1315 Map<String, KernelWakelockStats> m = mProcWakelockFileStats;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001316
Evan Millarc64edde2009-04-18 12:26:32 -07001317 sKernelWakelockUpdateVersion++;
1318 while (endIndex < len) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001319 for (endIndex=startIndex;
1320 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
Evan Millarc64edde2009-04-18 12:26:32 -07001321 endIndex++);
Johannes Carlsson3372f2e2010-06-30 08:45:55 +02001322 endIndex++; // endIndex is an exclusive upper bound.
1323 // Don't go over the end of the buffer, Process.parseProcLine might
1324 // write to wlBuffer[endIndex]
1325 if (endIndex >= (len - 1) ) {
1326 return m;
Amith Yamasanie5795612010-04-05 12:43:44 -07001327 }
Evan Millarc64edde2009-04-18 12:26:32 -07001328
1329 String[] nameStringArray = mProcWakelocksName;
1330 long[] wlData = mProcWakelocksData;
Amith Yamasani2098ead2010-04-02 13:46:49 -07001331 // Stomp out any bad characters since this is from a circular buffer
1332 // A corruption is seen sometimes that results in the vm crashing
1333 // This should prevent crashes and the line will probably fail to parse
1334 for (int j = startIndex; j < endIndex; j++) {
1335 if ((wlBuffer[j] & 0x80) != 0) wlBuffer[j] = (byte) '?';
1336 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001337 boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex,
Todd Poynor73f534a2012-06-19 11:07:26 -07001338 wakeup_sources ? WAKEUP_SOURCES_FORMAT :
1339 PROC_WAKELOCKS_FORMAT,
1340 nameStringArray, wlData, null);
Amith Yamasani2098ead2010-04-02 13:46:49 -07001341
Evan Millarc64edde2009-04-18 12:26:32 -07001342 name = nameStringArray[0];
1343 count = (int) wlData[1];
Todd Poynor73f534a2012-06-19 11:07:26 -07001344
1345 if (wakeup_sources) {
1346 // convert milliseconds to microseconds
1347 totalTime = wlData[2] * 1000;
1348 } else {
1349 // convert nanoseconds to microseconds with rounding.
1350 totalTime = (wlData[2] + 500) / 1000;
1351 }
Evan Millarc64edde2009-04-18 12:26:32 -07001352
Amith Yamasani53b707b2009-09-30 11:05:30 -07001353 if (parsed && name.length() > 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001354 if (!m.containsKey(name)) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001355 m.put(name, new KernelWakelockStats(count, totalTime,
Evan Millarc64edde2009-04-18 12:26:32 -07001356 sKernelWakelockUpdateVersion));
1357 numUpdatedWlNames++;
1358 } else {
1359 KernelWakelockStats kwlStats = m.get(name);
1360 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) {
1361 kwlStats.mCount += count;
1362 kwlStats.mTotalTime += totalTime;
1363 } else {
1364 kwlStats.mCount = count;
1365 kwlStats.mTotalTime = totalTime;
1366 kwlStats.mVersion = sKernelWakelockUpdateVersion;
1367 numUpdatedWlNames++;
1368 }
1369 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001370 }
Evan Millarc64edde2009-04-18 12:26:32 -07001371 startIndex = endIndex;
1372 }
1373
1374 if (m.size() != numUpdatedWlNames) {
1375 // Don't report old data.
1376 Iterator<KernelWakelockStats> itr = m.values().iterator();
1377 while (itr.hasNext()) {
1378 if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
1379 itr.remove();
1380 }
1381 }
1382 }
1383 return m;
1384 }
1385 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001386
Evan Millarc64edde2009-04-18 12:26:32 -07001387 private class KernelWakelockStats {
1388 public int mCount;
1389 public long mTotalTime;
1390 public int mVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001391
Evan Millarc64edde2009-04-18 12:26:32 -07001392 KernelWakelockStats(int count, long totalTime, int version) {
1393 mCount = count;
1394 mTotalTime = totalTime;
1395 mVersion = version;
1396 }
1397 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001398
Evan Millarc64edde2009-04-18 12:26:32 -07001399 /*
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001400 * Get the KernelWakelockTimer associated with name, and create a new one if one
Evan Millarc64edde2009-04-18 12:26:32 -07001401 * doesn't already exist.
1402 */
1403 public SamplingTimer getKernelWakelockTimerLocked(String name) {
1404 SamplingTimer kwlt = mKernelWakelockStats.get(name);
1405 if (kwlt == null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001406 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
Evan Millarc64edde2009-04-18 12:26:32 -07001407 true /* track reported values */);
1408 mKernelWakelockStats.put(name, kwlt);
1409 }
1410 return kwlt;
1411 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001412
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001413 /**
1414 * Radio uptime in microseconds when transferring data. This value is very approximate.
1415 * @return
1416 */
1417 private long getCurrentRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001418 try {
1419 File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms");
1420 if (!awakeTimeFile.exists()) return 0;
1421 BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile));
1422 String line = br.readLine();
1423 br.close();
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001424 return Long.parseLong(line) * 1000;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001425 } catch (NumberFormatException nfe) {
1426 // Nothing
1427 } catch (IOException ioe) {
1428 // Nothing
1429 }
1430 return 0;
1431 }
1432
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001433 /**
1434 * @deprecated use getRadioDataUptime
1435 */
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001436 public long getRadioDataUptimeMs() {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001437 return getRadioDataUptime() / 1000;
1438 }
1439
1440 /**
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001441 * Returns the duration that the cell radio was up for data transfers.
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001442 */
1443 public long getRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001444 if (mRadioDataStart == -1) {
1445 return mRadioDataUptime;
1446 } else {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001447 return getCurrentRadioDataUptime() - mRadioDataStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001448 }
1449 }
1450
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001451 private int getCurrentBluetoothPingCount() {
1452 if (mBtHeadset != null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001453 List<BluetoothDevice> deviceList = mBtHeadset.getConnectedDevices();
1454 if (deviceList.size() > 0) {
1455 return mBtHeadset.getBatteryUsageHint(deviceList.get(0));
Jaikumar Ganesh3f034962010-09-27 17:02:23 -07001456 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001457 }
1458 return -1;
1459 }
1460
1461 public int getBluetoothPingCount() {
1462 if (mBluetoothPingStart == -1) {
1463 return mBluetoothPingCount;
1464 } else if (mBtHeadset != null) {
1465 return getCurrentBluetoothPingCount() - mBluetoothPingStart;
1466 }
Amith Yamasani82cb0292009-08-18 11:29:28 -07001467 return 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001468 }
1469
1470 public void setBtHeadset(BluetoothHeadset headset) {
Amith Yamasani82cb0292009-08-18 11:29:28 -07001471 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) {
1472 mBluetoothPingStart = getCurrentBluetoothPingCount();
1473 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001474 mBtHeadset = headset;
1475 }
1476
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001477 int mChangedBufferStates = 0;
1478
1479 void addHistoryBufferLocked(long curTime) {
1480 if (!mHaveBatteryLevel || !mRecordingHistory) {
1481 return;
1482 }
1483
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001484 final long timeDiff = (mHistoryBaseTime+curTime) - mHistoryLastWritten.time;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001485 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001486 && timeDiff < 2000
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001487 && ((mHistoryLastWritten.states^mHistoryCur.states)&mChangedBufferStates) == 0) {
1488 // If the current is the same as the one before, then we no
1489 // longer need the entry.
1490 mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
1491 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
1492 mHistoryBufferLastPos = -1;
1493 if (mHistoryLastLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001494 && timeDiff < 500 && mHistoryLastLastWritten.same(mHistoryCur)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001495 // If this results in us returning to the state written
1496 // prior to the last one, then we can just delete the last
1497 // written one and drop the new one. Nothing more to do.
1498 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
1499 mHistoryLastLastWritten.cmd = HistoryItem.CMD_NULL;
1500 return;
1501 }
1502 mChangedBufferStates |= mHistoryLastWritten.states^mHistoryCur.states;
1503 curTime = mHistoryLastWritten.time - mHistoryBaseTime;
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001504 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001505 } else {
1506 mChangedBufferStates = 0;
1507 }
1508
1509 final int dataSize = mHistoryBuffer.dataSize();
1510 if (dataSize >= MAX_HISTORY_BUFFER) {
1511 if (!mHistoryOverflow) {
1512 mHistoryOverflow = true;
1513 addHistoryBufferLocked(curTime, HistoryItem.CMD_OVERFLOW);
1514 }
1515
1516 // Once we've reached the maximum number of items, we only
1517 // record changes to the battery level and the most interesting states.
1518 // Once we've reached the maximum maximum number of items, we only
1519 // record changes to the battery level.
1520 if (mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel &&
1521 (dataSize >= MAX_MAX_HISTORY_BUFFER
Amith Yamasani45f06462011-11-21 16:08:34 -08001522 || ((mHistoryLastWritten.states^mHistoryCur.states)
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001523 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
1524 return;
1525 }
1526 }
1527
1528 addHistoryBufferLocked(curTime, HistoryItem.CMD_UPDATE);
1529 }
1530
1531 void addHistoryBufferLocked(long curTime, byte cmd) {
1532 int origPos = 0;
1533 if (mIteratingHistory) {
1534 origPos = mHistoryBuffer.dataPosition();
1535 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
1536 }
1537 mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
1538 mHistoryLastLastWritten.setTo(mHistoryLastWritten);
1539 mHistoryLastWritten.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur);
1540 mHistoryLastWritten.writeDelta(mHistoryBuffer, mHistoryLastLastWritten);
1541 mLastHistoryTime = curTime;
1542 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
1543 + " now " + mHistoryBuffer.dataPosition()
1544 + " size is now " + mHistoryBuffer.dataSize());
1545 if (mIteratingHistory) {
1546 mHistoryBuffer.setDataPosition(origPos);
1547 }
1548 }
1549
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001550 int mChangedStates = 0;
1551
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001552 void addHistoryRecordLocked(long curTime) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001553 addHistoryBufferLocked(curTime);
1554
Dianne Hackborne8c88e62011-08-17 19:09:09 -07001555 if (!USE_OLD_HISTORY) {
1556 return;
1557 }
1558
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001559 if (!mHaveBatteryLevel || !mRecordingHistory) {
1560 return;
1561 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001562
1563 // If the current time is basically the same as the last time,
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001564 // and no states have since the last recorded entry changed and
1565 // are now resetting back to their original value, then just collapse
1566 // into one record.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001567 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001568 && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+2000)
1569 && ((mHistoryEnd.states^mHistoryCur.states)&mChangedStates) == 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001570 // If the current is the same as the one before, then we no
1571 // longer need the entry.
1572 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn1fadab52011-04-14 17:57:33 -07001573 && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+500)
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001574 && mHistoryLastEnd.same(mHistoryCur)) {
1575 mHistoryLastEnd.next = null;
1576 mHistoryEnd.next = mHistoryCache;
1577 mHistoryCache = mHistoryEnd;
1578 mHistoryEnd = mHistoryLastEnd;
1579 mHistoryLastEnd = null;
1580 } else {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001581 mChangedStates |= mHistoryEnd.states^mHistoryCur.states;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001582 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, mHistoryCur);
1583 }
1584 return;
1585 }
1586
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001587 mChangedStates = 0;
1588
1589 if (mNumHistoryItems == MAX_HISTORY_ITEMS
1590 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07001591 addHistoryRecordLocked(curTime, HistoryItem.CMD_OVERFLOW);
1592 }
1593
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001594 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
1595 // Once we've reached the maximum number of items, we only
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001596 // record changes to the battery level and the most interesting states.
1597 // Once we've reached the maximum maximum number of items, we only
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001598 // record changes to the battery level.
1599 if (mHistoryEnd != null && mHistoryEnd.batteryLevel
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07001600 == mHistoryCur.batteryLevel &&
1601 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
1602 || ((mHistoryEnd.states^mHistoryCur.states)
1603 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001604 return;
1605 }
1606 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001607
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001608 addHistoryRecordLocked(curTime, HistoryItem.CMD_UPDATE);
1609 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001610
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001611 void addHistoryRecordLocked(long curTime, byte cmd) {
1612 HistoryItem rec = mHistoryCache;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001613 if (rec != null) {
1614 mHistoryCache = rec.next;
1615 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001616 rec = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001617 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001618 rec.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001619
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001620 addHistoryRecordLocked(rec);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001621 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001622
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001623 void addHistoryRecordLocked(HistoryItem rec) {
1624 mNumHistoryItems++;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001625 rec.next = null;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001626 mHistoryLastEnd = mHistoryEnd;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001627 if (mHistoryEnd != null) {
1628 mHistoryEnd.next = rec;
1629 mHistoryEnd = rec;
1630 } else {
1631 mHistory = mHistoryEnd = rec;
1632 }
1633 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001634
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001635 void clearHistoryLocked() {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001636 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
Dianne Hackborne8c88e62011-08-17 19:09:09 -07001637 if (USE_OLD_HISTORY) {
1638 if (mHistory != null) {
1639 mHistoryEnd.next = mHistoryCache;
1640 mHistoryCache = mHistory;
1641 mHistory = mHistoryLastEnd = mHistoryEnd = null;
1642 }
1643 mNumHistoryItems = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001644 }
Dianne Hackborne8c88e62011-08-17 19:09:09 -07001645
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001646 mHistoryBaseTime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001647 mLastHistoryTime = 0;
1648
1649 mHistoryBuffer.setDataSize(0);
1650 mHistoryBuffer.setDataPosition(0);
1651 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER/2);
1652 mHistoryLastLastWritten.cmd = HistoryItem.CMD_NULL;
1653 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL;
1654 mHistoryBufferLastPos = -1;
1655 mHistoryOverflow = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001656 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001657
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001658 public void doUnplugLocked(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001659 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001660 mUnpluggables.get(i).unplug(elapsedRealtime, batteryUptime, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001661 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001662
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001663 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001664 mRadioDataStart = getCurrentRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001665 mRadioDataUptime = 0;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001666
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001667 // Track bt headset ping count
1668 mBluetoothPingStart = getCurrentBluetoothPingCount();
1669 mBluetoothPingCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001670 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001671
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001672 public void doPlugLocked(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001673 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001674 mUnpluggables.get(i).plug(elapsedRealtime, batteryUptime, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001675 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001676
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001677 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001678 mRadioDataUptime = getRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001679 mRadioDataStart = -1;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001680
1681 // Track bt headset ping count
1682 mBluetoothPingCount = getBluetoothPingCount();
1683 mBluetoothPingStart = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001684 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001685
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001686 int mWakeLockNesting;
1687
1688 public void noteStartWakeLocked(int uid, int pid, String name, int type) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001689 if (type == WAKE_TYPE_PARTIAL) {
1690 // Only care about partial wake locks, since full wake locks
1691 // will be canceled when the user puts the screen to sleep.
1692 if (mWakeLockNesting == 0) {
1693 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
1694 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
1695 + Integer.toHexString(mHistoryCur.states));
1696 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1697 }
1698 mWakeLockNesting++;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001699 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001700 if (uid >= 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001701 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
1702 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
1703 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
1704 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001705 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type);
1706 }
1707 }
1708
1709 public void noteStopWakeLocked(int uid, int pid, String name, int type) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001710 if (type == WAKE_TYPE_PARTIAL) {
1711 mWakeLockNesting--;
1712 if (mWakeLockNesting == 0) {
1713 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
1714 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
1715 + Integer.toHexString(mHistoryCur.states));
1716 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1717 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001718 }
1719 if (uid >= 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001720 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
1721 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
1722 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
1723 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001724 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type);
1725 }
1726 }
1727
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07001728 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
1729 int N = ws.size();
1730 for (int i=0; i<N; i++) {
1731 noteStartWakeLocked(ws.get(i), pid, name, type);
1732 }
1733 }
1734
1735 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
1736 int N = ws.size();
1737 for (int i=0; i<N; i++) {
1738 noteStopWakeLocked(ws.get(i), pid, name, type);
1739 }
1740 }
1741
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001742 public int startAddingCpuLocked() {
1743 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
1744
1745 if (mScreenOn) {
1746 return 0;
1747 }
1748
1749 final int N = mPartialTimers.size();
1750 if (N == 0) {
1751 mLastPartialTimers.clear();
1752 return 0;
1753 }
1754
1755 // How many timers should consume CPU? Only want to include ones
1756 // that have already been in the list.
1757 for (int i=0; i<N; i++) {
1758 StopwatchTimer st = mPartialTimers.get(i);
1759 if (st.mInList) {
1760 Uid uid = st.mUid;
1761 // We don't include the system UID, because it so often
1762 // holds wake locks at one request or another of an app.
1763 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
1764 return 50;
1765 }
1766 }
1767 }
1768
1769 return 0;
1770 }
1771
1772 public void finishAddingCpuLocked(int perc, int utime, int stime, long[] cpuSpeedTimes) {
1773 final int N = mPartialTimers.size();
1774 if (perc != 0) {
1775 int num = 0;
1776 for (int i=0; i<N; i++) {
1777 StopwatchTimer st = mPartialTimers.get(i);
1778 if (st.mInList) {
1779 Uid uid = st.mUid;
1780 // We don't include the system UID, because it so often
1781 // holds wake locks at one request or another of an app.
1782 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
1783 num++;
1784 }
1785 }
1786 }
1787 if (num != 0) {
1788 for (int i=0; i<N; i++) {
1789 StopwatchTimer st = mPartialTimers.get(i);
1790 if (st.mInList) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001791 Uid uid = st.mUid;
1792 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
Dianne Hackborn618b8c12010-09-09 23:10:38 -07001793 int myUTime = utime/num;
1794 int mySTime = stime/num;
1795 utime -= myUTime;
1796 stime -= mySTime;
1797 num--;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001798 Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*");
1799 proc.addCpuTimeLocked(myUTime, mySTime);
1800 proc.addSpeedStepTimes(cpuSpeedTimes);
1801 }
1802 }
1803 }
1804 }
1805
1806 // Just in case, collect any lost CPU time.
1807 if (utime != 0 || stime != 0) {
1808 Uid uid = getUidStatsLocked(Process.SYSTEM_UID);
1809 if (uid != null) {
1810 Uid.Proc proc = uid.getProcessStatsLocked("*lost*");
1811 proc.addCpuTimeLocked(utime, stime);
1812 proc.addSpeedStepTimes(cpuSpeedTimes);
1813 }
1814 }
1815 }
1816
1817 final int NL = mLastPartialTimers.size();
1818 boolean diff = N != NL;
1819 for (int i=0; i<NL && !diff; i++) {
1820 diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i);
1821 }
1822 if (!diff) {
1823 for (int i=0; i<NL; i++) {
1824 mPartialTimers.get(i).mInList = true;
1825 }
1826 return;
1827 }
1828
1829 for (int i=0; i<NL; i++) {
1830 mLastPartialTimers.get(i).mInList = false;
1831 }
1832 mLastPartialTimers.clear();
1833 for (int i=0; i<N; i++) {
1834 StopwatchTimer st = mPartialTimers.get(i);
1835 st.mInList = true;
1836 mLastPartialTimers.add(st);
1837 }
1838 }
1839
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001840 public void noteProcessDiedLocked(int uid, int pid) {
1841 Uid u = mUidStats.get(uid);
1842 if (u != null) {
1843 u.mPids.remove(pid);
1844 }
1845 }
1846
1847 public long getProcessWakeTime(int uid, int pid, long realtime) {
1848 Uid u = mUidStats.get(uid);
1849 if (u != null) {
1850 Uid.Pid p = u.mPids.get(pid);
1851 if (p != null) {
1852 return p.mWakeSum + (p.mWakeStart != 0 ? (realtime - p.mWakeStart) : 0);
1853 }
1854 }
1855 return 0;
1856 }
1857
1858 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) {
1859 Uid u = mUidStats.get(uid);
1860 if (u != null) {
1861 u.reportExcessiveWakeLocked(proc, overTime, usedTime);
1862 }
1863 }
1864
Dianne Hackborn287952c2010-09-22 22:34:31 -07001865 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
1866 Uid u = mUidStats.get(uid);
1867 if (u != null) {
1868 u.reportExcessiveCpuLocked(proc, overTime, usedTime);
1869 }
1870 }
1871
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001872 int mSensorNesting;
1873
1874 public void noteStartSensorLocked(int uid, int sensor) {
1875 if (mSensorNesting == 0) {
1876 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
1877 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
1878 + Integer.toHexString(mHistoryCur.states));
1879 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1880 }
1881 mSensorNesting++;
1882 getUidStatsLocked(uid).noteStartSensor(sensor);
1883 }
1884
1885 public void noteStopSensorLocked(int uid, int sensor) {
1886 mSensorNesting--;
1887 if (mSensorNesting == 0) {
1888 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
1889 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
1890 + Integer.toHexString(mHistoryCur.states));
1891 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1892 }
1893 getUidStatsLocked(uid).noteStopSensor(sensor);
1894 }
1895
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001896 int mGpsNesting;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001897
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001898 public void noteStartGpsLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001899 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001900 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001901 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
1902 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001903 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001904 }
1905 mGpsNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07001906 getUidStatsLocked(uid).noteStartGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001907 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001908
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001909 public void noteStopGpsLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001910 mGpsNesting--;
1911 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001912 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001913 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
1914 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001915 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001916 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001917 getUidStatsLocked(uid).noteStopGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001918 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001919
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001920 public void noteScreenOnLocked() {
1921 if (!mScreenOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001922 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001923 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
1924 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001925 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001926 mScreenOn = true;
1927 mScreenOnTimer.startRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001928 if (mScreenBrightnessBin >= 0) {
1929 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this);
1930 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001931
1932 // Fake a wake lock, so we consider the device waked as long
1933 // as the screen is on.
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001934 noteStartWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001935
1936 // Update discharge amounts.
1937 if (mOnBatteryInternal) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08001938 updateDischargeScreenLevelsLocked(false, true);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001939 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001940 }
1941 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001943 public void noteScreenOffLocked() {
1944 if (mScreenOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001945 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001946 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
1947 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001948 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001949 mScreenOn = false;
1950 mScreenOnTimer.stopRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001951 if (mScreenBrightnessBin >= 0) {
1952 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1953 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001954
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001955 noteStopWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001956
1957 // Update discharge amounts.
1958 if (mOnBatteryInternal) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08001959 updateDischargeScreenLevelsLocked(true, false);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001960 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001961 }
1962 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001963
Dianne Hackborn617f8772009-03-31 15:04:46 -07001964 public void noteScreenBrightnessLocked(int brightness) {
1965 // Bin the brightness.
1966 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
1967 if (bin < 0) bin = 0;
1968 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
1969 if (mScreenBrightnessBin != bin) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001970 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
1971 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001972 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
1973 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001974 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn617f8772009-03-31 15:04:46 -07001975 if (mScreenOn) {
1976 if (mScreenBrightnessBin >= 0) {
1977 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1978 }
1979 mScreenBrightnessTimer[bin].startRunningLocked(this);
1980 }
1981 mScreenBrightnessBin = bin;
1982 }
1983 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001984
Christopher Tate4cee7252010-03-19 14:50:40 -07001985 public void noteInputEventAtomic() {
1986 mInputEventCounter.stepAtomic();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001987 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001988
Dianne Hackborn617f8772009-03-31 15:04:46 -07001989 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001990 getUidStatsLocked(uid).noteUserActivityLocked(event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001991 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001992
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001993 public void notePhoneOnLocked() {
1994 if (!mPhoneOn) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001995 mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001996 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
1997 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001998 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001999 mPhoneOn = true;
2000 mPhoneOnTimer.startRunningLocked(this);
2001 }
2002 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002003
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002004 public void notePhoneOffLocked() {
2005 if (mPhoneOn) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002006 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002007 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
2008 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002009 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002010 mPhoneOn = false;
2011 mPhoneOnTimer.stopRunningLocked(this);
2012 }
2013 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002014
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002015 void stopAllSignalStrengthTimersLocked(int except) {
Wink Saville52840902011-02-18 12:40:47 -08002016 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002017 if (i == except) {
2018 continue;
2019 }
2020 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
2021 mPhoneSignalStrengthsTimer[i].stopRunningLocked(this);
2022 }
2023 }
2024 }
2025
Dianne Hackborne4a59512010-12-07 11:08:07 -08002026 private int fixPhoneServiceState(int state, int signalBin) {
2027 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
2028 // In this case we will always be STATE_OUT_OF_SERVICE, so need
2029 // to infer that we are scanning from other data.
2030 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08002031 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002032 state = ServiceState.STATE_IN_SERVICE;
2033 }
2034 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002035
Dianne Hackborne4a59512010-12-07 11:08:07 -08002036 return state;
2037 }
2038
2039 private void updateAllPhoneStateLocked(int state, int simState, int bin) {
2040 boolean scanning = false;
2041 boolean newHistory = false;
2042
2043 mPhoneServiceStateRaw = state;
2044 mPhoneSimStateRaw = simState;
2045 mPhoneSignalStrengthBinRaw = bin;
2046
2047 if (simState == TelephonyManager.SIM_STATE_ABSENT) {
2048 // In this case we will always be STATE_OUT_OF_SERVICE, so need
2049 // to infer that we are scanning from other data.
2050 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08002051 && bin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002052 state = ServiceState.STATE_IN_SERVICE;
2053 }
2054 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002055
2056 // If the phone is powered off, stop all timers.
2057 if (state == ServiceState.STATE_POWER_OFF) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08002058 bin = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -07002059
Dianne Hackborne4a59512010-12-07 11:08:07 -08002060 // If we are in service, make sure the correct signal string timer is running.
2061 } else if (state == ServiceState.STATE_IN_SERVICE) {
2062 // Bin will be changed below.
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002063
2064 // If we're out of service, we are in the lowest signal strength
2065 // bin and have the scanning bit set.
Amith Yamasanif37447b2009-10-08 18:28:01 -07002066 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002067 scanning = true;
Wink Saville52840902011-02-18 12:40:47 -08002068 bin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Amith Yamasanif37447b2009-10-08 18:28:01 -07002069 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002070 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
Dianne Hackborne4a59512010-12-07 11:08:07 -08002071 newHistory = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002072 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
2073 + Integer.toHexString(mHistoryCur.states));
Amith Yamasanif37447b2009-10-08 18:28:01 -07002074 mPhoneSignalScanningTimer.startRunningLocked(this);
2075 }
2076 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002077
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002078 if (!scanning) {
2079 // If we are no longer scanning, then stop the scanning timer.
2080 if (mPhoneSignalScanningTimer.isRunningLocked()) {
2081 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
2082 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
2083 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08002084 newHistory = true;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002085 mPhoneSignalScanningTimer.stopRunningLocked(this);
2086 }
2087 }
2088
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002089 if (mPhoneServiceState != state) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002090 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
2091 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
Dianne Hackborne4a59512010-12-07 11:08:07 -08002092 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002093 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08002094 newHistory = true;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002095 mPhoneServiceState = state;
2096 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08002097
2098 if (mPhoneSignalStrengthBin != bin) {
2099 if (mPhoneSignalStrengthBin >= 0) {
2100 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
2101 }
2102 if (bin >= 0) {
2103 if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
2104 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
2105 }
2106 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
2107 | (bin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
2108 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: "
2109 + Integer.toHexString(mHistoryCur.states));
2110 newHistory = true;
2111 } else {
2112 stopAllSignalStrengthTimersLocked(-1);
2113 }
2114 mPhoneSignalStrengthBin = bin;
2115 }
2116
2117 if (newHistory) {
2118 addHistoryRecordLocked(SystemClock.elapsedRealtime());
2119 }
2120 }
2121
2122 /**
2123 * Telephony stack updates the phone state.
2124 * @param state phone state from ServiceState.getState()
2125 */
2126 public void notePhoneStateLocked(int state, int simState) {
2127 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002128 }
2129
Wink Savillee9b06d72009-05-18 21:47:50 -07002130 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07002131 // Bin the strength.
Wink Saville52840902011-02-18 12:40:47 -08002132 int bin = signalStrength.getLevel();
Dianne Hackborne4a59512010-12-07 11:08:07 -08002133 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002134 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002135
Dianne Hackborn627bba72009-03-24 22:32:56 -07002136 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
2137 int bin = DATA_CONNECTION_NONE;
2138 if (hasData) {
2139 switch (dataType) {
2140 case TelephonyManager.NETWORK_TYPE_EDGE:
2141 bin = DATA_CONNECTION_EDGE;
2142 break;
2143 case TelephonyManager.NETWORK_TYPE_GPRS:
2144 bin = DATA_CONNECTION_GPRS;
2145 break;
2146 case TelephonyManager.NETWORK_TYPE_UMTS:
2147 bin = DATA_CONNECTION_UMTS;
2148 break;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002149 case TelephonyManager.NETWORK_TYPE_CDMA:
2150 bin = DATA_CONNECTION_CDMA;
2151 break;
2152 case TelephonyManager.NETWORK_TYPE_EVDO_0:
2153 bin = DATA_CONNECTION_EVDO_0;
2154 break;
2155 case TelephonyManager.NETWORK_TYPE_EVDO_A:
2156 bin = DATA_CONNECTION_EVDO_A;
2157 break;
2158 case TelephonyManager.NETWORK_TYPE_1xRTT:
2159 bin = DATA_CONNECTION_1xRTT;
2160 break;
2161 case TelephonyManager.NETWORK_TYPE_HSDPA:
2162 bin = DATA_CONNECTION_HSDPA;
2163 break;
2164 case TelephonyManager.NETWORK_TYPE_HSUPA:
2165 bin = DATA_CONNECTION_HSUPA;
2166 break;
2167 case TelephonyManager.NETWORK_TYPE_HSPA:
2168 bin = DATA_CONNECTION_HSPA;
2169 break;
2170 case TelephonyManager.NETWORK_TYPE_IDEN:
2171 bin = DATA_CONNECTION_IDEN;
2172 break;
2173 case TelephonyManager.NETWORK_TYPE_EVDO_B:
2174 bin = DATA_CONNECTION_EVDO_B;
2175 break;
Robert Greenwalt962a9902010-11-02 11:10:25 -07002176 case TelephonyManager.NETWORK_TYPE_LTE:
2177 bin = DATA_CONNECTION_LTE;
2178 break;
2179 case TelephonyManager.NETWORK_TYPE_EHRPD:
2180 bin = DATA_CONNECTION_EHRPD;
2181 break;
Patrick Tjinb71703c2013-11-06 09:27:03 -08002182 case TelephonyManager.NETWORK_TYPE_HSPAP:
2183 bin = DATA_CONNECTION_HSPAP;
2184 break;
Dianne Hackborn627bba72009-03-24 22:32:56 -07002185 default:
2186 bin = DATA_CONNECTION_OTHER;
2187 break;
2188 }
2189 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002190 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002191 if (mPhoneDataConnectionType != bin) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002192 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
2193 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002194 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
2195 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002196 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn627bba72009-03-24 22:32:56 -07002197 if (mPhoneDataConnectionType >= 0) {
2198 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this);
2199 }
2200 mPhoneDataConnectionType = bin;
2201 mPhoneDataConnectionsTimer[bin].startRunningLocked(this);
2202 }
2203 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002204
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002205 public void noteWifiOnLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002206 if (!mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002207 mHistoryCur.states |= HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002208 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
2209 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002210 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002211 mWifiOn = true;
2212 mWifiOnTimer.startRunningLocked(this);
2213 }
2214 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002215
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002216 public void noteWifiOffLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002217 if (mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002218 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002219 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
2220 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002221 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002222 mWifiOn = false;
2223 mWifiOnTimer.stopRunningLocked(this);
2224 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07002225 if (mWifiOnUid >= 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002226 getUidStatsLocked(mWifiOnUid).noteWifiStoppedLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07002227 mWifiOnUid = -1;
2228 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002229 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002230
2231 public void noteAudioOnLocked(int uid) {
2232 if (!mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002233 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002234 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
2235 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002236 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002237 mAudioOn = true;
2238 mAudioOnTimer.startRunningLocked(this);
2239 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002240 getUidStatsLocked(uid).noteAudioTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002241 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002242
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002243 public void noteAudioOffLocked(int uid) {
2244 if (mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002245 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002246 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
2247 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002248 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002249 mAudioOn = false;
2250 mAudioOnTimer.stopRunningLocked(this);
2251 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002252 getUidStatsLocked(uid).noteAudioTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002253 }
2254
2255 public void noteVideoOnLocked(int uid) {
2256 if (!mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002257 mHistoryCur.states |= HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002258 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
2259 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002260 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002261 mVideoOn = true;
2262 mVideoOnTimer.startRunningLocked(this);
2263 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002264 getUidStatsLocked(uid).noteVideoTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002265 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002266
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002267 public void noteVideoOffLocked(int uid) {
2268 if (mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002269 mHistoryCur.states &= ~HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002270 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
2271 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002272 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002273 mVideoOn = false;
2274 mVideoOnTimer.stopRunningLocked(this);
2275 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002276 getUidStatsLocked(uid).noteVideoTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002277 }
2278
Jeff Sharkey3e013e82013-04-25 14:48:19 -07002279 public void noteActivityResumedLocked(int uid) {
2280 getUidStatsLocked(uid).noteActivityResumedLocked();
2281 }
2282
2283 public void noteActivityPausedLocked(int uid) {
2284 getUidStatsLocked(uid).noteActivityPausedLocked();
2285 }
2286
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002287 public void noteVibratorOnLocked(int uid, long durationMillis) {
2288 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis);
2289 }
2290
2291 public void noteVibratorOffLocked(int uid) {
2292 getUidStatsLocked(uid).noteVibratorOffLocked();
2293 }
2294
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002295 public void noteWifiRunningLocked(WorkSource ws) {
2296 if (!mGlobalWifiRunning) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002297 mHistoryCur.states |= HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002298 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
2299 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002300 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002301 mGlobalWifiRunning = true;
2302 mGlobalWifiRunningTimer.startRunningLocked(this);
2303 int N = ws.size();
2304 for (int i=0; i<N; i++) {
2305 getUidStatsLocked(ws.get(i)).noteWifiRunningLocked();
2306 }
2307 } else {
2308 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002309 }
2310 }
2311
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002312 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
2313 if (mGlobalWifiRunning) {
2314 int N = oldWs.size();
2315 for (int i=0; i<N; i++) {
2316 getUidStatsLocked(oldWs.get(i)).noteWifiStoppedLocked();
2317 }
2318 N = newWs.size();
2319 for (int i=0; i<N; i++) {
2320 getUidStatsLocked(newWs.get(i)).noteWifiRunningLocked();
2321 }
2322 } else {
2323 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
2324 }
2325 }
2326
2327 public void noteWifiStoppedLocked(WorkSource ws) {
2328 if (mGlobalWifiRunning) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002329 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002330 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
2331 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002332 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002333 mGlobalWifiRunning = false;
2334 mGlobalWifiRunningTimer.stopRunningLocked(this);
2335 int N = ws.size();
2336 for (int i=0; i<N; i++) {
2337 getUidStatsLocked(ws.get(i)).noteWifiStoppedLocked();
2338 }
2339 } else {
2340 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002341 }
2342 }
2343
The Android Open Source Project10592532009-03-18 17:39:46 -07002344 public void noteBluetoothOnLocked() {
2345 if (!mBluetoothOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002346 mHistoryCur.states |= HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002347 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: "
2348 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002349 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002350 mBluetoothOn = true;
2351 mBluetoothOnTimer.startRunningLocked(this);
2352 }
2353 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002354
The Android Open Source Project10592532009-03-18 17:39:46 -07002355 public void noteBluetoothOffLocked() {
2356 if (mBluetoothOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002357 mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002358 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: "
2359 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002360 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07002361 mBluetoothOn = false;
2362 mBluetoothOnTimer.stopRunningLocked(this);
2363 }
2364 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002365
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002366 int mWifiFullLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002367
The Android Open Source Project10592532009-03-18 17:39:46 -07002368 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002369 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002370 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002371 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
2372 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002373 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002374 }
2375 mWifiFullLockNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002376 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002377 }
2378
2379 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002380 mWifiFullLockNesting--;
2381 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002382 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002383 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
2384 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002385 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002386 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002387 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002388 }
2389
Nick Pelly6ccaa542012-06-15 15:22:47 -07002390 int mWifiScanNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002391
Nick Pelly6ccaa542012-06-15 15:22:47 -07002392 public void noteWifiScanStartedLocked(int uid) {
2393 if (mWifiScanNesting == 0) {
2394 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG;
2395 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002396 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002397 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002398 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07002399 mWifiScanNesting++;
2400 getUidStatsLocked(uid).noteWifiScanStartedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002401 }
2402
Nick Pelly6ccaa542012-06-15 15:22:47 -07002403 public void noteWifiScanStoppedLocked(int uid) {
2404 mWifiScanNesting--;
2405 if (mWifiScanNesting == 0) {
2406 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG;
2407 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002408 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002409 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002410 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07002411 getUidStatsLocked(uid).noteWifiScanStoppedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002412 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002413
Robert Greenwalta029ea12013-09-25 16:38:12 -07002414 public void noteWifiBatchedScanStartedLocked(int uid, int csph) {
2415 getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph);
2416 }
2417
2418 public void noteWifiBatchedScanStoppedLocked(int uid) {
2419 getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked();
2420 }
2421
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002422 int mWifiMulticastNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002423
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002424 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002425 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002426 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002427 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
2428 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002429 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002430 }
2431 mWifiMulticastNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07002432 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002433 }
2434
2435 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002436 mWifiMulticastNesting--;
2437 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002438 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002439 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
2440 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002441 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002442 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07002443 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002444 }
2445
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002446 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
2447 int N = ws.size();
2448 for (int i=0; i<N; i++) {
2449 noteFullWifiLockAcquiredLocked(ws.get(i));
2450 }
2451 }
2452
2453 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
2454 int N = ws.size();
2455 for (int i=0; i<N; i++) {
2456 noteFullWifiLockReleasedLocked(ws.get(i));
2457 }
2458 }
2459
Nick Pelly6ccaa542012-06-15 15:22:47 -07002460 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002461 int N = ws.size();
2462 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07002463 noteWifiScanStartedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002464 }
2465 }
2466
Nick Pelly6ccaa542012-06-15 15:22:47 -07002467 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002468 int N = ws.size();
2469 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07002470 noteWifiScanStoppedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002471 }
2472 }
2473
Robert Greenwalta029ea12013-09-25 16:38:12 -07002474 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) {
2475 int N = ws.size();
2476 for (int i=0; i<N; i++) {
2477 noteWifiBatchedScanStartedLocked(ws.get(i), csph);
2478 }
2479 }
2480
2481 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) {
2482 int N = ws.size();
2483 for (int i=0; i<N; i++) {
2484 noteWifiBatchedScanStoppedLocked(ws.get(i));
2485 }
2486 }
2487
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002488 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
2489 int N = ws.size();
2490 for (int i=0; i<N; i++) {
2491 noteWifiMulticastEnabledLocked(ws.get(i));
2492 }
2493 }
2494
2495 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) {
2496 int N = ws.size();
2497 for (int i=0; i<N; i++) {
2498 noteWifiMulticastDisabledLocked(ws.get(i));
2499 }
2500 }
2501
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002502 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) {
2503 if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
2504 mMobileIfaces.add(iface);
2505 } else {
2506 mMobileIfaces.remove(iface);
2507 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07002508 if (ConnectivityManager.isNetworkTypeWifi(networkType)) {
2509 mWifiIfaces.add(iface);
2510 } else {
2511 mWifiIfaces.remove(iface);
2512 }
2513 }
2514
2515 public void noteNetworkStatsEnabledLocked() {
2516 // During device boot, qtaguid isn't enabled until after the inital
2517 // loading of battery stats. Now that they're enabled, take our initial
2518 // snapshot for future delta calculation.
2519 updateNetworkActivityLocked();
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002520 }
2521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002522 @Override public long getScreenOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002523 return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002524 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002525
Dianne Hackborn617f8772009-03-31 15:04:46 -07002526 @Override public long getScreenBrightnessTime(int brightnessBin,
2527 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002528 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn617f8772009-03-31 15:04:46 -07002529 batteryRealtime, which);
2530 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002531
Dianne Hackborn617f8772009-03-31 15:04:46 -07002532 @Override public int getInputEventCount(int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002533 return mInputEventCounter.getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002534 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002536 @Override public long getPhoneOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002537 return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002538 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002539
Dianne Hackborn627bba72009-03-24 22:32:56 -07002540 @Override public long getPhoneSignalStrengthTime(int strengthBin,
2541 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002542 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07002543 batteryRealtime, which);
2544 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07002545
2546 @Override public long getPhoneSignalScanningTime(
2547 long batteryRealtime, int which) {
2548 return mPhoneSignalScanningTimer.getTotalTimeLocked(
2549 batteryRealtime, which);
2550 }
2551
Catherine Liufb900812012-07-17 14:12:56 -05002552 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) {
2553 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002554 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002555
Dianne Hackborn627bba72009-03-24 22:32:56 -07002556 @Override public long getPhoneDataConnectionTime(int dataType,
2557 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002558 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07002559 batteryRealtime, which);
2560 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002561
Dianne Hackborn617f8772009-03-31 15:04:46 -07002562 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002563 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002564 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002565
The Android Open Source Project10592532009-03-18 17:39:46 -07002566 @Override public long getWifiOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002567 return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002568 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002569
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002570 @Override public long getGlobalWifiRunningTime(long batteryRealtime, int which) {
2571 return mGlobalWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002572 }
2573
The Android Open Source Project10592532009-03-18 17:39:46 -07002574 @Override public long getBluetoothOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07002575 return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002576 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002577
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07002578 @Override
2579 public long getNetworkActivityCount(int type, int which) {
2580 if (type >= 0 && type < mNetworkActivityCounters.length) {
2581 return mNetworkActivityCounters[type].getCountLocked(which);
2582 } else {
2583 return 0;
2584 }
2585 }
2586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002587 @Override public boolean getIsOnBattery() {
2588 return mOnBattery;
2589 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002590
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002591 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
2592 return mUidStats;
2593 }
2594
2595 /**
2596 * The statistics associated with a particular uid.
2597 */
2598 public final class Uid extends BatteryStats.Uid {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002599
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002600 final int mUid;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002601
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002602 boolean mWifiRunning;
2603 StopwatchTimer mWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002604
The Android Open Source Project10592532009-03-18 17:39:46 -07002605 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07002606 StopwatchTimer mFullWifiLockTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002607
Nick Pelly6ccaa542012-06-15 15:22:47 -07002608 boolean mWifiScanStarted;
2609 StopwatchTimer mWifiScanTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002610
Robert Greenwalta029ea12013-09-25 16:38:12 -07002611 private static final int NO_BATCHED_SCAN_STARTED = -1;
2612 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
2613 StopwatchTimer[] mWifiBatchedScanTimer;
2614
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002615 boolean mWifiMulticastEnabled;
2616 StopwatchTimer mWifiMulticastTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002617
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002618 boolean mAudioTurnedOn;
2619 StopwatchTimer mAudioTurnedOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002620
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002621 boolean mVideoTurnedOn;
2622 StopwatchTimer mVideoTurnedOnTimer;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002623
Jeff Sharkey3e013e82013-04-25 14:48:19 -07002624 StopwatchTimer mForegroundActivityTimer;
2625
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002626 BatchTimer mVibratorOnTimer;
2627
Dianne Hackborn617f8772009-03-31 15:04:46 -07002628 Counter[] mUserActivityCounters;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002629
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07002630 LongSamplingCounter[] mNetworkActivityCounters;
2631
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002632 /**
2633 * The statistics we have collected for this uid's wake locks.
2634 */
2635 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>();
2636
2637 /**
2638 * The statistics we have collected for this uid's sensor activations.
2639 */
2640 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>();
2641
2642 /**
2643 * The statistics we have collected for this uid's processes.
2644 */
2645 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>();
2646
2647 /**
2648 * The statistics we have collected for this uid's processes.
2649 */
2650 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002651
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002652 /**
2653 * The transient wake stats we have collected for this uid's pids.
2654 */
2655 final SparseArray<Pid> mPids = new SparseArray<Pid>();
2656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002657 public Uid(int uid) {
2658 mUid = uid;
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002659 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2660 mWifiRunningTimers, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002661 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002662 mFullWifiLockTimers, mUnpluggables);
Nick Pelly6ccaa542012-06-15 15:22:47 -07002663 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
2664 mWifiScanTimers, mUnpluggables);
Robert Greenwalta029ea12013-09-25 16:38:12 -07002665 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS];
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002666 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002667 mWifiMulticastTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002668 }
2669
2670 @Override
2671 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
2672 return mWakelockStats;
2673 }
2674
2675 @Override
2676 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() {
2677 return mSensorStats;
2678 }
2679
2680 @Override
2681 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
2682 return mProcessStats;
2683 }
2684
2685 @Override
2686 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
2687 return mPackageStats;
2688 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002689
2690 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002691 public int getUid() {
2692 return mUid;
2693 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002694
2695 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002696 public void noteWifiRunningLocked() {
2697 if (!mWifiRunning) {
2698 mWifiRunning = true;
2699 if (mWifiRunningTimer == null) {
2700 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
2701 mWifiRunningTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002702 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002703 mWifiRunningTimer.startRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002704 }
2705 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002706
Dianne Hackborn617f8772009-03-31 15:04:46 -07002707 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002708 public void noteWifiStoppedLocked() {
2709 if (mWifiRunning) {
2710 mWifiRunning = false;
2711 mWifiRunningTimer.stopRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002712 }
2713 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002714
Dianne Hackborn617f8772009-03-31 15:04:46 -07002715 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002716 public void noteFullWifiLockAcquiredLocked() {
2717 if (!mFullWifiLockOut) {
2718 mFullWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002719 if (mFullWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002720 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002721 mFullWifiLockTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002722 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002723 mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
2724 }
2725 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002726
The Android Open Source Project10592532009-03-18 17:39:46 -07002727 @Override
2728 public void noteFullWifiLockReleasedLocked() {
2729 if (mFullWifiLockOut) {
2730 mFullWifiLockOut = false;
2731 mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
2732 }
2733 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002734
The Android Open Source Project10592532009-03-18 17:39:46 -07002735 @Override
Nick Pelly6ccaa542012-06-15 15:22:47 -07002736 public void noteWifiScanStartedLocked() {
2737 if (!mWifiScanStarted) {
2738 mWifiScanStarted = true;
2739 if (mWifiScanTimer == null) {
2740 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
2741 mWifiScanTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002742 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07002743 mWifiScanTimer.startRunningLocked(BatteryStatsImpl.this);
The Android Open Source Project10592532009-03-18 17:39:46 -07002744 }
2745 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002746
The Android Open Source Project10592532009-03-18 17:39:46 -07002747 @Override
Nick Pelly6ccaa542012-06-15 15:22:47 -07002748 public void noteWifiScanStoppedLocked() {
2749 if (mWifiScanStarted) {
2750 mWifiScanStarted = false;
2751 mWifiScanTimer.stopRunningLocked(BatteryStatsImpl.this);
The Android Open Source Project10592532009-03-18 17:39:46 -07002752 }
2753 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002754
2755 @Override
Robert Greenwalta029ea12013-09-25 16:38:12 -07002756 public void noteWifiBatchedScanStartedLocked(int csph) {
2757 int bin = 0;
2758 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS) {
2759 csph = csph >> 3;
2760 bin++;
2761 }
2762
2763 if (mWifiBatchedScanBinStarted == bin) return;
2764
2765 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
2766 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
2767 stopRunningLocked(BatteryStatsImpl.this);
2768 }
2769 mWifiBatchedScanBinStarted = bin;
2770 if (mWifiBatchedScanTimer[bin] == null) {
2771 makeWifiBatchedScanBin(bin, null);
2772 }
2773 mWifiBatchedScanTimer[bin].startRunningLocked(BatteryStatsImpl.this);
2774 }
2775
2776 @Override
2777 public void noteWifiBatchedScanStoppedLocked() {
2778 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
2779 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
2780 stopRunningLocked(BatteryStatsImpl.this);
2781 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
2782 }
2783 }
2784
2785 @Override
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002786 public void noteWifiMulticastEnabledLocked() {
2787 if (!mWifiMulticastEnabled) {
2788 mWifiMulticastEnabled = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002789 if (mWifiMulticastTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002790 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002791 mWifiMulticastTimers, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002792 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002793 mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this);
2794 }
2795 }
2796
2797 @Override
2798 public void noteWifiMulticastDisabledLocked() {
2799 if (mWifiMulticastEnabled) {
2800 mWifiMulticastEnabled = false;
2801 mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this);
2802 }
2803 }
2804
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002805 public StopwatchTimer createAudioTurnedOnTimerLocked() {
2806 if (mAudioTurnedOnTimer == null) {
2807 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
2808 null, mUnpluggables);
2809 }
2810 return mAudioTurnedOnTimer;
2811 }
2812
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002813 @Override
2814 public void noteAudioTurnedOnLocked() {
2815 if (!mAudioTurnedOn) {
2816 mAudioTurnedOn = true;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002817 createAudioTurnedOnTimerLocked().startRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002818 }
2819 }
2820
2821 @Override
2822 public void noteAudioTurnedOffLocked() {
2823 if (mAudioTurnedOn) {
2824 mAudioTurnedOn = false;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002825 if (mAudioTurnedOnTimer != null) {
2826 mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
2827 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002828 }
2829 }
2830
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002831 public StopwatchTimer createVideoTurnedOnTimerLocked() {
2832 if (mVideoTurnedOnTimer == null) {
2833 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
2834 null, mUnpluggables);
2835 }
2836 return mVideoTurnedOnTimer;
2837 }
2838
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002839 @Override
2840 public void noteVideoTurnedOnLocked() {
2841 if (!mVideoTurnedOn) {
2842 mVideoTurnedOn = true;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002843 createVideoTurnedOnTimerLocked().startRunningLocked(BatteryStatsImpl.this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002844 }
2845 }
2846
2847 @Override
2848 public void noteVideoTurnedOffLocked() {
2849 if (mVideoTurnedOn) {
2850 mVideoTurnedOn = false;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002851 if (mVideoTurnedOnTimer != null) {
2852 mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
2853 }
2854 }
2855 }
2856
Jeff Sharkey3e013e82013-04-25 14:48:19 -07002857 public StopwatchTimer createForegroundActivityTimerLocked() {
2858 if (mForegroundActivityTimer == null) {
2859 mForegroundActivityTimer = new StopwatchTimer(
2860 Uid.this, FOREGROUND_ACTIVITY, null, mUnpluggables);
2861 }
2862 return mForegroundActivityTimer;
2863 }
2864
2865 @Override
2866 public void noteActivityResumedLocked() {
2867 // We always start, since we want multiple foreground PIDs to nest
2868 createForegroundActivityTimerLocked().startRunningLocked(BatteryStatsImpl.this);
2869 }
2870
2871 @Override
2872 public void noteActivityPausedLocked() {
2873 if (mForegroundActivityTimer != null) {
2874 mForegroundActivityTimer.stopRunningLocked(BatteryStatsImpl.this);
2875 }
2876 }
2877
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002878 public BatchTimer createVibratorOnTimerLocked() {
2879 if (mVibratorOnTimer == null) {
2880 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON,
2881 mUnpluggables, BatteryStatsImpl.this.mOnBatteryInternal);
2882 }
2883 return mVibratorOnTimer;
2884 }
2885
2886 public void noteVibratorOnLocked(long durationMillis) {
2887 createVibratorOnTimerLocked().addDuration(BatteryStatsImpl.this, durationMillis);
2888 }
2889
2890 public void noteVibratorOffLocked() {
2891 if (mVibratorOnTimer != null) {
2892 mVibratorOnTimer.abortLastDuration(BatteryStatsImpl.this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002893 }
2894 }
2895
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002896 @Override
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002897 public long getWifiRunningTime(long batteryRealtime, int which) {
2898 if (mWifiRunningTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002899 return 0;
2900 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07002901 return mWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002902 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002903
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002904 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002905 public long getFullWifiLockTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002906 if (mFullWifiLockTimer == null) {
2907 return 0;
2908 }
Evan Millarc64edde2009-04-18 12:26:32 -07002909 return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002910 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002911
2912 @Override
Nick Pelly6ccaa542012-06-15 15:22:47 -07002913 public long getWifiScanTime(long batteryRealtime, int which) {
2914 if (mWifiScanTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002915 return 0;
2916 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07002917 return mWifiScanTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002918 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002919
2920 @Override
Robert Greenwalta029ea12013-09-25 16:38:12 -07002921 public long getWifiBatchedScanTime(int csphBin, long batteryRealtime, int which) {
2922 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
2923 if (mWifiBatchedScanTimer[csphBin] == null) {
2924 return 0;
2925 }
2926 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(batteryRealtime, which);
2927 }
2928
2929 @Override
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002930 public long getWifiMulticastTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002931 if (mWifiMulticastTimer == null) {
2932 return 0;
2933 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002934 return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime,
2935 which);
2936 }
2937
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002938 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002939 public long getAudioTurnedOnTime(long batteryRealtime, int which) {
2940 if (mAudioTurnedOnTimer == null) {
2941 return 0;
2942 }
2943 return mAudioTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
2944 }
2945
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002946 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002947 public long getVideoTurnedOnTime(long batteryRealtime, int which) {
2948 if (mVideoTurnedOnTimer == null) {
2949 return 0;
2950 }
2951 return mVideoTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
2952 }
2953
Dianne Hackborn617f8772009-03-31 15:04:46 -07002954 @Override
Jeff Sharkey3e013e82013-04-25 14:48:19 -07002955 public Timer getForegroundActivityTimer() {
2956 return mForegroundActivityTimer;
2957 }
2958
2959 @Override
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002960 public Timer getVibratorOnTimer() {
2961 return mVibratorOnTimer;
2962 }
2963
2964 @Override
Dianne Hackborn617f8772009-03-31 15:04:46 -07002965 public void noteUserActivityLocked(int type) {
2966 if (mUserActivityCounters == null) {
2967 initUserActivityLocked();
2968 }
Jeff Browndf693de2012-07-27 12:03:38 -07002969 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) {
2970 mUserActivityCounters[type].stepAtomic();
2971 } else {
2972 Slog.w(TAG, "Unknown user activity type " + type + " was specified.",
2973 new Throwable());
2974 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07002975 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002976
Dianne Hackborn617f8772009-03-31 15:04:46 -07002977 @Override
2978 public boolean hasUserActivity() {
2979 return mUserActivityCounters != null;
2980 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002981
Dianne Hackborn617f8772009-03-31 15:04:46 -07002982 @Override
2983 public int getUserActivityCount(int type, int which) {
2984 if (mUserActivityCounters == null) {
2985 return 0;
2986 }
Evan Millarc64edde2009-04-18 12:26:32 -07002987 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002988 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002989
Robert Greenwalta029ea12013-09-25 16:38:12 -07002990 void makeWifiBatchedScanBin(int i, Parcel in) {
2991 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return;
2992
2993 ArrayList<StopwatchTimer> collected = mWifiBatchedScanTimers.get(i);
2994 if (collected == null) {
2995 collected = new ArrayList<StopwatchTimer>();
2996 mWifiBatchedScanTimers.put(i, collected);
2997 }
2998 if (in == null) {
2999 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
3000 mUnpluggables);
3001 } else {
3002 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
3003 mUnpluggables, in);
3004 }
3005 }
3006
3007
Dianne Hackborn617f8772009-03-31 15:04:46 -07003008 void initUserActivityLocked() {
3009 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
3010 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
3011 mUserActivityCounters[i] = new Counter(mUnpluggables);
3012 }
3013 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003014
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003015 void noteNetworkActivityLocked(int type, long delta) {
3016 if (mNetworkActivityCounters == null) {
3017 initNetworkActivityLocked();
3018 }
3019 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) {
3020 mNetworkActivityCounters[type].addCountLocked(delta);
3021 } else {
3022 Slog.w(TAG, "Unknown network activity type " + type + " was specified.",
3023 new Throwable());
3024 }
3025 }
3026
3027 @Override
3028 public boolean hasNetworkActivity() {
3029 return mNetworkActivityCounters != null;
3030 }
3031
3032 @Override
3033 public long getNetworkActivityCount(int type, int which) {
3034 if (mNetworkActivityCounters != null && type >= 0
3035 && type < mNetworkActivityCounters.length) {
3036 return mNetworkActivityCounters[type].getCountLocked(which);
3037 } else {
3038 return 0;
3039 }
3040 }
3041
3042 void initNetworkActivityLocked() {
3043 mNetworkActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
3044 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
3045 mNetworkActivityCounters[i] = new LongSamplingCounter(mUnpluggables);
3046 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003047 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003048
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003049 /**
3050 * Clear all stats for this uid. Returns true if the uid is completely
3051 * inactive so can be dropped.
3052 */
3053 boolean reset() {
3054 boolean active = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003055
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003056 if (mWifiRunningTimer != null) {
3057 active |= !mWifiRunningTimer.reset(BatteryStatsImpl.this, false);
3058 active |= mWifiRunning;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003059 }
3060 if (mFullWifiLockTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003061 active |= !mFullWifiLockTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003062 active |= mFullWifiLockOut;
3063 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07003064 if (mWifiScanTimer != null) {
3065 active |= !mWifiScanTimer.reset(BatteryStatsImpl.this, false);
3066 active |= mWifiScanStarted;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003067 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07003068 if (mWifiBatchedScanTimer != null) {
3069 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
3070 if (mWifiBatchedScanTimer[i] != null) {
3071 active |= !mWifiBatchedScanTimer[i].reset(BatteryStatsImpl.this, false);
3072 }
3073 }
3074 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED);
3075 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003076 if (mWifiMulticastTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003077 active |= !mWifiMulticastTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003078 active |= mWifiMulticastEnabled;
3079 }
3080 if (mAudioTurnedOnTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003081 active |= !mAudioTurnedOnTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003082 active |= mAudioTurnedOn;
3083 }
3084 if (mVideoTurnedOnTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003085 active |= !mVideoTurnedOnTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003086 active |= mVideoTurnedOn;
3087 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003088 if (mForegroundActivityTimer != null) {
3089 active |= !mForegroundActivityTimer.reset(BatteryStatsImpl.this, false);
3090 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003091 if (mVibratorOnTimer != null) {
3092 if (mVibratorOnTimer.reset(BatteryStatsImpl.this, false)) {
3093 mVibratorOnTimer.detach();
3094 mVibratorOnTimer = null;
3095 } else {
3096 active = true;
3097 }
3098 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003099
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003100 if (mUserActivityCounters != null) {
3101 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
3102 mUserActivityCounters[i].reset(false);
3103 }
3104 }
3105
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003106 if (mNetworkActivityCounters != null) {
3107 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
3108 mNetworkActivityCounters[i].reset(false);
3109 }
3110 }
3111
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003112 if (mWakelockStats.size() > 0) {
3113 Iterator<Map.Entry<String, Wakelock>> it = mWakelockStats.entrySet().iterator();
3114 while (it.hasNext()) {
3115 Map.Entry<String, Wakelock> wakelockEntry = it.next();
3116 Wakelock wl = wakelockEntry.getValue();
3117 if (wl.reset()) {
3118 it.remove();
3119 } else {
3120 active = true;
3121 }
3122 }
3123 }
3124 if (mSensorStats.size() > 0) {
3125 Iterator<Map.Entry<Integer, Sensor>> it = mSensorStats.entrySet().iterator();
3126 while (it.hasNext()) {
3127 Map.Entry<Integer, Sensor> sensorEntry = it.next();
3128 Sensor s = sensorEntry.getValue();
3129 if (s.reset()) {
3130 it.remove();
3131 } else {
3132 active = true;
3133 }
3134 }
3135 }
3136 if (mProcessStats.size() > 0) {
3137 Iterator<Map.Entry<String, Proc>> it = mProcessStats.entrySet().iterator();
3138 while (it.hasNext()) {
3139 Map.Entry<String, Proc> procEntry = it.next();
3140 procEntry.getValue().detach();
3141 }
3142 mProcessStats.clear();
3143 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003144 if (mPids.size() > 0) {
3145 for (int i=0; !active && i<mPids.size(); i++) {
3146 Pid pid = mPids.valueAt(i);
3147 if (pid.mWakeStart != 0) {
3148 active = true;
3149 }
3150 }
3151 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003152 if (mPackageStats.size() > 0) {
3153 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator();
3154 while (it.hasNext()) {
3155 Map.Entry<String, Pkg> pkgEntry = it.next();
3156 Pkg p = pkgEntry.getValue();
3157 p.detach();
3158 if (p.mServiceStats.size() > 0) {
3159 Iterator<Map.Entry<String, Pkg.Serv>> it2
3160 = p.mServiceStats.entrySet().iterator();
3161 while (it2.hasNext()) {
3162 Map.Entry<String, Pkg.Serv> servEntry = it2.next();
3163 servEntry.getValue().detach();
3164 }
3165 }
3166 }
3167 mPackageStats.clear();
3168 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003169
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003170 mPids.clear();
3171
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003172 if (!active) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003173 if (mWifiRunningTimer != null) {
3174 mWifiRunningTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003175 }
3176 if (mFullWifiLockTimer != null) {
3177 mFullWifiLockTimer.detach();
3178 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07003179 if (mWifiScanTimer != null) {
3180 mWifiScanTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003181 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07003182 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
3183 if (mWifiBatchedScanTimer[i] != null) {
3184 mWifiBatchedScanTimer[i].detach();
3185 }
3186 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003187 if (mWifiMulticastTimer != null) {
3188 mWifiMulticastTimer.detach();
3189 }
3190 if (mAudioTurnedOnTimer != null) {
3191 mAudioTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003192 mAudioTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003193 }
3194 if (mVideoTurnedOnTimer != null) {
3195 mVideoTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003196 mVideoTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003197 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003198 if (mForegroundActivityTimer != null) {
3199 mForegroundActivityTimer.detach();
3200 mForegroundActivityTimer = null;
3201 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003202 if (mUserActivityCounters != null) {
3203 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
3204 mUserActivityCounters[i].detach();
3205 }
3206 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003207 if (mNetworkActivityCounters != null) {
3208 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
3209 mNetworkActivityCounters[i].detach();
3210 }
3211 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003212 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003213
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003214 return !active;
3215 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003217 void writeToParcelLocked(Parcel out, long batteryRealtime) {
3218 out.writeInt(mWakelockStats.size());
3219 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
3220 out.writeString(wakelockEntry.getKey());
3221 Uid.Wakelock wakelock = wakelockEntry.getValue();
3222 wakelock.writeToParcelLocked(out, batteryRealtime);
3223 }
3224
3225 out.writeInt(mSensorStats.size());
3226 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) {
3227 out.writeInt(sensorEntry.getKey());
3228 Uid.Sensor sensor = sensorEntry.getValue();
3229 sensor.writeToParcelLocked(out, batteryRealtime);
3230 }
3231
3232 out.writeInt(mProcessStats.size());
3233 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) {
3234 out.writeString(procEntry.getKey());
3235 Uid.Proc proc = procEntry.getValue();
3236 proc.writeToParcelLocked(out);
3237 }
3238
3239 out.writeInt(mPackageStats.size());
3240 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
3241 out.writeString(pkgEntry.getKey());
3242 Uid.Pkg pkg = pkgEntry.getValue();
3243 pkg.writeToParcelLocked(out);
3244 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003245
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003246 if (mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003247 out.writeInt(1);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003248 mWifiRunningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003249 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003250 out.writeInt(0);
3251 }
3252 if (mFullWifiLockTimer != null) {
3253 out.writeInt(1);
3254 mFullWifiLockTimer.writeToParcel(out, batteryRealtime);
3255 } else {
3256 out.writeInt(0);
3257 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07003258 if (mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003259 out.writeInt(1);
Nick Pelly6ccaa542012-06-15 15:22:47 -07003260 mWifiScanTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003261 } else {
3262 out.writeInt(0);
3263 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07003264 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
3265 if (mWifiBatchedScanTimer[i] != null) {
3266 out.writeInt(1);
3267 mWifiBatchedScanTimer[i].writeToParcel(out, batteryRealtime);
3268 } else {
3269 out.writeInt(0);
3270 }
3271 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003272 if (mWifiMulticastTimer != null) {
3273 out.writeInt(1);
3274 mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
3275 } else {
3276 out.writeInt(0);
3277 }
3278 if (mAudioTurnedOnTimer != null) {
3279 out.writeInt(1);
3280 mAudioTurnedOnTimer.writeToParcel(out, batteryRealtime);
3281 } else {
3282 out.writeInt(0);
3283 }
3284 if (mVideoTurnedOnTimer != null) {
3285 out.writeInt(1);
3286 mVideoTurnedOnTimer.writeToParcel(out, batteryRealtime);
3287 } else {
3288 out.writeInt(0);
3289 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003290 if (mForegroundActivityTimer != null) {
3291 out.writeInt(1);
3292 mForegroundActivityTimer.writeToParcel(out, batteryRealtime);
3293 } else {
3294 out.writeInt(0);
3295 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003296 if (mVibratorOnTimer != null) {
3297 out.writeInt(1);
3298 mVibratorOnTimer.writeToParcel(out, batteryRealtime);
3299 } else {
3300 out.writeInt(0);
3301 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003302 if (mUserActivityCounters != null) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07003303 out.writeInt(1);
3304 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
3305 mUserActivityCounters[i].writeToParcel(out);
3306 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003307 } else {
3308 out.writeInt(0);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003309 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003310 if (mNetworkActivityCounters != null) {
3311 out.writeInt(1);
3312 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
3313 mNetworkActivityCounters[i].writeToParcel(out);
3314 }
3315 } else {
3316 out.writeInt(0);
3317 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003318 }
3319
3320 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
3321 int numWakelocks = in.readInt();
3322 mWakelockStats.clear();
3323 for (int j = 0; j < numWakelocks; j++) {
3324 String wakelockName = in.readString();
3325 Uid.Wakelock wakelock = new Wakelock();
3326 wakelock.readFromParcelLocked(unpluggables, in);
Dianne Hackbornc24ab862011-10-18 15:55:03 -07003327 // We will just drop some random set of wakelocks if
3328 // the previous run of the system was an older version
3329 // that didn't impose a limit.
3330 mWakelockStats.put(wakelockName, wakelock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003331 }
3332
3333 int numSensors = in.readInt();
3334 mSensorStats.clear();
3335 for (int k = 0; k < numSensors; k++) {
3336 int sensorNumber = in.readInt();
3337 Uid.Sensor sensor = new Sensor(sensorNumber);
3338 sensor.readFromParcelLocked(mUnpluggables, in);
3339 mSensorStats.put(sensorNumber, sensor);
3340 }
3341
3342 int numProcs = in.readInt();
3343 mProcessStats.clear();
3344 for (int k = 0; k < numProcs; k++) {
3345 String processName = in.readString();
3346 Uid.Proc proc = new Proc();
3347 proc.readFromParcelLocked(in);
3348 mProcessStats.put(processName, proc);
3349 }
3350
3351 int numPkgs = in.readInt();
3352 mPackageStats.clear();
3353 for (int l = 0; l < numPkgs; l++) {
3354 String packageName = in.readString();
3355 Uid.Pkg pkg = new Pkg();
3356 pkg.readFromParcelLocked(in);
3357 mPackageStats.put(packageName, pkg);
3358 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003359
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003360 mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003361 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003362 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
3363 mWifiRunningTimers, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003364 } else {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003365 mWifiRunningTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003366 }
3367 mFullWifiLockOut = false;
3368 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003369 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003370 mFullWifiLockTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003371 } else {
3372 mFullWifiLockTimer = null;
3373 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07003374 mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003375 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003376 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
3377 mWifiScanTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003378 } else {
Nick Pelly6ccaa542012-06-15 15:22:47 -07003379 mWifiScanTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003380 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07003381 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
3382 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
3383 if (in.readInt() != 0) {
3384 makeWifiBatchedScanBin(i, in);
3385 } else {
3386 mWifiBatchedScanTimer[i] = null;
3387 }
3388 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003389 mWifiMulticastEnabled = false;
3390 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003391 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003392 mWifiMulticastTimers, mUnpluggables, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003393 } else {
3394 mWifiMulticastTimer = null;
3395 }
3396 mAudioTurnedOn = false;
3397 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003398 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003399 null, mUnpluggables, in);
3400 } else {
3401 mAudioTurnedOnTimer = null;
3402 }
3403 mVideoTurnedOn = false;
3404 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003405 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003406 null, mUnpluggables, in);
3407 } else {
3408 mVideoTurnedOnTimer = null;
3409 }
3410 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003411 mForegroundActivityTimer = new StopwatchTimer(
3412 Uid.this, FOREGROUND_ACTIVITY, null, mUnpluggables, in);
3413 } else {
3414 mForegroundActivityTimer = null;
3415 }
3416 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003417 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON,
3418 mUnpluggables, BatteryStatsImpl.this.mOnBatteryInternal, in);
3419 } else {
3420 mVibratorOnTimer = null;
3421 }
3422 if (in.readInt() != 0) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07003423 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
3424 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
3425 mUserActivityCounters[i] = new Counter(mUnpluggables, in);
3426 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003427 } else {
3428 mUserActivityCounters = null;
Dianne Hackborn617f8772009-03-31 15:04:46 -07003429 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07003430 if (in.readInt() != 0) {
3431 mNetworkActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
3432 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
3433 mNetworkActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in);
3434 }
3435 } else {
3436 mNetworkActivityCounters = null;
3437 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003438 }
3439
3440 /**
3441 * The statistics associated with a particular wake lock.
3442 */
3443 public final class Wakelock extends BatteryStats.Uid.Wakelock {
3444 /**
3445 * How long (in ms) this uid has been keeping the device partially awake.
3446 */
Evan Millarc64edde2009-04-18 12:26:32 -07003447 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003448
3449 /**
3450 * How long (in ms) this uid has been keeping the device fully awake.
3451 */
Evan Millarc64edde2009-04-18 12:26:32 -07003452 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003453
3454 /**
3455 * How long (in ms) this uid has had a window keeping the device awake.
3456 */
Evan Millarc64edde2009-04-18 12:26:32 -07003457 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003458
3459 /**
3460 * Reads a possibly null Timer from a Parcel. The timer is associated with the
3461 * proper timer pool from the given BatteryStatsImpl object.
3462 *
3463 * @param in the Parcel to be read from.
3464 * return a new Timer, or null.
3465 */
Evan Millarc64edde2009-04-18 12:26:32 -07003466 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003467 ArrayList<Unpluggable> unpluggables, Parcel in) {
3468 if (in.readInt() == 0) {
3469 return null;
3470 }
3471
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003472 return new StopwatchTimer(Uid.this, type, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003473 }
3474
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003475 boolean reset() {
3476 boolean wlactive = false;
3477 if (mTimerFull != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003478 wlactive |= !mTimerFull.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003479 }
3480 if (mTimerPartial != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003481 wlactive |= !mTimerPartial.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003482 }
3483 if (mTimerWindow != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003484 wlactive |= !mTimerWindow.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003485 }
3486 if (!wlactive) {
3487 if (mTimerFull != null) {
3488 mTimerFull.detach();
3489 mTimerFull = null;
3490 }
3491 if (mTimerPartial != null) {
3492 mTimerPartial.detach();
3493 mTimerPartial = null;
3494 }
3495 if (mTimerWindow != null) {
3496 mTimerWindow.detach();
3497 mTimerWindow = null;
3498 }
3499 }
3500 return !wlactive;
3501 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003502
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003503 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
3504 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
3505 mPartialTimers, unpluggables, in);
3506 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
3507 mFullTimers, unpluggables, in);
3508 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
3509 mWindowTimers, unpluggables, in);
3510 }
3511
3512 void writeToParcelLocked(Parcel out, long batteryRealtime) {
3513 Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime);
3514 Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime);
3515 Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime);
3516 }
3517
3518 @Override
3519 public Timer getWakeTime(int type) {
3520 switch (type) {
3521 case WAKE_TYPE_FULL: return mTimerFull;
3522 case WAKE_TYPE_PARTIAL: return mTimerPartial;
3523 case WAKE_TYPE_WINDOW: return mTimerWindow;
3524 default: throw new IllegalArgumentException("type = " + type);
3525 }
3526 }
3527 }
3528
3529 public final class Sensor extends BatteryStats.Uid.Sensor {
3530 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07003531 StopwatchTimer mTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003532
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003533 public Sensor(int handle) {
3534 mHandle = handle;
3535 }
3536
Evan Millarc64edde2009-04-18 12:26:32 -07003537 private StopwatchTimer readTimerFromParcel(ArrayList<Unpluggable> unpluggables,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003538 Parcel in) {
3539 if (in.readInt() == 0) {
3540 return null;
3541 }
3542
Evan Millarc64edde2009-04-18 12:26:32 -07003543 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003544 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07003545 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003546 mSensorTimers.put(mHandle, pool);
3547 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003548 return new StopwatchTimer(Uid.this, 0, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003549 }
3550
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003551 boolean reset() {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003552 if (mTimer.reset(BatteryStatsImpl.this, true)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003553 mTimer = null;
3554 return true;
3555 }
3556 return false;
3557 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003559 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
3560 mTimer = readTimerFromParcel(unpluggables, in);
3561 }
3562
3563 void writeToParcelLocked(Parcel out, long batteryRealtime) {
3564 Timer.writeTimerToParcel(out, mTimer, batteryRealtime);
3565 }
3566
3567 @Override
3568 public Timer getSensorTime() {
3569 return mTimer;
3570 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003571
3572 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003573 public int getHandle() {
3574 return mHandle;
3575 }
3576 }
3577
3578 /**
3579 * The statistics associated with a particular process.
3580 */
3581 public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable {
3582 /**
3583 * Total time (in 1/100 sec) spent executing in user code.
3584 */
3585 long mUserTime;
3586
3587 /**
3588 * Total time (in 1/100 sec) spent executing in kernel code.
3589 */
3590 long mSystemTime;
3591
3592 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003593 * Amount of time the process was running in the foreground.
3594 */
3595 long mForegroundTime;
3596
3597 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003598 * Number of times the process has been started.
3599 */
3600 int mStarts;
3601
3602 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003603 * The amount of user time loaded from a previous save.
3604 */
3605 long mLoadedUserTime;
3606
3607 /**
3608 * The amount of system time loaded from a previous save.
3609 */
3610 long mLoadedSystemTime;
3611
3612 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003613 * The amount of foreground time loaded from a previous save.
3614 */
3615 long mLoadedForegroundTime;
3616
3617 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003618 * The number of times the process has started from a previous save.
3619 */
3620 int mLoadedStarts;
3621
3622 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003623 * The amount of user time loaded from the previous run.
3624 */
3625 long mLastUserTime;
3626
3627 /**
3628 * The amount of system time loaded from the previous run.
3629 */
3630 long mLastSystemTime;
3631
3632 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003633 * The amount of foreground time loaded from the previous run
3634 */
3635 long mLastForegroundTime;
3636
3637 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003638 * The number of times the process has started from the previous run.
3639 */
3640 int mLastStarts;
3641
3642 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003643 * The amount of user time when last unplugged.
3644 */
3645 long mUnpluggedUserTime;
3646
3647 /**
3648 * The amount of system time when last unplugged.
3649 */
3650 long mUnpluggedSystemTime;
3651
3652 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003653 * The amount of foreground time since unplugged.
3654 */
3655 long mUnpluggedForegroundTime;
3656
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003657 /**
3658 * The number of times the process has started before unplugged.
3659 */
3660 int mUnpluggedStarts;
3661
Amith Yamasanie43530a2009-08-21 13:11:37 -07003662 SamplingCounter[] mSpeedBins;
3663
Dianne Hackborn287952c2010-09-22 22:34:31 -07003664 ArrayList<ExcessivePower> mExcessivePower;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003665
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003666 Proc() {
3667 mUnpluggables.add(this);
Amith Yamasanie43530a2009-08-21 13:11:37 -07003668 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003669 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003670
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003671 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003672 mUnpluggedUserTime = mUserTime;
3673 mUnpluggedSystemTime = mSystemTime;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003674 mUnpluggedForegroundTime = mForegroundTime;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003675 mUnpluggedStarts = mStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003676 }
3677
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003678 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003679 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003680
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003681 void detach() {
3682 mUnpluggables.remove(this);
3683 for (int i = 0; i < mSpeedBins.length; i++) {
3684 SamplingCounter c = mSpeedBins[i];
3685 if (c != null) {
3686 mUnpluggables.remove(c);
3687 mSpeedBins[i] = null;
3688 }
3689 }
3690 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003691
Dianne Hackborn287952c2010-09-22 22:34:31 -07003692 public int countExcessivePowers() {
3693 return mExcessivePower != null ? mExcessivePower.size() : 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003694 }
3695
Dianne Hackborn287952c2010-09-22 22:34:31 -07003696 public ExcessivePower getExcessivePower(int i) {
3697 if (mExcessivePower != null) {
3698 return mExcessivePower.get(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003699 }
3700 return null;
3701 }
3702
3703 public void addExcessiveWake(long overTime, long usedTime) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003704 if (mExcessivePower == null) {
3705 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003706 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07003707 ExcessivePower ew = new ExcessivePower();
3708 ew.type = ExcessivePower.TYPE_WAKE;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003709 ew.overTime = overTime;
3710 ew.usedTime = usedTime;
Dianne Hackborn287952c2010-09-22 22:34:31 -07003711 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003712 }
3713
Dianne Hackborn287952c2010-09-22 22:34:31 -07003714 public void addExcessiveCpu(long overTime, long usedTime) {
3715 if (mExcessivePower == null) {
3716 mExcessivePower = new ArrayList<ExcessivePower>();
3717 }
3718 ExcessivePower ew = new ExcessivePower();
3719 ew.type = ExcessivePower.TYPE_CPU;
3720 ew.overTime = overTime;
3721 ew.usedTime = usedTime;
3722 mExcessivePower.add(ew);
3723 }
3724
3725 void writeExcessivePowerToParcelLocked(Parcel out) {
3726 if (mExcessivePower == null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003727 out.writeInt(0);
3728 return;
3729 }
3730
Dianne Hackborn287952c2010-09-22 22:34:31 -07003731 final int N = mExcessivePower.size();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003732 out.writeInt(N);
3733 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003734 ExcessivePower ew = mExcessivePower.get(i);
3735 out.writeInt(ew.type);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003736 out.writeLong(ew.overTime);
3737 out.writeLong(ew.usedTime);
3738 }
3739 }
3740
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003741 boolean readExcessivePowerFromParcelLocked(Parcel in) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003742 final int N = in.readInt();
3743 if (N == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003744 mExcessivePower = null;
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003745 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003746 }
3747
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003748 if (N > 10000) {
3749 Slog.w(TAG, "File corrupt: too many excessive power entries " + N);
3750 return false;
3751 }
3752
Dianne Hackborn287952c2010-09-22 22:34:31 -07003753 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003754 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07003755 ExcessivePower ew = new ExcessivePower();
3756 ew.type = in.readInt();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003757 ew.overTime = in.readLong();
3758 ew.usedTime = in.readLong();
Dianne Hackborn287952c2010-09-22 22:34:31 -07003759 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003760 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08003761 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003762 }
3763
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003764 void writeToParcelLocked(Parcel out) {
3765 out.writeLong(mUserTime);
3766 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003767 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003768 out.writeInt(mStarts);
3769 out.writeLong(mLoadedUserTime);
3770 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003771 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003772 out.writeInt(mLoadedStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003773 out.writeLong(mUnpluggedUserTime);
3774 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003775 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003776 out.writeInt(mUnpluggedStarts);
Amith Yamasanie43530a2009-08-21 13:11:37 -07003777
3778 out.writeInt(mSpeedBins.length);
3779 for (int i = 0; i < mSpeedBins.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003780 SamplingCounter c = mSpeedBins[i];
3781 if (c != null) {
3782 out.writeInt(1);
3783 c.writeToParcel(out);
3784 } else {
3785 out.writeInt(0);
3786 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003787 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003788
Dianne Hackborn287952c2010-09-22 22:34:31 -07003789 writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003790 }
3791
3792 void readFromParcelLocked(Parcel in) {
3793 mUserTime = in.readLong();
3794 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003795 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003796 mStarts = in.readInt();
3797 mLoadedUserTime = in.readLong();
3798 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003799 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003800 mLoadedStarts = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003801 mLastUserTime = 0;
3802 mLastSystemTime = 0;
3803 mLastForegroundTime = 0;
3804 mLastStarts = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003805 mUnpluggedUserTime = in.readLong();
3806 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003807 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003808 mUnpluggedStarts = in.readInt();
Amith Yamasanie43530a2009-08-21 13:11:37 -07003809
3810 int bins = in.readInt();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003811 int steps = getCpuSpeedSteps();
3812 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps];
Amith Yamasanie43530a2009-08-21 13:11:37 -07003813 for (int i = 0; i < bins; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003814 if (in.readInt() != 0) {
3815 mSpeedBins[i] = new SamplingCounter(mUnpluggables, in);
3816 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003817 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003818
Dianne Hackborn287952c2010-09-22 22:34:31 -07003819 readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003820 }
3821
3822 public BatteryStatsImpl getBatteryStats() {
3823 return BatteryStatsImpl.this;
3824 }
3825
3826 public void addCpuTimeLocked(int utime, int stime) {
3827 mUserTime += utime;
3828 mSystemTime += stime;
3829 }
3830
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003831 public void addForegroundTimeLocked(long ttime) {
3832 mForegroundTime += ttime;
3833 }
3834
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003835 public void incStartsLocked() {
3836 mStarts++;
3837 }
3838
3839 @Override
3840 public long getUserTime(int which) {
3841 long val;
3842 if (which == STATS_LAST) {
3843 val = mLastUserTime;
3844 } else {
3845 val = mUserTime;
3846 if (which == STATS_CURRENT) {
3847 val -= mLoadedUserTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003848 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003849 val -= mUnpluggedUserTime;
3850 }
3851 }
3852 return val;
3853 }
3854
3855 @Override
3856 public long getSystemTime(int which) {
3857 long val;
3858 if (which == STATS_LAST) {
3859 val = mLastSystemTime;
3860 } else {
3861 val = mSystemTime;
3862 if (which == STATS_CURRENT) {
3863 val -= mLoadedSystemTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003864 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003865 val -= mUnpluggedSystemTime;
3866 }
3867 }
3868 return val;
3869 }
3870
3871 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003872 public long getForegroundTime(int which) {
3873 long val;
3874 if (which == STATS_LAST) {
3875 val = mLastForegroundTime;
3876 } else {
3877 val = mForegroundTime;
3878 if (which == STATS_CURRENT) {
3879 val -= mLoadedForegroundTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003880 } else if (which == STATS_SINCE_UNPLUGGED) {
Amith Yamasanieaeb6632009-06-03 15:16:10 -07003881 val -= mUnpluggedForegroundTime;
3882 }
3883 }
3884 return val;
3885 }
3886
3887 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003888 public int getStarts(int which) {
3889 int val;
3890 if (which == STATS_LAST) {
3891 val = mLastStarts;
3892 } else {
3893 val = mStarts;
3894 if (which == STATS_CURRENT) {
3895 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003896 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003897 val -= mUnpluggedStarts;
3898 }
3899 }
3900 return val;
3901 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003902
3903 /* Called by ActivityManagerService when CPU times are updated. */
3904 public void addSpeedStepTimes(long[] values) {
3905 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003906 long amt = values[i];
3907 if (amt != 0) {
3908 SamplingCounter c = mSpeedBins[i];
3909 if (c == null) {
3910 mSpeedBins[i] = c = new SamplingCounter(mUnpluggables);
3911 }
3912 c.addCountAtomic(values[i]);
3913 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003914 }
3915 }
3916
3917 @Override
3918 public long getTimeAtCpuSpeedStep(int speedStep, int which) {
3919 if (speedStep < mSpeedBins.length) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003920 SamplingCounter c = mSpeedBins[speedStep];
3921 return c != null ? c.getCountLocked(which) : 0;
Amith Yamasanie43530a2009-08-21 13:11:37 -07003922 } else {
3923 return 0;
3924 }
3925 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003926 }
3927
3928 /**
3929 * The statistics associated with a particular package.
3930 */
3931 public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable {
3932 /**
3933 * Number of times this package has done something that could wake up the
3934 * device from sleep.
3935 */
3936 int mWakeups;
3937
3938 /**
3939 * Number of things that could wake up the device loaded from a
3940 * previous save.
3941 */
3942 int mLoadedWakeups;
3943
3944 /**
3945 * Number of things that could wake up the device as of the
3946 * last run.
3947 */
3948 int mLastWakeups;
3949
3950 /**
3951 * Number of things that could wake up the device as of the
3952 * last run.
3953 */
3954 int mUnpluggedWakeups;
3955
3956 /**
3957 * The statics we have collected for this package's services.
3958 */
3959 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
3960
3961 Pkg() {
3962 mUnpluggables.add(this);
3963 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003964
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003965 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003966 mUnpluggedWakeups = mWakeups;
3967 }
3968
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003969 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003970 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003971
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003972 void detach() {
3973 mUnpluggables.remove(this);
3974 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003975
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003976 void readFromParcelLocked(Parcel in) {
3977 mWakeups = in.readInt();
3978 mLoadedWakeups = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003979 mLastWakeups = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003980 mUnpluggedWakeups = in.readInt();
3981
3982 int numServs = in.readInt();
3983 mServiceStats.clear();
3984 for (int m = 0; m < numServs; m++) {
3985 String serviceName = in.readString();
3986 Uid.Pkg.Serv serv = new Serv();
3987 mServiceStats.put(serviceName, serv);
3988
3989 serv.readFromParcelLocked(in);
3990 }
3991 }
3992
3993 void writeToParcelLocked(Parcel out) {
3994 out.writeInt(mWakeups);
3995 out.writeInt(mLoadedWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003996 out.writeInt(mUnpluggedWakeups);
3997
3998 out.writeInt(mServiceStats.size());
3999 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
4000 out.writeString(servEntry.getKey());
4001 Uid.Pkg.Serv serv = servEntry.getValue();
4002
4003 serv.writeToParcelLocked(out);
4004 }
4005 }
4006
4007 @Override
4008 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
4009 return mServiceStats;
4010 }
4011
4012 @Override
4013 public int getWakeups(int which) {
4014 int val;
4015 if (which == STATS_LAST) {
4016 val = mLastWakeups;
4017 } else {
4018 val = mWakeups;
4019 if (which == STATS_CURRENT) {
4020 val -= mLoadedWakeups;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004021 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004022 val -= mUnpluggedWakeups;
4023 }
4024 }
4025
4026 return val;
4027 }
4028
4029 /**
4030 * The statistics associated with a particular service.
4031 */
4032 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable {
4033 /**
4034 * Total time (ms in battery uptime) the service has been left started.
4035 */
4036 long mStartTime;
4037
4038 /**
4039 * If service has been started and not yet stopped, this is
4040 * when it was started.
4041 */
4042 long mRunningSince;
4043
4044 /**
4045 * True if we are currently running.
4046 */
4047 boolean mRunning;
4048
4049 /**
4050 * Total number of times startService() has been called.
4051 */
4052 int mStarts;
4053
4054 /**
4055 * Total time (ms in battery uptime) the service has been left launched.
4056 */
4057 long mLaunchedTime;
4058
4059 /**
4060 * If service has been launched and not yet exited, this is
4061 * when it was launched (ms in battery uptime).
4062 */
4063 long mLaunchedSince;
4064
4065 /**
4066 * True if we are currently launched.
4067 */
4068 boolean mLaunched;
4069
4070 /**
4071 * Total number times the service has been launched.
4072 */
4073 int mLaunches;
4074
4075 /**
4076 * The amount of time spent started loaded from a previous save
4077 * (ms in battery uptime).
4078 */
4079 long mLoadedStartTime;
4080
4081 /**
4082 * The number of starts loaded from a previous save.
4083 */
4084 int mLoadedStarts;
4085
4086 /**
4087 * The number of launches loaded from a previous save.
4088 */
4089 int mLoadedLaunches;
4090
4091 /**
4092 * The amount of time spent started as of the last run (ms
4093 * in battery uptime).
4094 */
4095 long mLastStartTime;
4096
4097 /**
4098 * The number of starts as of the last run.
4099 */
4100 int mLastStarts;
4101
4102 /**
4103 * The number of launches as of the last run.
4104 */
4105 int mLastLaunches;
4106
4107 /**
4108 * The amount of time spent started when last unplugged (ms
4109 * in battery uptime).
4110 */
4111 long mUnpluggedStartTime;
4112
4113 /**
4114 * The number of starts when last unplugged.
4115 */
4116 int mUnpluggedStarts;
4117
4118 /**
4119 * The number of launches when last unplugged.
4120 */
4121 int mUnpluggedLaunches;
4122
4123 Serv() {
4124 mUnpluggables.add(this);
4125 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004126
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004127 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004128 mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime);
4129 mUnpluggedStarts = mStarts;
4130 mUnpluggedLaunches = mLaunches;
4131 }
4132
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004133 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004134 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004135
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004136 void detach() {
4137 mUnpluggables.remove(this);
4138 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004139
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004140 void readFromParcelLocked(Parcel in) {
4141 mStartTime = in.readLong();
4142 mRunningSince = in.readLong();
4143 mRunning = in.readInt() != 0;
4144 mStarts = in.readInt();
4145 mLaunchedTime = in.readLong();
4146 mLaunchedSince = in.readLong();
4147 mLaunched = in.readInt() != 0;
4148 mLaunches = in.readInt();
4149 mLoadedStartTime = in.readLong();
4150 mLoadedStarts = in.readInt();
4151 mLoadedLaunches = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004152 mLastStartTime = 0;
4153 mLastStarts = 0;
4154 mLastLaunches = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004155 mUnpluggedStartTime = in.readLong();
4156 mUnpluggedStarts = in.readInt();
4157 mUnpluggedLaunches = in.readInt();
4158 }
4159
4160 void writeToParcelLocked(Parcel out) {
4161 out.writeLong(mStartTime);
4162 out.writeLong(mRunningSince);
4163 out.writeInt(mRunning ? 1 : 0);
4164 out.writeInt(mStarts);
4165 out.writeLong(mLaunchedTime);
4166 out.writeLong(mLaunchedSince);
4167 out.writeInt(mLaunched ? 1 : 0);
4168 out.writeInt(mLaunches);
4169 out.writeLong(mLoadedStartTime);
4170 out.writeInt(mLoadedStarts);
4171 out.writeInt(mLoadedLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004172 out.writeLong(mUnpluggedStartTime);
4173 out.writeInt(mUnpluggedStarts);
4174 out.writeInt(mUnpluggedLaunches);
4175 }
4176
4177 long getLaunchTimeToNowLocked(long batteryUptime) {
4178 if (!mLaunched) return mLaunchedTime;
4179 return mLaunchedTime + batteryUptime - mLaunchedSince;
4180 }
4181
4182 long getStartTimeToNowLocked(long batteryUptime) {
4183 if (!mRunning) return mStartTime;
4184 return mStartTime + batteryUptime - mRunningSince;
4185 }
4186
4187 public void startLaunchedLocked() {
4188 if (!mLaunched) {
4189 mLaunches++;
4190 mLaunchedSince = getBatteryUptimeLocked();
4191 mLaunched = true;
4192 }
4193 }
4194
4195 public void stopLaunchedLocked() {
4196 if (mLaunched) {
4197 long time = getBatteryUptimeLocked() - mLaunchedSince;
4198 if (time > 0) {
4199 mLaunchedTime += time;
4200 } else {
4201 mLaunches--;
4202 }
4203 mLaunched = false;
4204 }
4205 }
4206
4207 public void startRunningLocked() {
4208 if (!mRunning) {
4209 mStarts++;
4210 mRunningSince = getBatteryUptimeLocked();
4211 mRunning = true;
4212 }
4213 }
4214
4215 public void stopRunningLocked() {
4216 if (mRunning) {
4217 long time = getBatteryUptimeLocked() - mRunningSince;
4218 if (time > 0) {
4219 mStartTime += time;
4220 } else {
4221 mStarts--;
4222 }
4223 mRunning = false;
4224 }
4225 }
4226
4227 public BatteryStatsImpl getBatteryStats() {
4228 return BatteryStatsImpl.this;
4229 }
4230
4231 @Override
4232 public int getLaunches(int which) {
4233 int val;
4234
4235 if (which == STATS_LAST) {
4236 val = mLastLaunches;
4237 } else {
4238 val = mLaunches;
4239 if (which == STATS_CURRENT) {
4240 val -= mLoadedLaunches;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004241 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004242 val -= mUnpluggedLaunches;
4243 }
4244 }
4245
4246 return val;
4247 }
4248
4249 @Override
4250 public long getStartTime(long now, int which) {
4251 long val;
4252 if (which == STATS_LAST) {
4253 val = mLastStartTime;
4254 } else {
4255 val = getStartTimeToNowLocked(now);
4256 if (which == STATS_CURRENT) {
4257 val -= mLoadedStartTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004258 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004259 val -= mUnpluggedStartTime;
4260 }
4261 }
4262
4263 return val;
4264 }
4265
4266 @Override
4267 public int getStarts(int which) {
4268 int val;
4269 if (which == STATS_LAST) {
4270 val = mLastStarts;
4271 } else {
4272 val = mStarts;
4273 if (which == STATS_CURRENT) {
4274 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004275 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004276 val -= mUnpluggedStarts;
4277 }
4278 }
4279
4280 return val;
4281 }
4282 }
4283
4284 public BatteryStatsImpl getBatteryStats() {
4285 return BatteryStatsImpl.this;
4286 }
4287
4288 public void incWakeupsLocked() {
4289 mWakeups++;
4290 }
4291
4292 final Serv newServiceStatsLocked() {
4293 return new Serv();
4294 }
4295 }
4296
4297 /**
4298 * Retrieve the statistics object for a particular process, creating
4299 * if needed.
4300 */
4301 public Proc getProcessStatsLocked(String name) {
4302 Proc ps = mProcessStats.get(name);
4303 if (ps == null) {
4304 ps = new Proc();
4305 mProcessStats.put(name, ps);
4306 }
4307
4308 return ps;
4309 }
4310
Dianne Hackbornb5e31652010-09-07 12:13:55 -07004311 public SparseArray<? extends Pid> getPidStats() {
4312 return mPids;
4313 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004314
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004315 public Pid getPidStatsLocked(int pid) {
4316 Pid p = mPids.get(pid);
4317 if (p == null) {
4318 p = new Pid();
4319 mPids.put(pid, p);
4320 }
4321 return p;
4322 }
4323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004324 /**
4325 * Retrieve the statistics object for a particular service, creating
4326 * if needed.
4327 */
4328 public Pkg getPackageStatsLocked(String name) {
4329 Pkg ps = mPackageStats.get(name);
4330 if (ps == null) {
4331 ps = new Pkg();
4332 mPackageStats.put(name, ps);
4333 }
4334
4335 return ps;
4336 }
4337
4338 /**
4339 * Retrieve the statistics object for a particular service, creating
4340 * if needed.
4341 */
4342 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
4343 Pkg ps = getPackageStatsLocked(pkg);
4344 Pkg.Serv ss = ps.mServiceStats.get(serv);
4345 if (ss == null) {
4346 ss = ps.newServiceStatsLocked();
4347 ps.mServiceStats.put(serv, ss);
4348 }
4349
4350 return ss;
4351 }
4352
Evan Millarc64edde2009-04-18 12:26:32 -07004353 public StopwatchTimer getWakeTimerLocked(String name, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004354 Wakelock wl = mWakelockStats.get(name);
4355 if (wl == null) {
Dianne Hackbornc24ab862011-10-18 15:55:03 -07004356 final int N = mWakelockStats.size();
Dianne Hackbornaf17baa2013-05-09 15:27:47 -07004357 if (N > MAX_WAKELOCKS_PER_UID) {
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004358 name = BATCHED_WAKELOCK_NAME;
4359 wl = mWakelockStats.get(name);
4360 }
4361 if (wl == null) {
4362 wl = new Wakelock();
4363 mWakelockStats.put(name, wl);
4364 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004365 }
Evan Millarc64edde2009-04-18 12:26:32 -07004366 StopwatchTimer t = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004367 switch (type) {
4368 case WAKE_TYPE_PARTIAL:
4369 t = wl.mTimerPartial;
4370 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004371 t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL,
4372 mPartialTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004373 wl.mTimerPartial = t;
4374 }
4375 return t;
4376 case WAKE_TYPE_FULL:
4377 t = wl.mTimerFull;
4378 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004379 t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL,
4380 mFullTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004381 wl.mTimerFull = t;
4382 }
4383 return t;
4384 case WAKE_TYPE_WINDOW:
4385 t = wl.mTimerWindow;
4386 if (t == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004387 t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW,
4388 mWindowTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004389 wl.mTimerWindow = t;
4390 }
4391 return t;
4392 default:
4393 throw new IllegalArgumentException("type=" + type);
4394 }
4395 }
4396
Evan Millarc64edde2009-04-18 12:26:32 -07004397 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004398 Sensor se = mSensorStats.get(sensor);
4399 if (se == null) {
4400 if (!create) {
4401 return null;
4402 }
4403 se = new Sensor(sensor);
4404 mSensorStats.put(sensor, se);
4405 }
Evan Millarc64edde2009-04-18 12:26:32 -07004406 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004407 if (t != null) {
4408 return t;
4409 }
Evan Millarc64edde2009-04-18 12:26:32 -07004410 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004411 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07004412 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004413 mSensorTimers.put(sensor, timers);
4414 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004415 t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004416 se.mTimer = t;
4417 return t;
4418 }
4419
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004420 public void noteStartWakeLocked(int pid, String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07004421 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004422 if (t != null) {
4423 t.startRunningLocked(BatteryStatsImpl.this);
4424 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07004425 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004426 Pid p = getPidStatsLocked(pid);
Dianne Hackbornb8071d792010-09-09 16:45:15 -07004427 if (p.mWakeStart == 0) {
4428 p.mWakeStart = SystemClock.elapsedRealtime();
4429 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004430 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004431 }
4432
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004433 public void noteStopWakeLocked(int pid, String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07004434 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004435 if (t != null) {
4436 t.stopRunningLocked(BatteryStatsImpl.this);
4437 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07004438 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004439 Pid p = mPids.get(pid);
Dianne Hackbornb8071d792010-09-09 16:45:15 -07004440 if (p != null && p.mWakeStart != 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004441 p.mWakeSum += SystemClock.elapsedRealtime() - p.mWakeStart;
4442 p.mWakeStart = 0;
4443 }
4444 }
4445 }
4446
4447 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) {
4448 Proc p = getProcessStatsLocked(proc);
4449 if (p != null) {
4450 p.addExcessiveWake(overTime, usedTime);
4451 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004452 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004453
Dianne Hackborn287952c2010-09-22 22:34:31 -07004454 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
4455 Proc p = getProcessStatsLocked(proc);
4456 if (p != null) {
4457 p.addExcessiveCpu(overTime, usedTime);
4458 }
4459 }
4460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004461 public void noteStartSensor(int sensor) {
Evan Millarc64edde2009-04-18 12:26:32 -07004462 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004463 if (t != null) {
4464 t.startRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004465 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004466 }
4467
4468 public void noteStopSensor(int sensor) {
4469 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07004470 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004471 if (t != null) {
4472 t.stopRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004473 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004474 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004476 public void noteStartGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07004477 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004478 if (t != null) {
4479 t.startRunningLocked(BatteryStatsImpl.this);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004480 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004481 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004482
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004483 public void noteStopGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07004484 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004485 if (t != null) {
4486 t.stopRunningLocked(BatteryStatsImpl.this);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004487 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004488 }
4489
4490 public BatteryStatsImpl getBatteryStats() {
4491 return BatteryStatsImpl.this;
4492 }
4493 }
4494
Jeff Brown6f357d32014-01-15 20:40:55 -08004495 public BatteryStatsImpl(String filename, Handler handler) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004496 mFile = new JournaledFile(new File(filename), new File(filename + ".tmp"));
Jeff Brown6f357d32014-01-15 20:40:55 -08004497 mHandler = new MyHandler(handler.getLooper());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004498 mStartCount++;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004499 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004500 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004501 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004502 }
4503 mInputEventCounter = new Counter(mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004504 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables);
Wink Saville52840902011-02-18 12:40:47 -08004505 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004506 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004507 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004508 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004509 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004510 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004511 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004512 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
4513 mNetworkActivityCounters[i] = new LongSamplingCounter(mUnpluggables);
4514 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004515 mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004516 mGlobalWifiRunningTimer = new StopwatchTimer(null, -4, null, mUnpluggables);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004517 mBluetoothOnTimer = new StopwatchTimer(null, -5, null, mUnpluggables);
4518 mAudioOnTimer = new StopwatchTimer(null, -6, null, mUnpluggables);
4519 mVideoOnTimer = new StopwatchTimer(null, -7, null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004520 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004521 initTimes();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004522 mTrackBatteryPastUptime = 0;
4523 mTrackBatteryPastRealtime = 0;
4524 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
4525 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
4526 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
4527 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
Evan Millar633a1742009-04-02 16:36:33 -07004528 mDischargeStartLevel = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004529 mDischargeUnplugLevel = 0;
Evan Millar633a1742009-04-02 16:36:33 -07004530 mDischargeCurrentLevel = 0;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004531 initDischarge();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004532 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004533 }
4534
4535 public BatteryStatsImpl(Parcel p) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004536 mFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004537 mHandler = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004538 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004539 readFromParcel(p);
4540 }
4541
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004542 public void setCallback(BatteryCallback cb) {
4543 mCallback = cb;
4544 }
4545
Amith Yamasanie43530a2009-08-21 13:11:37 -07004546 public void setNumSpeedSteps(int steps) {
4547 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
4548 }
4549
Amith Yamasanif37447b2009-10-08 18:28:01 -07004550 public void setRadioScanningTimeout(long timeout) {
4551 if (mPhoneSignalScanningTimer != null) {
4552 mPhoneSignalScanningTimer.setTimeout(timeout);
4553 }
4554 }
4555
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004556 @Override
4557 public boolean startIteratingOldHistoryLocked() {
4558 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
4559 + " pos=" + mHistoryBuffer.dataPosition());
4560 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004561 mHistoryReadTmp.clear();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004562 mReadOverflow = false;
4563 mIteratingHistory = true;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004564 return (mHistoryIterator = mHistory) != null;
4565 }
4566
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004567 @Override
4568 public boolean getNextOldHistoryLocked(HistoryItem out) {
4569 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize();
4570 if (!end) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004571 mHistoryReadTmp.readDelta(mHistoryBuffer);
4572 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004573 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004574 HistoryItem cur = mHistoryIterator;
4575 if (cur == null) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004576 if (!mReadOverflow && !end) {
4577 Slog.w(TAG, "Old history ends before new history!");
4578 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004579 return false;
4580 }
4581 out.setTo(cur);
4582 mHistoryIterator = cur.next;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004583 if (!mReadOverflow) {
4584 if (end) {
4585 Slog.w(TAG, "New history ends before old history!");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004586 } else if (!out.same(mHistoryReadTmp)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004587 long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
Dianne Hackborn8c841092013-06-24 13:46:13 -07004588 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004589 pw.println("Histories differ!");
4590 pw.println("Old history:");
4591 (new HistoryPrinter()).printNextItem(pw, out, now);
4592 pw.println("New history:");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004593 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, now);
Dianne Hackborn8c841092013-06-24 13:46:13 -07004594 pw.flush();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004595 }
4596 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07004597 return true;
4598 }
4599
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004600 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004601 public void finishIteratingOldHistoryLocked() {
4602 mIteratingHistory = false;
4603 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
4604 }
4605
4606 @Override
4607 public boolean startIteratingHistoryLocked() {
4608 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
4609 + " pos=" + mHistoryBuffer.dataPosition());
4610 mHistoryBuffer.setDataPosition(0);
4611 mReadOverflow = false;
4612 mIteratingHistory = true;
4613 return mHistoryBuffer.dataSize() > 0;
4614 }
4615
4616 @Override
4617 public boolean getNextHistoryLocked(HistoryItem out) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004618 final int pos = mHistoryBuffer.dataPosition();
4619 if (pos == 0) {
4620 out.clear();
4621 }
4622 boolean end = pos >= mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004623 if (end) {
4624 return false;
4625 }
4626
Dianne Hackborn1fadab52011-04-14 17:57:33 -07004627 out.readDelta(mHistoryBuffer);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07004628 return true;
4629 }
4630
4631 @Override
4632 public void finishIteratingHistoryLocked() {
4633 mIteratingHistory = false;
4634 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004635 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004636
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004637 @Override
Dianne Hackbornb5e31652010-09-07 12:13:55 -07004638 public long getHistoryBaseTime() {
4639 return mHistoryBaseTime;
4640 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004641
Dianne Hackbornb5e31652010-09-07 12:13:55 -07004642 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004643 public int getStartCount() {
4644 return mStartCount;
4645 }
4646
4647 public boolean isOnBattery() {
4648 return mOnBattery;
4649 }
4650
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004651 public boolean isScreenOn() {
4652 return mScreenOn;
4653 }
4654
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004655 void initTimes() {
4656 mBatteryRealtime = mTrackBatteryPastUptime = 0;
4657 mBatteryUptime = mTrackBatteryPastRealtime = 0;
4658 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
4659 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
4660 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
4661 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
4662 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004663
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004664 void initDischarge() {
4665 mLowDischargeAmountSinceCharge = 0;
4666 mHighDischargeAmountSinceCharge = 0;
4667 mDischargeAmountScreenOn = 0;
4668 mDischargeAmountScreenOnSinceCharge = 0;
4669 mDischargeAmountScreenOff = 0;
4670 mDischargeAmountScreenOffSinceCharge = 0;
4671 }
4672
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004673 public void resetAllStatsLocked() {
4674 mStartCount = 0;
4675 initTimes();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004676 mScreenOnTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004677 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004678 mScreenBrightnessTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004679 }
4680 mInputEventCounter.reset(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004681 mPhoneOnTimer.reset(this, false);
4682 mAudioOnTimer.reset(this, false);
4683 mVideoOnTimer.reset(this, false);
Wink Saville52840902011-02-18 12:40:47 -08004684 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004685 mPhoneSignalStrengthsTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004686 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004687 mPhoneSignalScanningTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004688 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004689 mPhoneDataConnectionsTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004690 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004691 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
4692 mNetworkActivityCounters[i].reset(false);
4693 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004694 mWifiOnTimer.reset(this, false);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004695 mGlobalWifiRunningTimer.reset(this, false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004696 mBluetoothOnTimer.reset(this, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004697
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004698 for (int i=0; i<mUidStats.size(); i++) {
4699 if (mUidStats.valueAt(i).reset()) {
4700 mUidStats.remove(mUidStats.keyAt(i));
4701 i--;
4702 }
4703 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004704
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004705 if (mKernelWakelockStats.size() > 0) {
4706 for (SamplingTimer timer : mKernelWakelockStats.values()) {
4707 mUnpluggables.remove(timer);
4708 }
4709 mKernelWakelockStats.clear();
4710 }
4711
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004712 initDischarge();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004713
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004714 clearHistoryLocked();
4715 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004716
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004717 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) {
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004718 if (oldScreenOn) {
4719 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
4720 if (diff > 0) {
4721 mDischargeAmountScreenOn += diff;
4722 mDischargeAmountScreenOnSinceCharge += diff;
4723 }
4724 } else {
4725 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel;
4726 if (diff > 0) {
4727 mDischargeAmountScreenOff += diff;
4728 mDischargeAmountScreenOffSinceCharge += diff;
4729 }
4730 }
4731 if (newScreenOn) {
4732 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel;
4733 mDischargeScreenOffUnplugLevel = 0;
4734 } else {
4735 mDischargeScreenOnUnplugLevel = 0;
4736 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
4737 }
4738 }
4739
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004740 void setOnBattery(boolean onBattery, int oldStatus, int level) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004741 synchronized(this) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004742 setOnBatteryLocked(onBattery, oldStatus, level);
4743 }
4744 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004745
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004746 void setOnBatteryLocked(boolean onBattery, int oldStatus, int level) {
4747 boolean doWrite = false;
4748 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
4749 m.arg1 = onBattery ? 1 : 0;
4750 mHandler.sendMessage(m);
4751 mOnBattery = mOnBatteryInternal = onBattery;
4752
4753 long uptime = SystemClock.uptimeMillis() * 1000;
4754 long mSecRealtime = SystemClock.elapsedRealtime();
4755 long realtime = mSecRealtime * 1000;
4756 if (onBattery) {
4757 // We will reset our status if we are unplugging after the
4758 // battery was last full, or the level is at 100, or
4759 // we have gone through a significant charge (from a very low
4760 // level to a now very high level).
4761 if (oldStatus == BatteryManager.BATTERY_STATUS_FULL
4762 || level >= 90
4763 || (mDischargeCurrentLevel < 20 && level >= 80)) {
4764 doWrite = true;
4765 resetAllStatsLocked();
4766 mDischargeStartLevel = level;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004767 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004768 updateKernelWakelocksLocked();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004769 updateNetworkActivityLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004770 mHistoryCur.batteryLevel = (byte)level;
4771 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4772 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
4773 + Integer.toHexString(mHistoryCur.states));
4774 addHistoryRecordLocked(mSecRealtime);
4775 mTrackBatteryUptimeStart = uptime;
4776 mTrackBatteryRealtimeStart = realtime;
4777 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
4778 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
4779 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
4780 if (mScreenOn) {
4781 mDischargeScreenOnUnplugLevel = level;
4782 mDischargeScreenOffUnplugLevel = 0;
4783 } else {
4784 mDischargeScreenOnUnplugLevel = 0;
4785 mDischargeScreenOffUnplugLevel = level;
4786 }
4787 mDischargeAmountScreenOn = 0;
4788 mDischargeAmountScreenOff = 0;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004789 doUnplugLocked(realtime, mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004790 } else {
4791 updateKernelWakelocksLocked();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004792 updateNetworkActivityLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004793 mHistoryCur.batteryLevel = (byte)level;
4794 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4795 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
4796 + Integer.toHexString(mHistoryCur.states));
4797 addHistoryRecordLocked(mSecRealtime);
4798 mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
4799 mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
4800 mDischargeCurrentLevel = level;
4801 if (level < mDischargeUnplugLevel) {
4802 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
4803 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
4804 }
4805 updateDischargeScreenLevelsLocked(mScreenOn, mScreenOn);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004806 doPlugLocked(realtime, getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004807 }
4808 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
4809 if (mFile != null) {
4810 writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004811 }
4812 }
4813 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004814
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004815 // This should probably be exposed in the API, though it's not critical
4816 private static final int BATTERY_PLUGGED_NONE = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004817
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004818 public void setBatteryState(int status, int health, int plugType, int level,
4819 int temp, int volt) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004820 synchronized(this) {
4821 boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
4822 int oldStatus = mHistoryCur.batteryStatus;
4823 if (!mHaveBatteryLevel) {
4824 mHaveBatteryLevel = true;
4825 // We start out assuming that the device is plugged in (not
4826 // on battery). If our first report is now that we are indeed
4827 // plugged in, then twiddle our state to correctly reflect that
4828 // since we won't be going through the full setOnBattery().
4829 if (onBattery == mOnBattery) {
4830 if (onBattery) {
4831 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4832 } else {
4833 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
4834 }
4835 }
4836 oldStatus = status;
4837 }
4838 if (onBattery) {
4839 mDischargeCurrentLevel = level;
4840 mRecordingHistory = true;
4841 }
4842 if (onBattery != mOnBattery) {
4843 mHistoryCur.batteryLevel = (byte)level;
4844 mHistoryCur.batteryStatus = (byte)status;
4845 mHistoryCur.batteryHealth = (byte)health;
4846 mHistoryCur.batteryPlugType = (byte)plugType;
Sungmin Choic7e9e8b2013-01-16 12:57:36 +09004847 mHistoryCur.batteryTemperature = (short)temp;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004848 mHistoryCur.batteryVoltage = (char)volt;
4849 setOnBatteryLocked(onBattery, oldStatus, level);
4850 } else {
4851 boolean changed = false;
4852 if (mHistoryCur.batteryLevel != level) {
4853 mHistoryCur.batteryLevel = (byte)level;
4854 changed = true;
4855 }
4856 if (mHistoryCur.batteryStatus != status) {
4857 mHistoryCur.batteryStatus = (byte)status;
4858 changed = true;
4859 }
4860 if (mHistoryCur.batteryHealth != health) {
4861 mHistoryCur.batteryHealth = (byte)health;
4862 changed = true;
4863 }
4864 if (mHistoryCur.batteryPlugType != plugType) {
4865 mHistoryCur.batteryPlugType = (byte)plugType;
4866 changed = true;
4867 }
4868 if (temp >= (mHistoryCur.batteryTemperature+10)
4869 || temp <= (mHistoryCur.batteryTemperature-10)) {
Sungmin Choic7e9e8b2013-01-16 12:57:36 +09004870 mHistoryCur.batteryTemperature = (short)temp;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004871 changed = true;
4872 }
4873 if (volt > (mHistoryCur.batteryVoltage+20)
4874 || volt < (mHistoryCur.batteryVoltage-20)) {
4875 mHistoryCur.batteryVoltage = (char)volt;
4876 changed = true;
4877 }
4878 if (changed) {
4879 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004880 }
4881 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08004882 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
4883 // We don't record history while we are plugged in and fully charged.
4884 // The next time we are unplugged, history will be cleared.
4885 mRecordingHistory = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004886 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004887 }
Evan Millar633a1742009-04-02 16:36:33 -07004888 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004889
Evan Millarc64edde2009-04-18 12:26:32 -07004890 public void updateKernelWakelocksLocked() {
4891 Map<String, KernelWakelockStats> m = readKernelWakelockStats();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004892
Marco Nelissend8593312009-04-30 14:45:06 -07004893 if (m == null) {
4894 // Not crashing might make board bringup easier.
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004895 Slog.w(TAG, "Couldn't get kernel wake lock stats");
Marco Nelissend8593312009-04-30 14:45:06 -07004896 return;
4897 }
4898
Evan Millarc64edde2009-04-18 12:26:32 -07004899 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) {
4900 String name = ent.getKey();
4901 KernelWakelockStats kws = ent.getValue();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004902
Evan Millarc64edde2009-04-18 12:26:32 -07004903 SamplingTimer kwlt = mKernelWakelockStats.get(name);
4904 if (kwlt == null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004905 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
Evan Millarc64edde2009-04-18 12:26:32 -07004906 true /* track reported values */);
4907 mKernelWakelockStats.put(name, kwlt);
4908 }
4909 kwlt.updateCurrentReportedCount(kws.mCount);
4910 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
4911 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion);
4912 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004913
Evan Millarc64edde2009-04-18 12:26:32 -07004914 if (m.size() != mKernelWakelockStats.size()) {
4915 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
4916 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
4917 SamplingTimer st = ent.getValue();
4918 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) {
4919 st.setStale();
4920 }
4921 }
4922 }
4923 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004924
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004925 private void updateNetworkActivityLocked() {
4926 if (!SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) return;
4927
4928 final NetworkStats snapshot;
4929 try {
4930 snapshot = mNetworkStatsFactory.readNetworkStatsDetail();
4931 } catch (IOException e) {
4932 Log.wtf(TAG, "Failed to read network stats", e);
4933 return;
4934 }
4935
4936 if (mLastSnapshot == null) {
4937 mLastSnapshot = snapshot;
4938 return;
4939 }
4940
4941 final NetworkStats delta = snapshot.subtract(mLastSnapshot);
4942 mLastSnapshot = snapshot;
4943
4944 NetworkStats.Entry entry = null;
4945 final int size = delta.size();
4946 for (int i = 0; i < size; i++) {
4947 entry = delta.getValues(i, entry);
4948
4949 if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
4950 if (entry.tag != NetworkStats.TAG_NONE) continue;
4951
4952 final Uid u = getUidStatsLocked(entry.uid);
4953
4954 if (mMobileIfaces.contains(entry.iface)) {
4955 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_BYTES, entry.rxBytes);
4956 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_BYTES, entry.txBytes);
4957
4958 mNetworkActivityCounters[NETWORK_MOBILE_RX_BYTES].addCountLocked(entry.rxBytes);
4959 mNetworkActivityCounters[NETWORK_MOBILE_TX_BYTES].addCountLocked(entry.txBytes);
4960
4961 } else if (mWifiIfaces.contains(entry.iface)) {
4962 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_BYTES, entry.rxBytes);
4963 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_BYTES, entry.txBytes);
4964
4965 mNetworkActivityCounters[NETWORK_WIFI_RX_BYTES].addCountLocked(entry.rxBytes);
4966 mNetworkActivityCounters[NETWORK_WIFI_TX_BYTES].addCountLocked(entry.txBytes);
4967 }
4968 }
4969 }
4970
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004971 public long getAwakeTimeBattery() {
4972 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
4973 }
4974
4975 public long getAwakeTimePlugged() {
4976 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
4977 }
4978
4979 @Override
4980 public long computeUptime(long curTime, int which) {
4981 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004982 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004983 case STATS_LAST: return mLastUptime;
4984 case STATS_CURRENT: return (curTime-mUptimeStart);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004985 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004986 }
4987 return 0;
4988 }
4989
4990 @Override
4991 public long computeRealtime(long curTime, int which) {
4992 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004993 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004994 case STATS_LAST: return mLastRealtime;
4995 case STATS_CURRENT: return (curTime-mRealtimeStart);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004996 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004997 }
4998 return 0;
4999 }
5000
5001 @Override
5002 public long computeBatteryUptime(long curTime, int which) {
5003 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005004 case STATS_SINCE_CHARGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005005 return mBatteryUptime + getBatteryUptime(curTime);
5006 case STATS_LAST:
5007 return mBatteryLastUptime;
5008 case STATS_CURRENT:
5009 return getBatteryUptime(curTime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005010 case STATS_SINCE_UNPLUGGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005011 return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime;
5012 }
5013 return 0;
5014 }
5015
5016 @Override
5017 public long computeBatteryRealtime(long curTime, int which) {
5018 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005019 case STATS_SINCE_CHARGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005020 return mBatteryRealtime + getBatteryRealtimeLocked(curTime);
5021 case STATS_LAST:
5022 return mBatteryLastRealtime;
5023 case STATS_CURRENT:
5024 return getBatteryRealtimeLocked(curTime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005025 case STATS_SINCE_UNPLUGGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005026 return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime;
5027 }
5028 return 0;
5029 }
5030
5031 long getBatteryUptimeLocked(long curTime) {
5032 long time = mTrackBatteryPastUptime;
5033 if (mOnBatteryInternal) {
5034 time += curTime - mTrackBatteryUptimeStart;
5035 }
5036 return time;
5037 }
5038
5039 long getBatteryUptimeLocked() {
5040 return getBatteryUptime(SystemClock.uptimeMillis() * 1000);
5041 }
5042
5043 @Override
5044 public long getBatteryUptime(long curTime) {
5045 return getBatteryUptimeLocked(curTime);
5046 }
5047
5048 long getBatteryRealtimeLocked(long curTime) {
5049 long time = mTrackBatteryPastRealtime;
5050 if (mOnBatteryInternal) {
5051 time += curTime - mTrackBatteryRealtimeStart;
5052 }
5053 return time;
5054 }
5055
5056 @Override
5057 public long getBatteryRealtime(long curTime) {
5058 return getBatteryRealtimeLocked(curTime);
5059 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07005060
The Android Open Source Project10592532009-03-18 17:39:46 -07005061 @Override
Evan Millar633a1742009-04-02 16:36:33 -07005062 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07005063 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07005064 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07005065 }
5066 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005067
Evan Millar633a1742009-04-02 16:36:33 -07005068 public int getDischargeStartLevelLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005069 return mDischargeUnplugLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07005070 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005071
The Android Open Source Project10592532009-03-18 17:39:46 -07005072 @Override
Evan Millar633a1742009-04-02 16:36:33 -07005073 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07005074 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07005075 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07005076 }
5077 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005078
Evan Millar633a1742009-04-02 16:36:33 -07005079 public int getDischargeCurrentLevelLocked() {
Dianne Hackborne4a59512010-12-07 11:08:07 -08005080 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07005081 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005082
Amith Yamasanie43530a2009-08-21 13:11:37 -07005083 @Override
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005084 public int getLowDischargeAmountSinceCharge() {
5085 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08005086 int val = mLowDischargeAmountSinceCharge;
5087 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
5088 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
5089 }
5090 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005091 }
5092 }
5093
5094 @Override
5095 public int getHighDischargeAmountSinceCharge() {
5096 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08005097 int val = mHighDischargeAmountSinceCharge;
5098 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
5099 val += mDischargeUnplugLevel-mDischargeCurrentLevel;
5100 }
5101 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005102 }
5103 }
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005104
5105 public int getDischargeAmountScreenOn() {
5106 synchronized(this) {
5107 int val = mDischargeAmountScreenOn;
5108 if (mOnBattery && mScreenOn
5109 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
5110 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
5111 }
5112 return val;
5113 }
5114 }
5115
5116 public int getDischargeAmountScreenOnSinceCharge() {
5117 synchronized(this) {
5118 int val = mDischargeAmountScreenOnSinceCharge;
5119 if (mOnBattery && mScreenOn
5120 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
5121 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
5122 }
5123 return val;
5124 }
5125 }
5126
5127 public int getDischargeAmountScreenOff() {
5128 synchronized(this) {
5129 int val = mDischargeAmountScreenOff;
5130 if (mOnBattery && !mScreenOn
5131 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
5132 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
5133 }
5134 return val;
5135 }
5136 }
5137
5138 public int getDischargeAmountScreenOffSinceCharge() {
5139 synchronized(this) {
5140 int val = mDischargeAmountScreenOffSinceCharge;
5141 if (mOnBattery && !mScreenOn
5142 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
5143 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
5144 }
5145 return val;
5146 }
5147 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005148
5149 @Override
Amith Yamasanie43530a2009-08-21 13:11:37 -07005150 public int getCpuSpeedSteps() {
5151 return sNumSpeedSteps;
5152 }
5153
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005154 /**
5155 * Retrieve the statistics object for a particular uid, creating if needed.
5156 */
5157 public Uid getUidStatsLocked(int uid) {
5158 Uid u = mUidStats.get(uid);
5159 if (u == null) {
5160 u = new Uid(uid);
5161 mUidStats.put(uid, u);
5162 }
5163 return u;
5164 }
5165
5166 /**
5167 * Remove the statistics object for a particular uid.
5168 */
5169 public void removeUidStatsLocked(int uid) {
5170 mUidStats.remove(uid);
5171 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07005172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005173 /**
5174 * Retrieve the statistics object for a particular process, creating
5175 * if needed.
5176 */
5177 public Uid.Proc getProcessStatsLocked(int uid, String name) {
5178 Uid u = getUidStatsLocked(uid);
5179 return u.getProcessStatsLocked(name);
5180 }
5181
5182 /**
Amith Yamasani32dbefd2009-06-19 09:21:17 -07005183 * Retrieve the statistics object for a particular process, given
5184 * the name of the process.
5185 * @param name process name
5186 * @return the statistics object for the process
5187 */
Amith Yamasani819f9282009-06-24 23:18:15 -07005188 public Uid.Proc getProcessStatsLocked(String name, int pid) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -07005189 int uid;
5190 if (mUidCache.containsKey(name)) {
5191 uid = mUidCache.get(name);
5192 } else {
Amith Yamasani819f9282009-06-24 23:18:15 -07005193 uid = Process.getUidForPid(pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07005194 mUidCache.put(name, uid);
5195 }
5196 Uid u = getUidStatsLocked(uid);
5197 return u.getProcessStatsLocked(name);
5198 }
5199
5200 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005201 * Retrieve the statistics object for a particular process, creating
5202 * if needed.
5203 */
5204 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
5205 Uid u = getUidStatsLocked(uid);
5206 return u.getPackageStatsLocked(pkg);
5207 }
5208
5209 /**
5210 * Retrieve the statistics object for a particular service, creating
5211 * if needed.
5212 */
5213 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
5214 Uid u = getUidStatsLocked(uid);
5215 return u.getServiceStatsLocked(pkg, name);
5216 }
5217
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005218 /**
5219 * Massage data to distribute any reasonable work down to more specific
5220 * owners. Must only be called on a dead BatteryStats object!
5221 */
5222 public void distributeWorkLocked(int which) {
5223 // Aggregate all CPU time associated with WIFI.
5224 Uid wifiUid = mUidStats.get(Process.WIFI_UID);
5225 if (wifiUid != null) {
5226 long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
5227 for (Uid.Proc proc : wifiUid.mProcessStats.values()) {
5228 long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which);
5229 for (int i=0; i<mUidStats.size(); i++) {
5230 Uid uid = mUidStats.valueAt(i);
5231 if (uid.mUid != Process.WIFI_UID) {
5232 long uidRunningTime = uid.getWifiRunningTime(uSecTime, which);
5233 if (uidRunningTime > 0) {
5234 Uid.Proc uidProc = uid.getProcessStatsLocked("*wifi*");
5235 long time = proc.getUserTime(which);
5236 time = (time*uidRunningTime)/totalRunningTime;
5237 uidProc.mUserTime += time;
5238 proc.mUserTime -= time;
5239 time = proc.getSystemTime(which);
5240 time = (time*uidRunningTime)/totalRunningTime;
5241 uidProc.mSystemTime += time;
5242 proc.mSystemTime -= time;
5243 time = proc.getForegroundTime(which);
5244 time = (time*uidRunningTime)/totalRunningTime;
5245 uidProc.mForegroundTime += time;
5246 proc.mForegroundTime -= time;
5247 for (int sb=0; sb<proc.mSpeedBins.length; sb++) {
5248 SamplingCounter sc = proc.mSpeedBins[sb];
5249 if (sc != null) {
5250 time = sc.getCountLocked(which);
5251 time = (time*uidRunningTime)/totalRunningTime;
5252 SamplingCounter uidSc = uidProc.mSpeedBins[sb];
5253 if (uidSc == null) {
5254 uidSc = new SamplingCounter(mUnpluggables);
5255 uidProc.mSpeedBins[sb] = uidSc;
5256 }
5257 uidSc.mCount.addAndGet((int)time);
5258 sc.mCount.addAndGet((int)-time);
5259 }
5260 }
5261 totalRunningTime -= uidRunningTime;
5262 }
5263 }
5264 }
5265 }
5266 }
5267 }
5268
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005269 public void shutdownLocked() {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005270 writeSyncLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005271 mShuttingDown = true;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005272 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005273
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005274 Parcel mPendingWrite = null;
5275 final ReentrantLock mWriteLock = new ReentrantLock();
5276
5277 public void writeAsyncLocked() {
5278 writeLocked(false);
5279 }
5280
5281 public void writeSyncLocked() {
5282 writeLocked(true);
5283 }
5284
5285 void writeLocked(boolean sync) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005286 if (mFile == null) {
5287 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005288 return;
5289 }
5290
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005291 if (mShuttingDown) {
5292 return;
5293 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005294
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005295 Parcel out = Parcel.obtain();
5296 writeSummaryToParcel(out);
5297 mLastWriteTime = SystemClock.elapsedRealtime();
5298
5299 if (mPendingWrite != null) {
5300 mPendingWrite.recycle();
5301 }
5302 mPendingWrite = out;
5303
5304 if (sync) {
5305 commitPendingDataToDisk();
5306 } else {
5307 Thread thr = new Thread("BatteryStats-Write") {
5308 @Override
5309 public void run() {
5310 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
5311 commitPendingDataToDisk();
5312 }
5313 };
5314 thr.start();
5315 }
5316 }
5317
5318 public void commitPendingDataToDisk() {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07005319 final Parcel next;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005320 synchronized (this) {
5321 next = mPendingWrite;
5322 mPendingWrite = null;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07005323 if (next == null) {
5324 return;
5325 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005326
5327 mWriteLock.lock();
5328 }
5329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005330 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005331 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005332 stream.write(next.marshall());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005333 stream.flush();
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07005334 FileUtils.sync(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005335 stream.close();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005336 mFile.commit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005337 } catch (IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005338 Slog.w("BatteryStats", "Error writing battery statistics", e);
Dianne Hackbornce2ef762010-09-20 11:39:14 -07005339 mFile.rollback();
5340 } finally {
5341 next.recycle();
5342 mWriteLock.unlock();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07005343 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005344 }
5345
5346 static byte[] readFully(FileInputStream stream) throws java.io.IOException {
5347 int pos = 0;
5348 int avail = stream.available();
5349 byte[] data = new byte[avail];
5350 while (true) {
5351 int amt = stream.read(data, pos, data.length-pos);
5352 //Log.i("foo", "Read " + amt + " bytes at " + pos
5353 // + " of avail " + data.length);
5354 if (amt <= 0) {
5355 //Log.i("foo", "**** FINISHED READING: pos=" + pos
5356 // + " len=" + data.length);
5357 return data;
5358 }
5359 pos += amt;
5360 avail = stream.available();
5361 if (avail > data.length-pos) {
5362 byte[] newData = new byte[pos+avail];
5363 System.arraycopy(data, 0, newData, 0, pos);
5364 data = newData;
5365 }
5366 }
5367 }
5368
5369 public void readLocked() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005370 if (mFile == null) {
5371 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005372 return;
5373 }
5374
5375 mUidStats.clear();
5376
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005377 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005378 File file = mFile.chooseForRead();
5379 if (!file.exists()) {
5380 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005381 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005382 FileInputStream stream = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005383
5384 byte[] raw = readFully(stream);
5385 Parcel in = Parcel.obtain();
5386 in.unmarshall(raw, 0, raw.length);
5387 in.setDataPosition(0);
5388 stream.close();
5389
5390 readSummaryFromParcel(in);
5391 } catch(java.io.IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005392 Slog.e("BatteryStats", "Error reading battery statistics", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005393 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005394
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005395 long now = SystemClock.elapsedRealtime();
Dianne Hackborne8c88e62011-08-17 19:09:09 -07005396 if (USE_OLD_HISTORY) {
5397 addHistoryRecordLocked(now, HistoryItem.CMD_START);
5398 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005399 addHistoryBufferLocked(now, HistoryItem.CMD_START);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005400 }
5401
5402 public int describeContents() {
5403 return 0;
5404 }
5405
Dianne Hackbornae384452011-06-28 12:33:48 -07005406 void readHistory(Parcel in, boolean andOldHistory) {
5407 final long historyBaseTime = in.readLong();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005408
5409 mHistoryBuffer.setDataSize(0);
5410 mHistoryBuffer.setDataPosition(0);
5411
5412 int bufSize = in.readInt();
5413 int curPos = in.dataPosition();
5414 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) {
5415 Slog.w(TAG, "File corrupt: history data buffer too large " + bufSize);
5416 } else if ((bufSize&~3) != bufSize) {
5417 Slog.w(TAG, "File corrupt: history data buffer not aligned " + bufSize);
5418 } else {
5419 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize
5420 + " bytes at " + curPos);
5421 mHistoryBuffer.appendFrom(in, curPos, bufSize);
5422 in.setDataPosition(curPos + bufSize);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005423 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005424
Dianne Hackbornae384452011-06-28 12:33:48 -07005425 if (andOldHistory) {
5426 readOldHistory(in);
5427 }
5428
5429 if (DEBUG_HISTORY) {
5430 StringBuilder sb = new StringBuilder(128);
5431 sb.append("****************** OLD mHistoryBaseTime: ");
5432 TimeUtils.formatDuration(mHistoryBaseTime, sb);
5433 Slog.i(TAG, sb.toString());
5434 }
5435 mHistoryBaseTime = historyBaseTime;
5436 if (DEBUG_HISTORY) {
5437 StringBuilder sb = new StringBuilder(128);
5438 sb.append("****************** NEW mHistoryBaseTime: ");
5439 TimeUtils.formatDuration(mHistoryBaseTime, sb);
5440 Slog.i(TAG, sb.toString());
5441 }
5442
5443 // We are just arbitrarily going to insert 1 minute from the sample of
5444 // the last run until samples in this run.
5445 if (mHistoryBaseTime > 0) {
5446 long oldnow = SystemClock.elapsedRealtime();
5447 mHistoryBaseTime = (mHistoryBaseTime - oldnow) + 60*1000;
5448 if (DEBUG_HISTORY) {
5449 StringBuilder sb = new StringBuilder(128);
5450 sb.append("****************** ADJUSTED mHistoryBaseTime: ");
5451 TimeUtils.formatDuration(mHistoryBaseTime, sb);
5452 Slog.i(TAG, sb.toString());
5453 }
Dianne Hackborn1e4b9f32010-06-23 14:10:57 -07005454 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005455 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005456
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005457 void readOldHistory(Parcel in) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07005458 if (!USE_OLD_HISTORY) {
5459 return;
5460 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005461 mHistory = mHistoryEnd = mHistoryCache = null;
5462 long time;
Conley Owens5e3357f2011-05-02 09:59:30 -07005463 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005464 HistoryItem rec = new HistoryItem(time, in);
5465 addHistoryRecordLocked(rec);
5466 }
5467 }
5468
Dianne Hackbornae384452011-06-28 12:33:48 -07005469 void writeHistory(Parcel out, boolean andOldHistory) {
5470 if (DEBUG_HISTORY) {
5471 StringBuilder sb = new StringBuilder(128);
5472 sb.append("****************** WRITING mHistoryBaseTime: ");
5473 TimeUtils.formatDuration(mHistoryBaseTime, sb);
5474 sb.append(" mLastHistoryTime: ");
5475 TimeUtils.formatDuration(mLastHistoryTime, sb);
5476 Slog.i(TAG, sb.toString());
5477 }
5478 out.writeLong(mHistoryBaseTime + mLastHistoryTime);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005479 out.writeInt(mHistoryBuffer.dataSize());
5480 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
5481 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
5482 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
Dianne Hackbornae384452011-06-28 12:33:48 -07005483
5484 if (andOldHistory) {
5485 writeOldHistory(out);
5486 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005487 }
5488
5489 void writeOldHistory(Parcel out) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07005490 if (!USE_OLD_HISTORY) {
5491 return;
5492 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005493 HistoryItem rec = mHistory;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005494 while (rec != null) {
5495 if (rec.time >= 0) rec.writeToParcel(out, 0);
5496 rec = rec.next;
5497 }
5498 out.writeLong(-1);
5499 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005501 private void readSummaryFromParcel(Parcel in) {
5502 final int version = in.readInt();
5503 if (version != VERSION) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005504 Slog.w("BatteryStats", "readFromParcel: version got " + version
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005505 + ", expected " + VERSION + "; erasing old stats");
5506 return;
5507 }
5508
Dianne Hackbornae384452011-06-28 12:33:48 -07005509 readHistory(in, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005510
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005511 mStartCount = in.readInt();
5512 mBatteryUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005513 mBatteryRealtime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005514 mUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005515 mRealtime = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005516 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07005517 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005518 mLowDischargeAmountSinceCharge = in.readInt();
5519 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005520 mDischargeAmountScreenOnSinceCharge = in.readInt();
5521 mDischargeAmountScreenOffSinceCharge = in.readInt();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005522
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005523 mStartCount++;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005525 mScreenOn = false;
5526 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005527 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
5528 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
5529 }
5530 mInputEventCounter.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005531 mPhoneOn = false;
5532 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Wink Saville52840902011-02-18 12:40:47 -08005533 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07005534 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
5535 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005536 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005537 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
5538 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
5539 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005540 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
5541 mNetworkActivityCounters[i].readSummaryFromParcelLocked(in);
5542 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005543 mWifiOn = false;
5544 mWifiOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005545 mGlobalWifiRunning = false;
5546 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07005547 mBluetoothOn = false;
5548 mBluetoothOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005549
Evan Millarc64edde2009-04-18 12:26:32 -07005550 int NKW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005551 if (NKW > 10000) {
5552 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW);
5553 return;
5554 }
Evan Millarc64edde2009-04-18 12:26:32 -07005555 for (int ikw = 0; ikw < NKW; ikw++) {
5556 if (in.readInt() != 0) {
5557 String kwltName = in.readString();
5558 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
5559 }
5560 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07005561
5562 sNumSpeedSteps = in.readInt();
5563
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005564 final int NU = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005565 if (NU > 10000) {
5566 Slog.w(TAG, "File corrupt: too many uids " + NU);
5567 return;
5568 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005569 for (int iu = 0; iu < NU; iu++) {
5570 int uid = in.readInt();
5571 Uid u = new Uid(uid);
5572 mUidStats.put(uid, u);
5573
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005574 u.mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005575 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005576 u.mWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005577 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005578 u.mFullWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005579 if (in.readInt() != 0) {
5580 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
5581 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005582 u.mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005583 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07005584 u.mWifiScanTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005585 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07005586 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED;
5587 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
5588 if (in.readInt() != 0) {
5589 u.makeWifiBatchedScanBin(i, null);
5590 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in);
5591 }
5592 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005593 u.mWifiMulticastEnabled = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005594 if (in.readInt() != 0) {
5595 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
5596 }
5597 u.mAudioTurnedOn = false;
5598 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005599 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005600 }
5601 u.mVideoTurnedOn = false;
5602 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005603 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
5604 }
5605 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005606 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
5607 }
5608 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005609 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005610 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005611
Dianne Hackborn617f8772009-03-31 15:04:46 -07005612 if (in.readInt() != 0) {
5613 if (u.mUserActivityCounters == null) {
5614 u.initUserActivityLocked();
5615 }
5616 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
5617 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
5618 }
5619 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005620
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005621 if (in.readInt() != 0) {
5622 if (u.mNetworkActivityCounters == null) {
5623 u.initNetworkActivityLocked();
5624 }
5625 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
5626 u.mNetworkActivityCounters[i].readSummaryFromParcelLocked(in);
5627 }
5628 }
5629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005630 int NW = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005631 if (NW > 100) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005632 Slog.w(TAG, "File corrupt: too many wake locks " + NW);
5633 return;
5634 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005635 for (int iw = 0; iw < NW; iw++) {
5636 String wlName = in.readString();
5637 if (in.readInt() != 0) {
5638 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
5639 }
5640 if (in.readInt() != 0) {
5641 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
5642 }
5643 if (in.readInt() != 0) {
5644 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
5645 }
5646 }
5647
5648 int NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005649 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005650 Slog.w(TAG, "File corrupt: too many sensors " + NP);
5651 return;
5652 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005653 for (int is = 0; is < NP; is++) {
5654 int seNumber = in.readInt();
5655 if (in.readInt() != 0) {
5656 u.getSensorTimerLocked(seNumber, true)
5657 .readSummaryFromParcelLocked(in);
5658 }
5659 }
5660
5661 NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005662 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005663 Slog.w(TAG, "File corrupt: too many processes " + NP);
5664 return;
5665 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005666 for (int ip = 0; ip < NP; ip++) {
5667 String procName = in.readString();
5668 Uid.Proc p = u.getProcessStatsLocked(procName);
5669 p.mUserTime = p.mLoadedUserTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005670 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005671 p.mForegroundTime = p.mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005672 p.mStarts = p.mLoadedStarts = in.readInt();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005673 int NSB = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005674 if (NSB > 100) {
5675 Slog.w(TAG, "File corrupt: too many speed bins " + NSB);
5676 return;
5677 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005678 p.mSpeedBins = new SamplingCounter[NSB];
5679 for (int i=0; i<NSB; i++) {
5680 if (in.readInt() != 0) {
5681 p.mSpeedBins[i] = new SamplingCounter(mUnpluggables);
5682 p.mSpeedBins[i].readSummaryFromParcelLocked(in);
5683 }
5684 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005685 if (!p.readExcessivePowerFromParcelLocked(in)) {
5686 return;
5687 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005688 }
5689
5690 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07005691 if (NP > 10000) {
5692 Slog.w(TAG, "File corrupt: too many packages " + NP);
5693 return;
5694 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005695 for (int ip = 0; ip < NP; ip++) {
5696 String pkgName = in.readString();
5697 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
5698 p.mWakeups = p.mLoadedWakeups = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005699 final int NS = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005700 if (NS > 1000) {
5701 Slog.w(TAG, "File corrupt: too many services " + NS);
5702 return;
5703 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005704 for (int is = 0; is < NS; is++) {
5705 String servName = in.readString();
5706 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
5707 s.mStartTime = s.mLoadedStartTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005708 s.mStarts = s.mLoadedStarts = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005709 s.mLaunches = s.mLoadedLaunches = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005710 }
5711 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005712 }
5713 }
5714
5715 /**
5716 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
5717 * disk. This format does not allow a lossless round-trip.
5718 *
5719 * @param out the Parcel to be written to.
5720 */
5721 public void writeSummaryToParcel(Parcel out) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005722 // Need to update with current kernel wake lock counts.
5723 updateKernelWakelocksLocked();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005724 updateNetworkActivityLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07005725
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005726 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
5727 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
5728 final long NOW = getBatteryUptimeLocked(NOW_SYS);
5729 final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS);
5730
5731 out.writeInt(VERSION);
5732
Dianne Hackbornae384452011-06-28 12:33:48 -07005733 writeHistory(out, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005734
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005735 out.writeInt(mStartCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005736 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005737 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005738 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005739 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005740 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07005741 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborne4a59512010-12-07 11:08:07 -08005742 out.writeInt(getLowDischargeAmountSinceCharge());
5743 out.writeInt(getHighDischargeAmountSinceCharge());
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08005744 out.writeInt(getDischargeAmountScreenOnSinceCharge());
5745 out.writeInt(getDischargeAmountScreenOffSinceCharge());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005746
5747 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005748 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
5749 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
5750 }
5751 mInputEventCounter.writeSummaryFromParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005752 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Wink Saville52840902011-02-18 12:40:47 -08005753 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07005754 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
5755 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005756 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005757 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
5758 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
5759 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005760 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
5761 mNetworkActivityCounters[i].writeSummaryFromParcelLocked(out);
5762 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005763 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005764 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07005765 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005766
Evan Millarc64edde2009-04-18 12:26:32 -07005767 out.writeInt(mKernelWakelockStats.size());
5768 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
5769 Timer kwlt = ent.getValue();
5770 if (kwlt != null) {
5771 out.writeInt(1);
5772 out.writeString(ent.getKey());
5773 ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL);
5774 } else {
5775 out.writeInt(0);
5776 }
5777 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005778
Amith Yamasanie43530a2009-08-21 13:11:37 -07005779 out.writeInt(sNumSpeedSteps);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005780 final int NU = mUidStats.size();
5781 out.writeInt(NU);
5782 for (int iu = 0; iu < NU; iu++) {
5783 out.writeInt(mUidStats.keyAt(iu));
5784 Uid u = mUidStats.valueAt(iu);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005785
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005786 if (u.mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005787 out.writeInt(1);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005788 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005789 } else {
5790 out.writeInt(0);
5791 }
5792 if (u.mFullWifiLockTimer != null) {
5793 out.writeInt(1);
5794 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5795 } else {
5796 out.writeInt(0);
5797 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005798 if (u.mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005799 out.writeInt(1);
Nick Pelly6ccaa542012-06-15 15:22:47 -07005800 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005801 } else {
5802 out.writeInt(0);
5803 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07005804 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
5805 if (u.mWifiBatchedScanTimer[i] != null) {
5806 out.writeInt(1);
5807 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
5808 } else {
5809 out.writeInt(0);
5810 }
5811 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005812 if (u.mWifiMulticastTimer != null) {
5813 out.writeInt(1);
5814 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5815 } else {
5816 out.writeInt(0);
5817 }
5818 if (u.mAudioTurnedOnTimer != null) {
5819 out.writeInt(1);
5820 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5821 } else {
5822 out.writeInt(0);
5823 }
5824 if (u.mVideoTurnedOnTimer != null) {
5825 out.writeInt(1);
5826 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5827 } else {
5828 out.writeInt(0);
5829 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005830 if (u.mForegroundActivityTimer != null) {
5831 out.writeInt(1);
5832 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5833 } else {
5834 out.writeInt(0);
5835 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005836 if (u.mVibratorOnTimer != null) {
5837 out.writeInt(1);
5838 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5839 } else {
5840 out.writeInt(0);
5841 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005842
Dianne Hackborn617f8772009-03-31 15:04:46 -07005843 if (u.mUserActivityCounters == null) {
5844 out.writeInt(0);
5845 } else {
5846 out.writeInt(1);
5847 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
5848 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
5849 }
5850 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005851
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005852 if (u.mNetworkActivityCounters == null) {
5853 out.writeInt(0);
5854 } else {
5855 out.writeInt(1);
5856 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
5857 u.mNetworkActivityCounters[i].writeSummaryFromParcelLocked(out);
5858 }
5859 }
5860
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005861 int NW = u.mWakelockStats.size();
5862 out.writeInt(NW);
5863 if (NW > 0) {
5864 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent
5865 : u.mWakelockStats.entrySet()) {
5866 out.writeString(ent.getKey());
5867 Uid.Wakelock wl = ent.getValue();
5868 if (wl.mTimerFull != null) {
5869 out.writeInt(1);
5870 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL);
5871 } else {
5872 out.writeInt(0);
5873 }
5874 if (wl.mTimerPartial != null) {
5875 out.writeInt(1);
5876 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL);
5877 } else {
5878 out.writeInt(0);
5879 }
5880 if (wl.mTimerWindow != null) {
5881 out.writeInt(1);
5882 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL);
5883 } else {
5884 out.writeInt(0);
5885 }
5886 }
5887 }
5888
5889 int NSE = u.mSensorStats.size();
5890 out.writeInt(NSE);
5891 if (NSE > 0) {
5892 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent
5893 : u.mSensorStats.entrySet()) {
5894 out.writeInt(ent.getKey());
5895 Uid.Sensor se = ent.getValue();
5896 if (se.mTimer != null) {
5897 out.writeInt(1);
5898 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL);
5899 } else {
5900 out.writeInt(0);
5901 }
5902 }
5903 }
5904
5905 int NP = u.mProcessStats.size();
5906 out.writeInt(NP);
5907 if (NP > 0) {
5908 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent
5909 : u.mProcessStats.entrySet()) {
5910 out.writeString(ent.getKey());
5911 Uid.Proc ps = ent.getValue();
5912 out.writeLong(ps.mUserTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005913 out.writeLong(ps.mSystemTime);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005914 out.writeLong(ps.mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005915 out.writeInt(ps.mStarts);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005916 final int N = ps.mSpeedBins.length;
5917 out.writeInt(N);
5918 for (int i=0; i<N; i++) {
5919 if (ps.mSpeedBins[i] != null) {
5920 out.writeInt(1);
5921 ps.mSpeedBins[i].writeSummaryFromParcelLocked(out);
5922 } else {
5923 out.writeInt(0);
5924 }
5925 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07005926 ps.writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005927 }
5928 }
5929
5930 NP = u.mPackageStats.size();
5931 out.writeInt(NP);
5932 if (NP > 0) {
5933 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
5934 : u.mPackageStats.entrySet()) {
5935 out.writeString(ent.getKey());
5936 Uid.Pkg ps = ent.getValue();
5937 out.writeInt(ps.mWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005938 final int NS = ps.mServiceStats.size();
5939 out.writeInt(NS);
5940 if (NS > 0) {
5941 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
5942 : ps.mServiceStats.entrySet()) {
5943 out.writeString(sent.getKey());
5944 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
5945 long time = ss.getStartTimeToNowLocked(NOW);
5946 out.writeLong(time);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005947 out.writeInt(ss.mStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005948 out.writeInt(ss.mLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005949 }
5950 }
5951 }
5952 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005953 }
5954 }
5955
5956 public void readFromParcel(Parcel in) {
5957 readFromParcelLocked(in);
5958 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005959
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005960 void readFromParcelLocked(Parcel in) {
5961 int magic = in.readInt();
5962 if (magic != MAGIC) {
5963 throw new ParcelFormatException("Bad magic number");
5964 }
5965
Dianne Hackbornae384452011-06-28 12:33:48 -07005966 readHistory(in, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005967
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005968 mStartCount = in.readInt();
5969 mBatteryUptime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005970 mBatteryLastUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005971 mBatteryRealtime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07005972 mBatteryLastRealtime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005973 mScreenOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005974 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005975 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005976 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i,
5977 null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005978 }
5979 mInputEventCounter = new Counter(mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005980 mPhoneOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005981 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
Wink Saville52840902011-02-18 12:40:47 -08005982 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005983 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i,
5984 null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005985 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005986 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005987 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005988 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i,
5989 null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005990 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005991 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
5992 mNetworkActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in);
5993 }
The Android Open Source Project10592532009-03-18 17:39:46 -07005994 mWifiOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005995 mWifiOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005996 mGlobalWifiRunning = false;
5997 mGlobalWifiRunningTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07005998 mBluetoothOn = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005999 mBluetoothOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006000 mUptime = in.readLong();
6001 mUptimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006002 mLastUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006003 mRealtime = in.readLong();
6004 mRealtimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006005 mLastRealtime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006006 mOnBattery = in.readInt() != 0;
6007 mOnBatteryInternal = false; // we are no longer really running.
6008 mTrackBatteryPastUptime = in.readLong();
6009 mTrackBatteryUptimeStart = in.readLong();
6010 mTrackBatteryPastRealtime = in.readLong();
6011 mTrackBatteryRealtimeStart = in.readLong();
6012 mUnpluggedBatteryUptime = in.readLong();
6013 mUnpluggedBatteryRealtime = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006014 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07006015 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006016 mLowDischargeAmountSinceCharge = in.readInt();
6017 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006018 mDischargeAmountScreenOn = in.readInt();
6019 mDischargeAmountScreenOnSinceCharge = in.readInt();
6020 mDischargeAmountScreenOff = in.readInt();
6021 mDischargeAmountScreenOffSinceCharge = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006022 mLastWriteTime = in.readLong();
6023
Amith Yamasani3718aaa2009-06-09 06:32:35 -07006024 mRadioDataUptime = in.readLong();
6025 mRadioDataStart = -1;
6026
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07006027 mBluetoothPingCount = in.readInt();
6028 mBluetoothPingStart = -1;
6029
Evan Millarc64edde2009-04-18 12:26:32 -07006030 mKernelWakelockStats.clear();
6031 int NKW = in.readInt();
6032 for (int ikw = 0; ikw < NKW; ikw++) {
6033 if (in.readInt() != 0) {
6034 String wakelockName = in.readString();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07006035 in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel
Evan Millarc64edde2009-04-18 12:26:32 -07006036 SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in);
6037 mKernelWakelockStats.put(wakelockName, kwlt);
6038 }
6039 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006041 mPartialTimers.clear();
6042 mFullTimers.clear();
6043 mWindowTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006044 mWifiRunningTimers.clear();
6045 mFullWifiLockTimers.clear();
Nick Pelly6ccaa542012-06-15 15:22:47 -07006046 mWifiScanTimers.clear();
Robert Greenwalta029ea12013-09-25 16:38:12 -07006047 mWifiBatchedScanTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006048 mWifiMulticastTimers.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006049
Amith Yamasanie43530a2009-08-21 13:11:37 -07006050 sNumSpeedSteps = in.readInt();
6051
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006052 int numUids = in.readInt();
6053 mUidStats.clear();
6054 for (int i = 0; i < numUids; i++) {
6055 int uid = in.readInt();
6056 Uid u = new Uid(uid);
6057 u.readFromParcelLocked(mUnpluggables, in);
6058 mUidStats.append(uid, u);
6059 }
6060 }
6061
6062 public void writeToParcel(Parcel out, int flags) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006063 writeToParcelLocked(out, true, flags);
6064 }
6065
6066 public void writeToParcelWithoutUids(Parcel out, int flags) {
6067 writeToParcelLocked(out, false, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006068 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006069
6070 @SuppressWarnings("unused")
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006071 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006072 // Need to update with current kernel wake lock counts.
6073 updateKernelWakelocksLocked();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006074 updateNetworkActivityLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006076 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
6077 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
6078 final long batteryUptime = getBatteryUptimeLocked(uSecUptime);
6079 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006080
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006081 out.writeInt(MAGIC);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006082
Dianne Hackbornae384452011-06-28 12:33:48 -07006083 writeHistory(out, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006085 out.writeInt(mStartCount);
6086 out.writeLong(mBatteryUptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006087 out.writeLong(mBatteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006088 mScreenOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006089 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
6090 mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime);
6091 }
6092 mInputEventCounter.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006093 mPhoneOnTimer.writeToParcel(out, batteryRealtime);
Wink Saville52840902011-02-18 12:40:47 -08006094 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07006095 mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
6096 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07006097 mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07006098 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
6099 mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime);
6100 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006101 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
6102 mNetworkActivityCounters[i].writeToParcel(out);
6103 }
The Android Open Source Project10592532009-03-18 17:39:46 -07006104 mWifiOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006105 mGlobalWifiRunningTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07006106 mBluetoothOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006107 out.writeLong(mUptime);
6108 out.writeLong(mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006109 out.writeLong(mRealtime);
6110 out.writeLong(mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006111 out.writeInt(mOnBattery ? 1 : 0);
6112 out.writeLong(batteryUptime);
6113 out.writeLong(mTrackBatteryUptimeStart);
6114 out.writeLong(batteryRealtime);
6115 out.writeLong(mTrackBatteryRealtimeStart);
6116 out.writeLong(mUnpluggedBatteryUptime);
6117 out.writeLong(mUnpluggedBatteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006118 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07006119 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006120 out.writeInt(mLowDischargeAmountSinceCharge);
6121 out.writeInt(mHighDischargeAmountSinceCharge);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006122 out.writeInt(mDischargeAmountScreenOn);
6123 out.writeInt(mDischargeAmountScreenOnSinceCharge);
6124 out.writeInt(mDischargeAmountScreenOff);
6125 out.writeInt(mDischargeAmountScreenOffSinceCharge);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006126 out.writeLong(mLastWriteTime);
6127
Amith Yamasani3718aaa2009-06-09 06:32:35 -07006128 // Write radio uptime for data
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07006129 out.writeLong(getRadioDataUptime());
6130
6131 out.writeInt(getBluetoothPingCount());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07006132
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006133 if (inclUids) {
6134 out.writeInt(mKernelWakelockStats.size());
6135 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
6136 SamplingTimer kwlt = ent.getValue();
6137 if (kwlt != null) {
6138 out.writeInt(1);
6139 out.writeString(ent.getKey());
6140 Timer.writeTimerToParcel(out, kwlt, batteryRealtime);
6141 } else {
6142 out.writeInt(0);
6143 }
Evan Millarc64edde2009-04-18 12:26:32 -07006144 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006145 } else {
6146 out.writeInt(0);
Evan Millarc64edde2009-04-18 12:26:32 -07006147 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07006148
6149 out.writeInt(sNumSpeedSteps);
6150
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006151 if (inclUids) {
6152 int size = mUidStats.size();
6153 out.writeInt(size);
6154 for (int i = 0; i < size; i++) {
6155 out.writeInt(mUidStats.keyAt(i));
6156 Uid uid = mUidStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006157
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006158 uid.writeToParcelLocked(out, batteryRealtime);
6159 }
6160 } else {
6161 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006162 }
6163 }
6164
6165 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
6166 new Parcelable.Creator<BatteryStatsImpl>() {
6167 public BatteryStatsImpl createFromParcel(Parcel in) {
6168 return new BatteryStatsImpl(in);
6169 }
6170
6171 public BatteryStatsImpl[] newArray(int size) {
6172 return new BatteryStatsImpl[size];
6173 }
6174 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006175
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006176 public void prepareForDumpLocked() {
6177 // Need to retrieve current kernel wake lock stats before printing.
6178 updateKernelWakelocksLocked();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006179 updateNetworkActivityLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006180 }
6181
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07006182 public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly, int reqUid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006183 if (DEBUG) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006184 Printer pr = new PrintWriterPrinter(pw);
6185 pr.println("*** Screen timer:");
6186 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07006187 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006188 pr.println("*** Screen brightness #" + i + ":");
6189 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07006190 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006191 pr.println("*** Input event counter:");
6192 mInputEventCounter.logState(pr, " ");
6193 pr.println("*** Phone timer:");
6194 mPhoneOnTimer.logState(pr, " ");
Wink Saville52840902011-02-18 12:40:47 -08006195 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006196 pr.println("*** Signal strength #" + i + ":");
6197 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07006198 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07006199 pr.println("*** Signal scanning :");
6200 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07006201 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006202 pr.println("*** Data connection type #" + i + ":");
6203 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07006204 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006205 pr.println("*** Wifi timer:");
6206 mWifiOnTimer.logState(pr, " ");
6207 pr.println("*** WifiRunning timer:");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006208 mGlobalWifiRunningTimer.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006209 pr.println("*** Bluetooth timer:");
6210 mBluetoothOnTimer.logState(pr, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006211 }
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07006212 super.dumpLocked(pw, isUnpluggedOnly, reqUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006213 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006214}