blob: 0a1c8ffb17f4fbc2b1326668a93ae902d9d60f99 [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
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070019import com.android.internal.util.JournaledFile;
20
Amith Yamasani3f7e35c2009-07-13 16:02:45 -070021import android.bluetooth.BluetoothHeadset;
Ken Shirriff1719a392009-12-07 15:57:35 -080022import android.net.TrafficStats;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070023import android.os.BatteryManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.os.BatteryStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import android.os.Parcel;
26import android.os.ParcelFormatException;
27import android.os.Parcelable;
Evan Millarc64edde2009-04-18 12:26:32 -070028import android.os.Process;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.os.SystemClock;
Amith Yamasanif37447b2009-10-08 18:28:01 -070030import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070031import android.telephony.SignalStrength;
Dianne Hackborn627bba72009-03-24 22:32:56 -070032import android.telephony.TelephonyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import android.util.Log;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070034import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import android.util.Printer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070036import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.util.SparseArray;
38
Amith Yamasani3718aaa2009-06-09 06:32:35 -070039import java.io.BufferedReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import java.io.File;
41import java.io.FileInputStream;
42import java.io.FileOutputStream;
Amith Yamasani3718aaa2009-06-09 06:32:35 -070043import java.io.FileReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070045import java.io.PrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import java.util.ArrayList;
47import java.util.HashMap;
Evan Millarc64edde2009-04-18 12:26:32 -070048import java.util.Iterator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049import java.util.Map;
Christopher Tate4cee7252010-03-19 14:50:40 -070050import java.util.concurrent.atomic.AtomicInteger;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051
52/**
53 * All information we are collecting about things that can happen that impact
54 * battery life. All times are represented in microseconds except where indicated
55 * otherwise.
56 */
57public final class BatteryStatsImpl extends BatteryStats {
58 private static final String TAG = "BatteryStatsImpl";
59 private static final boolean DEBUG = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070060 private static final boolean DEBUG_HISTORY = false;
61
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
63 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
64
65 // Current on-disk Parcel version
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070066 private static final int VERSION = 50;
Amith Yamasanie43530a2009-08-21 13:11:37 -070067
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070068 // Maximum number of items we will record in the history.
69 private static final int MAX_HISTORY_ITEMS = 1000;
70
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -080071 // The maximum number of names wakelocks we will keep track of
72 // per uid; once the limit is reached, we batch the remaining wakelocks
73 // in to one common name.
74 private static final int MAX_WAKELOCKS_PER_UID = 20;
75
76 private static final String BATCHED_WAKELOCK_NAME = "*overflow*";
77
Amith Yamasanie43530a2009-08-21 13:11:37 -070078 private static int sNumSpeedSteps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070080 private final JournaledFile mFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081
82 /**
83 * The statistics we have collected organized by uids.
84 */
85 final SparseArray<BatteryStatsImpl.Uid> mUidStats =
86 new SparseArray<BatteryStatsImpl.Uid>();
87
88 // A set of pools of currently active timers. When a timer is queried, we will divide the
89 // elapsed time by the number of active timers to arrive at that timer's share of the time.
90 // In order to do this, we must refresh each timer whenever the number of active timers
91 // changes.
Evan Millarc64edde2009-04-18 12:26:32 -070092 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>();
93 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>();
94 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>();
95 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers
96 = new SparseArray<ArrayList<StopwatchTimer>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097
98 // These are the objects that will want to do something when the device
99 // is unplugged from power.
100 final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>();
101
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700102 boolean mShuttingDown;
103
104 long mHistoryBaseTime;
105 boolean mHaveBatteryLevel = false;
106 boolean mRecordingHistory = true;
107 int mNumHistoryItems;
108 HistoryItem mHistory;
109 HistoryItem mHistoryEnd;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700110 HistoryItem mHistoryLastEnd;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700111 HistoryItem mHistoryCache;
112 final HistoryItem mHistoryCur = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114 int mStartCount;
115
116 long mBatteryUptime;
117 long mBatteryLastUptime;
118 long mBatteryRealtime;
119 long mBatteryLastRealtime;
120
121 long mUptime;
122 long mUptimeStart;
123 long mLastUptime;
124 long mRealtime;
125 long mRealtimeStart;
126 long mLastRealtime;
127
128 boolean mScreenOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700129 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700130
Dianne Hackborn617f8772009-03-31 15:04:46 -0700131 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700132 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Dianne Hackborn617f8772009-03-31 15:04:46 -0700133
134 Counter mInputEventCounter;
135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700137 StopwatchTimer mPhoneOnTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700139 boolean mAudioOn;
140 StopwatchTimer mAudioOnTimer;
141
142 boolean mVideoOn;
143 StopwatchTimer mVideoOnTimer;
144
Dianne Hackborn627bba72009-03-24 22:32:56 -0700145 int mPhoneSignalStrengthBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700146 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
147 new StopwatchTimer[NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700148
149 StopwatchTimer mPhoneSignalScanningTimer;
150
Dianne Hackborn627bba72009-03-24 22:32:56 -0700151 int mPhoneDataConnectionType = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700152 final StopwatchTimer[] mPhoneDataConnectionsTimer =
153 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Dianne Hackborn627bba72009-03-24 22:32:56 -0700154
The Android Open Source Project10592532009-03-18 17:39:46 -0700155 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700156 StopwatchTimer mWifiOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700157 int mWifiOnUid = -1;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700158
159 boolean mWifiRunning;
Evan Millarc64edde2009-04-18 12:26:32 -0700160 StopwatchTimer mWifiRunningTimer;
The Android Open Source Project10592532009-03-18 17:39:46 -0700161
162 boolean mBluetoothOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700163 StopwatchTimer mBluetoothOnTimer;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700164
165 /** Bluetooth headset object */
166 BluetoothHeadset mBtHeadset;
167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 /**
169 * These provide time bases that discount the time the device is plugged
170 * in to power.
171 */
172 boolean mOnBattery;
173 boolean mOnBatteryInternal;
174 long mTrackBatteryPastUptime;
175 long mTrackBatteryUptimeStart;
176 long mTrackBatteryPastRealtime;
177 long mTrackBatteryRealtimeStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700178
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179 long mUnpluggedBatteryUptime;
180 long mUnpluggedBatteryRealtime;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700181
The Android Open Source Project10592532009-03-18 17:39:46 -0700182 /*
183 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
184 */
Evan Millar633a1742009-04-02 16:36:33 -0700185 int mDischargeStartLevel;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700186 int mDischargeUnplugLevel;
Evan Millar633a1742009-04-02 16:36:33 -0700187 int mDischargeCurrentLevel;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700188 int mLowDischargeAmountSinceCharge;
189 int mHighDischargeAmountSinceCharge;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700190
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800191 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700192
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700193 // Mobile data transferred while on battery
194 private long[] mMobileDataTx = new long[4];
195 private long[] mMobileDataRx = new long[4];
196 private long[] mTotalDataTx = new long[4];
197 private long[] mTotalDataRx = new long[4];
198
199 private long mRadioDataUptime;
200 private long mRadioDataStart;
201
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700202 private int mBluetoothPingCount;
203 private int mBluetoothPingStart = -1;
204
Amith Yamasanif37447b2009-10-08 18:28:01 -0700205 private int mPhoneServiceState = -1;
206
Evan Millarc64edde2009-04-18 12:26:32 -0700207 /*
208 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
209 */
210 private final HashMap<String, SamplingTimer> mKernelWakelockStats =
211 new HashMap<String, SamplingTimer>();
212
213 public Map<String, ? extends SamplingTimer> getKernelWakelockStats() {
214 return mKernelWakelockStats;
215 }
216
217 private static int sKernelWakelockUpdateVersion = 0;
218
219 private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
220 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name
221 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count
222 Process.PROC_TAB_TERM,
223 Process.PROC_TAB_TERM,
224 Process.PROC_TAB_TERM,
225 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime
226 };
227
228 private final String[] mProcWakelocksName = new String[3];
229 private final long[] mProcWakelocksData = new long[3];
230
231 /*
232 * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added
233 * to mKernelWakelockStats.
234 */
235 private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
236 new HashMap<String, KernelWakelockStats>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700238 private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>();
239
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240 // For debugging
241 public BatteryStatsImpl() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700242 mFile = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243 }
244
245 public static interface Unpluggable {
246 void unplug(long batteryUptime, long batteryRealtime);
247 void plug(long batteryUptime, long batteryRealtime);
248 }
249
250 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700251 * State for keeping track of counting information.
252 */
Amith Yamasanie43530a2009-08-21 13:11:37 -0700253 public static class Counter extends BatteryStats.Counter implements Unpluggable {
Christopher Tate4cee7252010-03-19 14:50:40 -0700254 final AtomicInteger mCount = new AtomicInteger();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700255 final ArrayList<Unpluggable> mUnpluggables;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700256 int mLoadedCount;
257 int mLastCount;
258 int mUnpluggedCount;
259 int mPluggedCount;
260
261 Counter(ArrayList<Unpluggable> unpluggables, Parcel in) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700262 mUnpluggables = unpluggables;
Christopher Tate4cee7252010-03-19 14:50:40 -0700263 mPluggedCount = in.readInt();
264 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700265 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700266 mLastCount = 0;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700267 mUnpluggedCount = in.readInt();
268 unpluggables.add(this);
269 }
270
271 Counter(ArrayList<Unpluggable> unpluggables) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700272 mUnpluggables = unpluggables;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700273 unpluggables.add(this);
274 }
275
276 public void writeToParcel(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700277 out.writeInt(mCount.get());
Dianne Hackborn617f8772009-03-31 15:04:46 -0700278 out.writeInt(mLoadedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700279 out.writeInt(mUnpluggedCount);
280 }
281
282 public void unplug(long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700283 mUnpluggedCount = mPluggedCount;
284 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700285 }
286
287 public void plug(long batteryUptime, long batteryRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700288 mPluggedCount = mCount.get();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700289 }
290
291 /**
292 * Writes a possibly null Counter to a Parcel.
293 *
294 * @param out the Parcel to be written to.
295 * @param counter a Counter, or null.
296 */
297 public static void writeCounterToParcel(Parcel out, Counter counter) {
298 if (counter == null) {
299 out.writeInt(0); // indicates null
300 return;
301 }
302 out.writeInt(1); // indicates non-null
303
304 counter.writeToParcel(out);
305 }
306
307 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700308 public int getCountLocked(int which) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700309 int val;
310 if (which == STATS_LAST) {
311 val = mLastCount;
312 } else {
Christopher Tate4cee7252010-03-19 14:50:40 -0700313 val = mCount.get();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700314 if (which == STATS_SINCE_UNPLUGGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700315 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700316 } else if (which != STATS_SINCE_CHARGED) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700317 val -= mLoadedCount;
318 }
319 }
320
321 return val;
322 }
323
324 public void logState(Printer pw, String prefix) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700325 pw.println(prefix + "mCount=" + mCount.get()
Dianne Hackborn617f8772009-03-31 15:04:46 -0700326 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
327 + " mUnpluggedCount=" + mUnpluggedCount
328 + " mPluggedCount=" + mPluggedCount);
329 }
330
Christopher Tate4cee7252010-03-19 14:50:40 -0700331 void stepAtomic() {
332 mCount.incrementAndGet();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700333 }
334
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700335 /**
336 * Clear state of this counter.
337 */
338 void reset(boolean detachIfReset) {
339 mCount.set(0);
340 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
341 if (detachIfReset) {
342 detach();
343 }
344 }
345
346 void detach() {
347 mUnpluggables.remove(this);
348 }
349
Dianne Hackborn617f8772009-03-31 15:04:46 -0700350 void writeSummaryFromParcelLocked(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700351 int count = mCount.get();
352 out.writeInt(count);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700353 }
354
355 void readSummaryFromParcelLocked(Parcel in) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700356 mLoadedCount = in.readInt();
357 mCount.set(mLoadedCount);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700358 mLastCount = 0;
Christopher Tate4cee7252010-03-19 14:50:40 -0700359 mUnpluggedCount = mPluggedCount = mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700360 }
361 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700362
363 public static class SamplingCounter extends Counter {
364
365 SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
366 super(unpluggables, in);
367 }
368
369 SamplingCounter(ArrayList<Unpluggable> unpluggables) {
370 super(unpluggables);
371 }
372
Christopher Tate4cee7252010-03-19 14:50:40 -0700373 public void addCountAtomic(long count) {
374 mCount.addAndGet((int)count);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700375 }
376 }
377
Dianne Hackborn617f8772009-03-31 15:04:46 -0700378 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800379 * State for keeping track of timing information.
380 */
Evan Millarc64edde2009-04-18 12:26:32 -0700381 public static abstract class Timer extends BatteryStats.Timer implements Unpluggable {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 final int mType;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700383 final ArrayList<Unpluggable> mUnpluggables;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384
385 int mCount;
386 int mLoadedCount;
387 int mLastCount;
388 int mUnpluggedCount;
389
390 // Times are in microseconds for better accuracy when dividing by the
391 // lock count, and are in "battery realtime" units.
392
393 /**
394 * The total time we have accumulated since the start of the original
395 * boot, to the last time something interesting happened in the
396 * current run.
397 */
398 long mTotalTime;
399
400 /**
401 * The total time we loaded for the previous runs. Subtract this from
402 * mTotalTime to find the time for the current run of the system.
403 */
404 long mLoadedTime;
405
406 /**
407 * The run time of the last run of the system, as loaded from the
408 * saved data.
409 */
410 long mLastTime;
411
412 /**
413 * The value of mTotalTime when unplug() was last called. Subtract
414 * this from mTotalTime to find the time since the last unplug from
415 * power.
416 */
417 long mUnpluggedTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700419 /**
420 * Constructs from a parcel.
421 * @param type
422 * @param unpluggables
423 * @param powerType
424 * @param in
425 */
Evan Millarc64edde2009-04-18 12:26:32 -0700426 Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 mType = type;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700428 mUnpluggables = unpluggables;
Evan Millarc64edde2009-04-18 12:26:32 -0700429
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800430 mCount = in.readInt();
431 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700432 mLastCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800433 mUnpluggedCount = in.readInt();
434 mTotalTime = in.readLong();
435 mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700436 mLastTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437 mUnpluggedTime = in.readLong();
438 unpluggables.add(this);
439 }
440
Evan Millarc64edde2009-04-18 12:26:32 -0700441 Timer(int type, ArrayList<Unpluggable> unpluggables) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 mType = type;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700443 mUnpluggables = unpluggables;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800444 unpluggables.add(this);
445 }
Evan Millarc64edde2009-04-18 12:26:32 -0700446
447 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
448
449 protected abstract int computeCurrentCountLocked();
450
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700451 /**
452 * Clear state of this timer. Returns true if the timer is inactive
453 * so can be completely dropped.
454 */
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700455 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700456 mTotalTime = mLoadedTime = mLastTime = 0;
457 mCount = mLoadedCount = mLastCount = 0;
458 if (detachIfReset) {
459 detach();
460 }
461 return true;
462 }
463
464 void detach() {
465 mUnpluggables.remove(this);
466 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467
468 public void writeToParcel(Parcel out, long batteryRealtime) {
469 out.writeInt(mCount);
470 out.writeInt(mLoadedCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 out.writeInt(mUnpluggedCount);
472 out.writeLong(computeRunTimeLocked(batteryRealtime));
473 out.writeLong(mLoadedTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 out.writeLong(mUnpluggedTime);
475 }
476
477 public void unplug(long batteryUptime, long batteryRealtime) {
478 if (DEBUG && mType < 0) {
479 Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime
480 + " old mUnpluggedTime=" + mUnpluggedTime
481 + " old mUnpluggedCount=" + mUnpluggedCount);
482 }
483 mUnpluggedTime = computeRunTimeLocked(batteryRealtime);
484 mUnpluggedCount = mCount;
485 if (DEBUG && mType < 0) {
486 Log.v(TAG, "unplug #" + mType
487 + ": new mUnpluggedTime=" + mUnpluggedTime
488 + " new mUnpluggedCount=" + mUnpluggedCount);
489 }
490 }
491
492 public void plug(long batteryUptime, long batteryRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -0700493 if (DEBUG && mType < 0) {
494 Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime
495 + " old mTotalTime=" + mTotalTime);
496 }
497 mTotalTime = computeRunTimeLocked(batteryRealtime);
498 mCount = computeCurrentCountLocked();
499 if (DEBUG && mType < 0) {
500 Log.v(TAG, "plug #" + mType
501 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502 }
503 }
504
505 /**
506 * Writes a possibly null Timer to a Parcel.
507 *
508 * @param out the Parcel to be written to.
509 * @param timer a Timer, or null.
510 */
511 public static void writeTimerToParcel(Parcel out, Timer timer,
512 long batteryRealtime) {
513 if (timer == null) {
514 out.writeInt(0); // indicates null
515 return;
516 }
517 out.writeInt(1); // indicates non-null
518
519 timer.writeToParcel(out, batteryRealtime);
520 }
521
522 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700523 public long getTotalTimeLocked(long batteryRealtime, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524 long val;
525 if (which == STATS_LAST) {
526 val = mLastTime;
527 } else {
528 val = computeRunTimeLocked(batteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700529 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530 val -= mUnpluggedTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700531 } else if (which != STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800532 val -= mLoadedTime;
533 }
534 }
535
536 return val;
537 }
538
539 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700540 public int getCountLocked(int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800541 int val;
542 if (which == STATS_LAST) {
543 val = mLastCount;
544 } else {
Evan Millarc64edde2009-04-18 12:26:32 -0700545 val = computeCurrentCountLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700546 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800547 val -= mUnpluggedCount;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700548 } else if (which != STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 val -= mLoadedCount;
550 }
551 }
552
553 return val;
554 }
555
Dianne Hackborn627bba72009-03-24 22:32:56 -0700556 public void logState(Printer pw, String prefix) {
Evan Millarc64edde2009-04-18 12:26:32 -0700557 pw.println(prefix + " mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800558 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
559 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700560 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800561 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700562 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800563 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -0700564 }
565
566
567 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
568 long runTime = computeRunTimeLocked(batteryRealtime);
569 // Divide by 1000 for backwards compatibility
570 out.writeLong((runTime + 500) / 1000);
Evan Millarc64edde2009-04-18 12:26:32 -0700571 out.writeInt(mCount);
Evan Millarc64edde2009-04-18 12:26:32 -0700572 }
573
574 void readSummaryFromParcelLocked(Parcel in) {
575 // Multiply by 1000 for backwards compatibility
576 mTotalTime = mLoadedTime = in.readLong() * 1000;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700577 mLastTime = 0;
Evan Millarc64edde2009-04-18 12:26:32 -0700578 mUnpluggedTime = mTotalTime;
579 mCount = mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700580 mLastCount = 0;
Evan Millarc64edde2009-04-18 12:26:32 -0700581 mUnpluggedCount = mCount;
582 }
583 }
584
585 public static final class SamplingTimer extends Timer {
586
587 /**
588 * The most recent reported count from /proc/wakelocks.
589 */
590 int mCurrentReportedCount;
591
592 /**
593 * The reported count from /proc/wakelocks when unplug() was last
594 * called.
595 */
596 int mUnpluggedReportedCount;
597
598 /**
599 * The most recent reported total_time from /proc/wakelocks.
600 */
601 long mCurrentReportedTotalTime;
602
603
604 /**
605 * The reported total_time from /proc/wakelocks when unplug() was last
606 * called.
607 */
608 long mUnpluggedReportedTotalTime;
609
610 /**
611 * Whether we are currently in a discharge cycle.
612 */
613 boolean mInDischarge;
614
615 /**
616 * Whether we are currently recording reported values.
617 */
618 boolean mTrackingReportedValues;
619
620 /*
621 * A sequnce counter, incremented once for each update of the stats.
622 */
623 int mUpdateVersion;
624
625 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) {
626 super(0, unpluggables, in);
627 mCurrentReportedCount = in.readInt();
628 mUnpluggedReportedCount = in.readInt();
629 mCurrentReportedTotalTime = in.readLong();
630 mUnpluggedReportedTotalTime = in.readLong();
631 mTrackingReportedValues = in.readInt() == 1;
632 mInDischarge = inDischarge;
633 }
634
635 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge,
636 boolean trackReportedValues) {
637 super(0, unpluggables);
638 mTrackingReportedValues = trackReportedValues;
639 mInDischarge = inDischarge;
640 }
641
642 public void setStale() {
643 mTrackingReportedValues = false;
644 mUnpluggedReportedTotalTime = 0;
645 mUnpluggedReportedCount = 0;
646 }
647
648 public void setUpdateVersion(int version) {
649 mUpdateVersion = version;
650 }
651
652 public int getUpdateVersion() {
653 return mUpdateVersion;
654 }
655
656 public void updateCurrentReportedCount(int count) {
657 if (mInDischarge && mUnpluggedReportedCount == 0) {
658 // Updating the reported value for the first time.
659 mUnpluggedReportedCount = count;
660 // If we are receiving an update update mTrackingReportedValues;
661 mTrackingReportedValues = true;
662 }
663 mCurrentReportedCount = count;
664 }
665
666 public void updateCurrentReportedTotalTime(long totalTime) {
667 if (mInDischarge && mUnpluggedReportedTotalTime == 0) {
668 // Updating the reported value for the first time.
669 mUnpluggedReportedTotalTime = totalTime;
670 // If we are receiving an update update mTrackingReportedValues;
671 mTrackingReportedValues = true;
672 }
673 mCurrentReportedTotalTime = totalTime;
674 }
675
676 public void unplug(long batteryUptime, long batteryRealtime) {
677 super.unplug(batteryUptime, batteryRealtime);
678 if (mTrackingReportedValues) {
679 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
680 mUnpluggedReportedCount = mCurrentReportedCount;
681 }
682 mInDischarge = true;
683 }
684
685 public void plug(long batteryUptime, long batteryRealtime) {
686 super.plug(batteryUptime, batteryRealtime);
687 mInDischarge = false;
688 }
689
690 public void logState(Printer pw, String prefix) {
691 super.logState(pw, prefix);
692 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
693 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
694 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
695 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
696 }
697
698 protected long computeRunTimeLocked(long curBatteryRealtime) {
699 return mTotalTime + (mInDischarge && mTrackingReportedValues
700 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
701 }
702
703 protected int computeCurrentCountLocked() {
704 return mCount + (mInDischarge && mTrackingReportedValues
705 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
706 }
707
708 public void writeToParcel(Parcel out, long batteryRealtime) {
709 super.writeToParcel(out, batteryRealtime);
710 out.writeInt(mCurrentReportedCount);
711 out.writeInt(mUnpluggedReportedCount);
712 out.writeLong(mCurrentReportedTotalTime);
713 out.writeLong(mUnpluggedReportedTotalTime);
714 out.writeInt(mTrackingReportedValues ? 1 : 0);
715 }
716
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700717 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
718 super.reset(stats, detachIfReset);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700719 setStale();
720 return true;
721 }
722
Evan Millarc64edde2009-04-18 12:26:32 -0700723 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
724 super.writeSummaryFromParcelLocked(out, batteryRealtime);
725 out.writeLong(mCurrentReportedTotalTime);
726 out.writeInt(mCurrentReportedCount);
727 out.writeInt(mTrackingReportedValues ? 1 : 0);
728 }
729
730 void readSummaryFromParcelLocked(Parcel in) {
731 super.readSummaryFromParcelLocked(in);
732 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
733 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
734 mTrackingReportedValues = in.readInt() == 1;
735 }
736 }
737
738 /**
739 * State for keeping track of timing information.
740 */
741 public static final class StopwatchTimer extends Timer {
742 final ArrayList<StopwatchTimer> mTimerPool;
743 int mNesting;
744
Evan Millarc64edde2009-04-18 12:26:32 -0700745 /**
746 * The last time at which we updated the timer. If mNesting is > 0,
747 * subtract this from the current battery time to find the amount of
748 * time we have been running since we last computed an update.
749 */
750 long mUpdateTime;
751
752 /**
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700753 * The total time at which the timer was acquired, to determine if it
Evan Millarc64edde2009-04-18 12:26:32 -0700754 * was actually held for an interesting duration.
755 */
756 long mAcquireTime;
Evan Millarc64edde2009-04-18 12:26:32 -0700757
Amith Yamasanif37447b2009-10-08 18:28:01 -0700758 long mTimeout;
759
Evan Millarc64edde2009-04-18 12:26:32 -0700760 StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool,
761 ArrayList<Unpluggable> unpluggables, Parcel in) {
762 super(type, unpluggables, in);
763 mTimerPool = timerPool;
764 mUpdateTime = in.readLong();
765 }
766
767 StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool,
768 ArrayList<Unpluggable> unpluggables) {
769 super(type, unpluggables);
770 mTimerPool = timerPool;
771 }
772
Amith Yamasanif37447b2009-10-08 18:28:01 -0700773 void setTimeout(long timeout) {
774 mTimeout = timeout;
775 }
776
Evan Millarc64edde2009-04-18 12:26:32 -0700777 public void writeToParcel(Parcel out, long batteryRealtime) {
778 super.writeToParcel(out, batteryRealtime);
779 out.writeLong(mUpdateTime);
780 }
781
782 public void plug(long batteryUptime, long batteryRealtime) {
783 if (mNesting > 0) {
784 if (DEBUG && mType < 0) {
785 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
786 }
787 super.plug(batteryUptime, batteryRealtime);
788 mUpdateTime = batteryRealtime;
789 if (DEBUG && mType < 0) {
790 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
791 }
792 }
793 }
794
795 public void logState(Printer pw, String prefix) {
796 super.logState(pw, prefix);
797 pw.println(prefix + "mNesting=" + mNesting + "mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800798 + " mAcquireTime=" + mAcquireTime);
799 }
800
801 void startRunningLocked(BatteryStatsImpl stats) {
802 if (mNesting++ == 0) {
803 mUpdateTime = stats.getBatteryRealtimeLocked(
804 SystemClock.elapsedRealtime() * 1000);
805 if (mTimerPool != null) {
806 // Accumulate time to all currently active timers before adding
807 // this new one to the pool.
808 refreshTimersLocked(stats, mTimerPool);
809 // Add this timer to the active pool
810 mTimerPool.add(this);
811 }
812 // Increment the count
813 mCount++;
814 mAcquireTime = mTotalTime;
815 if (DEBUG && mType < 0) {
816 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
817 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
818 + " mAcquireTime=" + mAcquireTime);
819 }
820 }
821 }
822
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700823 boolean isRunningLocked() {
824 return mNesting > 0;
825 }
826
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800827 void stopRunningLocked(BatteryStatsImpl stats) {
828 // Ignore attempt to stop a timer that isn't running
829 if (mNesting == 0) {
830 return;
831 }
832 if (--mNesting == 0) {
833 if (mTimerPool != null) {
834 // Accumulate time to all active counters, scaled by the total
835 // active in the pool, before taking this one out of the pool.
836 refreshTimersLocked(stats, mTimerPool);
837 // Remove this timer from the active pool
838 mTimerPool.remove(this);
839 } else {
840 final long realtime = SystemClock.elapsedRealtime() * 1000;
841 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
842 mNesting = 1;
843 mTotalTime = computeRunTimeLocked(batteryRealtime);
844 mNesting = 0;
845 }
846
847 if (DEBUG && mType < 0) {
848 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
849 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
850 + " mAcquireTime=" + mAcquireTime);
851 }
852
853 if (mTotalTime == mAcquireTime) {
854 // If there was no change in the time, then discard this
855 // count. A somewhat cheezy strategy, but hey.
856 mCount--;
857 }
858 }
859 }
860
861 // Update the total time for all other running Timers with the same type as this Timer
862 // due to a change in timer count
863 private static void refreshTimersLocked(final BatteryStatsImpl stats,
Evan Millarc64edde2009-04-18 12:26:32 -0700864 final ArrayList<StopwatchTimer> pool) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800865 final long realtime = SystemClock.elapsedRealtime() * 1000;
866 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
867 final int N = pool.size();
868 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -0700869 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800870 long heldTime = batteryRealtime - t.mUpdateTime;
871 if (heldTime > 0) {
872 t.mTotalTime += heldTime / N;
873 }
874 t.mUpdateTime = batteryRealtime;
875 }
876 }
877
Evan Millarc64edde2009-04-18 12:26:32 -0700878 @Override
879 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -0700880 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
881 curBatteryRealtime = mUpdateTime + mTimeout;
882 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800883 return mTotalTime + (mNesting > 0
884 ? (curBatteryRealtime - mUpdateTime)
885 / (mTimerPool != null ? mTimerPool.size() : 1)
886 : 0);
887 }
888
Evan Millarc64edde2009-04-18 12:26:32 -0700889 @Override
890 protected int computeCurrentCountLocked() {
891 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800892 }
893
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700894 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700895 boolean canDetach = mNesting <= 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700896 super.reset(stats, canDetach && detachIfReset);
897 if (mNesting > 0) {
898 mUpdateTime = stats.getBatteryRealtimeLocked(
899 SystemClock.elapsedRealtime() * 1000);
900 }
901 mAcquireTime = mTotalTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700902 return canDetach;
903 }
904
905 void detach() {
906 super.detach();
907 if (mTimerPool != null) {
908 mTimerPool.remove(this);
909 }
910 }
911
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800912 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -0700913 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800914 mNesting = 0;
915 }
916 }
917
Evan Millarc64edde2009-04-18 12:26:32 -0700918 private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
919
Johannes Carlsson3372f2e2010-06-30 08:45:55 +0200920 byte[] buffer = new byte[8192];
Evan Millarc64edde2009-04-18 12:26:32 -0700921 int len;
922
923 try {
924 FileInputStream is = new FileInputStream("/proc/wakelocks");
925 len = is.read(buffer);
926 is.close();
927
928 if (len > 0) {
929 int i;
930 for (i=0; i<len; i++) {
931 if (buffer[i] == '\0') {
932 len = i;
933 break;
934 }
935 }
936 }
937 } catch (java.io.FileNotFoundException e) {
938 return null;
939 } catch (java.io.IOException e) {
940 return null;
941 }
942
943 return parseProcWakelocks(buffer, len);
944 }
945
946 private final Map<String, KernelWakelockStats> parseProcWakelocks(
947 byte[] wlBuffer, int len) {
948 String name;
949 int count;
950 long totalTime;
951 int startIndex, endIndex;
952 int numUpdatedWlNames = 0;
953
954 // Advance past the first line.
955 int i;
956 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++);
957 startIndex = endIndex = i + 1;
958
959 synchronized(this) {
960 Map<String, KernelWakelockStats> m = mProcWakelockFileStats;
961
962 sKernelWakelockUpdateVersion++;
963 while (endIndex < len) {
964 for (endIndex=startIndex;
965 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
966 endIndex++);
Johannes Carlsson3372f2e2010-06-30 08:45:55 +0200967 endIndex++; // endIndex is an exclusive upper bound.
968 // Don't go over the end of the buffer, Process.parseProcLine might
969 // write to wlBuffer[endIndex]
970 if (endIndex >= (len - 1) ) {
971 return m;
Amith Yamasanie5795612010-04-05 12:43:44 -0700972 }
Evan Millarc64edde2009-04-18 12:26:32 -0700973
974 String[] nameStringArray = mProcWakelocksName;
975 long[] wlData = mProcWakelocksData;
Amith Yamasani2098ead2010-04-02 13:46:49 -0700976 // Stomp out any bad characters since this is from a circular buffer
977 // A corruption is seen sometimes that results in the vm crashing
978 // This should prevent crashes and the line will probably fail to parse
979 for (int j = startIndex; j < endIndex; j++) {
980 if ((wlBuffer[j] & 0x80) != 0) wlBuffer[j] = (byte) '?';
981 }
Amith Yamasani53b707b2009-09-30 11:05:30 -0700982 boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex,
983 PROC_WAKELOCKS_FORMAT, nameStringArray, wlData, null);
Amith Yamasani2098ead2010-04-02 13:46:49 -0700984
Evan Millarc64edde2009-04-18 12:26:32 -0700985 name = nameStringArray[0];
986 count = (int) wlData[1];
987 // convert nanoseconds to microseconds with rounding.
988 totalTime = (wlData[2] + 500) / 1000;
989
Amith Yamasani53b707b2009-09-30 11:05:30 -0700990 if (parsed && name.length() > 0) {
Evan Millarc64edde2009-04-18 12:26:32 -0700991 if (!m.containsKey(name)) {
992 m.put(name, new KernelWakelockStats(count, totalTime,
993 sKernelWakelockUpdateVersion));
994 numUpdatedWlNames++;
995 } else {
996 KernelWakelockStats kwlStats = m.get(name);
997 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) {
998 kwlStats.mCount += count;
999 kwlStats.mTotalTime += totalTime;
1000 } else {
1001 kwlStats.mCount = count;
1002 kwlStats.mTotalTime = totalTime;
1003 kwlStats.mVersion = sKernelWakelockUpdateVersion;
1004 numUpdatedWlNames++;
1005 }
1006 }
Amith Yamasani53b707b2009-09-30 11:05:30 -07001007 }
Evan Millarc64edde2009-04-18 12:26:32 -07001008 startIndex = endIndex;
1009 }
1010
1011 if (m.size() != numUpdatedWlNames) {
1012 // Don't report old data.
1013 Iterator<KernelWakelockStats> itr = m.values().iterator();
1014 while (itr.hasNext()) {
1015 if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
1016 itr.remove();
1017 }
1018 }
1019 }
1020 return m;
1021 }
1022 }
1023
1024 private class KernelWakelockStats {
1025 public int mCount;
1026 public long mTotalTime;
1027 public int mVersion;
1028
1029 KernelWakelockStats(int count, long totalTime, int version) {
1030 mCount = count;
1031 mTotalTime = totalTime;
1032 mVersion = version;
1033 }
1034 }
1035
1036 /*
1037 * Get the KernelWakelockTimer associated with name, and create a new one if one
1038 * doesn't already exist.
1039 */
1040 public SamplingTimer getKernelWakelockTimerLocked(String name) {
1041 SamplingTimer kwlt = mKernelWakelockStats.get(name);
1042 if (kwlt == null) {
1043 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
1044 true /* track reported values */);
1045 mKernelWakelockStats.put(name, kwlt);
1046 }
1047 return kwlt;
1048 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001049
1050 private void doDataPlug(long[] dataTransfer, long currentBytes) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001051 dataTransfer[STATS_LAST] = dataTransfer[STATS_SINCE_UNPLUGGED];
1052 dataTransfer[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001053 }
1054
1055 private void doDataUnplug(long[] dataTransfer, long currentBytes) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001056 dataTransfer[STATS_SINCE_UNPLUGGED] = currentBytes;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001057 }
1058
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001059 /**
1060 * Radio uptime in microseconds when transferring data. This value is very approximate.
1061 * @return
1062 */
1063 private long getCurrentRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001064 try {
1065 File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms");
1066 if (!awakeTimeFile.exists()) return 0;
1067 BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile));
1068 String line = br.readLine();
1069 br.close();
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001070 return Long.parseLong(line) * 1000;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001071 } catch (NumberFormatException nfe) {
1072 // Nothing
1073 } catch (IOException ioe) {
1074 // Nothing
1075 }
1076 return 0;
1077 }
1078
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001079 /**
1080 * @deprecated use getRadioDataUptime
1081 */
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001082 public long getRadioDataUptimeMs() {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001083 return getRadioDataUptime() / 1000;
1084 }
1085
1086 /**
1087 * Returns the duration that the cell radio was up for data transfers.
1088 */
1089 public long getRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001090 if (mRadioDataStart == -1) {
1091 return mRadioDataUptime;
1092 } else {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001093 return getCurrentRadioDataUptime() - mRadioDataStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001094 }
1095 }
1096
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001097 private int getCurrentBluetoothPingCount() {
1098 if (mBtHeadset != null) {
1099 return mBtHeadset.getBatteryUsageHint();
1100 }
1101 return -1;
1102 }
1103
1104 public int getBluetoothPingCount() {
1105 if (mBluetoothPingStart == -1) {
1106 return mBluetoothPingCount;
1107 } else if (mBtHeadset != null) {
1108 return getCurrentBluetoothPingCount() - mBluetoothPingStart;
1109 }
Amith Yamasani82cb0292009-08-18 11:29:28 -07001110 return 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001111 }
1112
1113 public void setBtHeadset(BluetoothHeadset headset) {
Amith Yamasani82cb0292009-08-18 11:29:28 -07001114 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) {
1115 mBluetoothPingStart = getCurrentBluetoothPingCount();
1116 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001117 mBtHeadset = headset;
1118 }
1119
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001120 void addHistoryRecordLocked(long curTime) {
1121 if (!mHaveBatteryLevel || !mRecordingHistory) {
1122 return;
1123 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001124
1125 // If the current time is basically the same as the last time,
1126 // just collapse into one record.
1127 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
1128 && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+100)) {
1129 // If the current is the same as the one before, then we no
1130 // longer need the entry.
1131 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
1132 && mHistoryLastEnd.same(mHistoryCur)) {
1133 mHistoryLastEnd.next = null;
1134 mHistoryEnd.next = mHistoryCache;
1135 mHistoryCache = mHistoryEnd;
1136 mHistoryEnd = mHistoryLastEnd;
1137 mHistoryLastEnd = null;
1138 } else {
1139 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, mHistoryCur);
1140 }
1141 return;
1142 }
1143
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001144 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
1145 // Once we've reached the maximum number of items, we only
1146 // record changes to the battery level.
1147 if (mHistoryEnd != null && mHistoryEnd.batteryLevel
1148 == mHistoryCur.batteryLevel) {
1149 return;
1150 }
1151 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001152
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001153 addHistoryRecordLocked(curTime, HistoryItem.CMD_UPDATE);
1154 }
1155
1156 void addHistoryRecordLocked(long curTime, byte cmd) {
1157 HistoryItem rec = mHistoryCache;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001158 if (rec != null) {
1159 mHistoryCache = rec.next;
1160 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001161 rec = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001162 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001163 rec.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur);
1164
1165 addHistoryRecordLocked(rec);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001166 }
1167
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001168 void addHistoryRecordLocked(HistoryItem rec) {
1169 mNumHistoryItems++;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001170 rec.next = null;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001171 mHistoryLastEnd = mHistoryEnd;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001172 if (mHistoryEnd != null) {
1173 mHistoryEnd.next = rec;
1174 mHistoryEnd = rec;
1175 } else {
1176 mHistory = mHistoryEnd = rec;
1177 }
1178 }
1179
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001180 void clearHistoryLocked() {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001181 if (mHistory != null) {
1182 mHistoryEnd.next = mHistoryCache;
1183 mHistoryCache = mHistory;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001184 mHistory = mHistoryLastEnd = mHistoryEnd = null;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001185 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001186 mNumHistoryItems = 0;
1187 mHistoryBaseTime = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001188 }
1189
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001190 public void doUnplugLocked(long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001191 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
1192 Uid u = mUidStats.valueAt(iu);
Ken Shirriff1719a392009-12-07 15:57:35 -08001193 u.mStartedTcpBytesReceived = TrafficStats.getUidRxBytes(u.mUid);
1194 u.mStartedTcpBytesSent = TrafficStats.getUidTxBytes(u.mUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001195 u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived;
1196 u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent;
1197 }
1198 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
1199 mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime);
1200 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001201 // Track total mobile data
Ken Shirriff1719a392009-12-07 15:57:35 -08001202 doDataUnplug(mMobileDataRx, TrafficStats.getMobileRxBytes());
1203 doDataUnplug(mMobileDataTx, TrafficStats.getMobileTxBytes());
1204 doDataUnplug(mTotalDataRx, TrafficStats.getTotalRxBytes());
1205 doDataUnplug(mTotalDataTx, TrafficStats.getTotalTxBytes());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001206 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001207 mRadioDataStart = getCurrentRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001208 mRadioDataUptime = 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001209 // Track bt headset ping count
1210 mBluetoothPingStart = getCurrentBluetoothPingCount();
1211 mBluetoothPingCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001212 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001213
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001214 public void doPlugLocked(long batteryUptime, long batteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001215 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
1216 Uid u = mUidStats.valueAt(iu);
1217 if (u.mStartedTcpBytesReceived >= 0) {
1218 u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived();
1219 u.mStartedTcpBytesReceived = -1;
1220 }
1221 if (u.mStartedTcpBytesSent >= 0) {
1222 u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent();
1223 u.mStartedTcpBytesSent = -1;
1224 }
1225 }
1226 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
1227 mUnpluggables.get(i).plug(batteryUptime, batteryRealtime);
1228 }
Ken Shirriff1719a392009-12-07 15:57:35 -08001229 doDataPlug(mMobileDataRx, TrafficStats.getMobileRxBytes());
1230 doDataPlug(mMobileDataTx, TrafficStats.getMobileTxBytes());
1231 doDataPlug(mTotalDataRx, TrafficStats.getTotalRxBytes());
1232 doDataPlug(mTotalDataTx, TrafficStats.getTotalTxBytes());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001233 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001234 mRadioDataUptime = getRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001235 mRadioDataStart = -1;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001236
1237 // Track bt headset ping count
1238 mBluetoothPingCount = getBluetoothPingCount();
1239 mBluetoothPingStart = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001240 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001241
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001242 int mWakeLockNesting;
1243
1244 public void noteStartWakeLocked(int uid, int pid, String name, int type) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001245 if (type == WAKE_TYPE_PARTIAL) {
1246 // Only care about partial wake locks, since full wake locks
1247 // will be canceled when the user puts the screen to sleep.
1248 if (mWakeLockNesting == 0) {
1249 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
1250 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
1251 + Integer.toHexString(mHistoryCur.states));
1252 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1253 }
1254 mWakeLockNesting++;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001255 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001256 if (uid >= 0) {
1257 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type);
1258 }
1259 }
1260
1261 public void noteStopWakeLocked(int uid, int pid, String name, int type) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001262 if (type == WAKE_TYPE_PARTIAL) {
1263 mWakeLockNesting--;
1264 if (mWakeLockNesting == 0) {
1265 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
1266 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
1267 + Integer.toHexString(mHistoryCur.states));
1268 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1269 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001270 }
1271 if (uid >= 0) {
1272 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type);
1273 }
1274 }
1275
1276 public void noteProcessDiedLocked(int uid, int pid) {
1277 Uid u = mUidStats.get(uid);
1278 if (u != null) {
1279 u.mPids.remove(pid);
1280 }
1281 }
1282
1283 public long getProcessWakeTime(int uid, int pid, long realtime) {
1284 Uid u = mUidStats.get(uid);
1285 if (u != null) {
1286 Uid.Pid p = u.mPids.get(pid);
1287 if (p != null) {
1288 return p.mWakeSum + (p.mWakeStart != 0 ? (realtime - p.mWakeStart) : 0);
1289 }
1290 }
1291 return 0;
1292 }
1293
1294 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) {
1295 Uid u = mUidStats.get(uid);
1296 if (u != null) {
1297 u.reportExcessiveWakeLocked(proc, overTime, usedTime);
1298 }
1299 }
1300
1301 int mSensorNesting;
1302
1303 public void noteStartSensorLocked(int uid, int sensor) {
1304 if (mSensorNesting == 0) {
1305 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
1306 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
1307 + Integer.toHexString(mHistoryCur.states));
1308 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1309 }
1310 mSensorNesting++;
1311 getUidStatsLocked(uid).noteStartSensor(sensor);
1312 }
1313
1314 public void noteStopSensorLocked(int uid, int sensor) {
1315 mSensorNesting--;
1316 if (mSensorNesting == 0) {
1317 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
1318 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
1319 + Integer.toHexString(mHistoryCur.states));
1320 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1321 }
1322 getUidStatsLocked(uid).noteStopSensor(sensor);
1323 }
1324
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001325 int mGpsNesting;
1326
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001327 public void noteStartGpsLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001328 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001329 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001330 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
1331 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001332 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001333 }
1334 mGpsNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07001335 getUidStatsLocked(uid).noteStartGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001336 }
1337
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001338 public void noteStopGpsLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001339 mGpsNesting--;
1340 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001341 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001342 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
1343 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001344 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001345 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001346 getUidStatsLocked(uid).noteStopGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001347 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 public void noteScreenOnLocked() {
1350 if (!mScreenOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001351 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001352 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
1353 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001354 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001355 mScreenOn = true;
1356 mScreenOnTimer.startRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001357 if (mScreenBrightnessBin >= 0) {
1358 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this);
1359 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001360
1361 // Fake a wake lock, so we consider the device waked as long
1362 // as the screen is on.
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001363 noteStartWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001364 }
1365 }
1366
1367 public void noteScreenOffLocked() {
1368 if (mScreenOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001369 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001370 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
1371 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001372 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001373 mScreenOn = false;
1374 mScreenOnTimer.stopRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001375 if (mScreenBrightnessBin >= 0) {
1376 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1377 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001378
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001379 noteStopWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001380 }
1381 }
1382
1383 public void noteScreenBrightnessLocked(int brightness) {
1384 // Bin the brightness.
1385 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
1386 if (bin < 0) bin = 0;
1387 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
1388 if (mScreenBrightnessBin != bin) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001389 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
1390 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001391 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
1392 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001393 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn617f8772009-03-31 15:04:46 -07001394 if (mScreenOn) {
1395 if (mScreenBrightnessBin >= 0) {
1396 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1397 }
1398 mScreenBrightnessTimer[bin].startRunningLocked(this);
1399 }
1400 mScreenBrightnessBin = bin;
1401 }
1402 }
1403
Christopher Tate4cee7252010-03-19 14:50:40 -07001404 public void noteInputEventAtomic() {
1405 mInputEventCounter.stepAtomic();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001406 }
1407
1408 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001409 getUidStatsLocked(uid).noteUserActivityLocked(event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001410 }
1411
1412 public void notePhoneOnLocked() {
1413 if (!mPhoneOn) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001414 mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001415 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
1416 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001417 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001418 mPhoneOn = true;
1419 mPhoneOnTimer.startRunningLocked(this);
1420 }
1421 }
1422
1423 public void notePhoneOffLocked() {
1424 if (mPhoneOn) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001425 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001426 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
1427 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001428 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001429 mPhoneOn = false;
1430 mPhoneOnTimer.stopRunningLocked(this);
1431 }
1432 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001433
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001434 void stopAllSignalStrengthTimersLocked(int except) {
1435 for (int i = 0; i < NUM_SIGNAL_STRENGTH_BINS; i++) {
1436 if (i == except) {
1437 continue;
1438 }
1439 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
1440 mPhoneSignalStrengthsTimer[i].stopRunningLocked(this);
1441 }
1442 }
1443 }
1444
Amith Yamasanif37447b2009-10-08 18:28:01 -07001445 /**
1446 * Telephony stack updates the phone state.
1447 * @param state phone state from ServiceState.getState()
1448 */
1449 public void notePhoneStateLocked(int state) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001450 boolean scanning = false;
1451
Amith Yamasanif37447b2009-10-08 18:28:01 -07001452 int bin = mPhoneSignalStrengthBin;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001453
1454 // If the phone is powered off, stop all timers.
1455 if (state == ServiceState.STATE_POWER_OFF) {
1456 stopAllSignalStrengthTimersLocked(-1);
Amith Yamasanif37447b2009-10-08 18:28:01 -07001457
1458 // If we're back in service or continuing in service, restart the old timer.
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001459 } if (state == ServiceState.STATE_IN_SERVICE) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07001460 if (bin == -1) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
1461 if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
1462 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
1463 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001464
1465 // If we're out of service, we are in the lowest signal strength
1466 // bin and have the scanning bit set.
Amith Yamasanif37447b2009-10-08 18:28:01 -07001467 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001468 scanning = true;
Amith Yamasanif37447b2009-10-08 18:28:01 -07001469 mPhoneSignalStrengthBin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001470 stopAllSignalStrengthTimersLocked(mPhoneSignalStrengthBin);
Amith Yamasanif37447b2009-10-08 18:28:01 -07001471 if (!mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].isRunningLocked()) {
1472 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].startRunningLocked(this);
1473 }
1474 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001475 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
1476 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
1477 + Integer.toHexString(mHistoryCur.states));
1478 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasanif37447b2009-10-08 18:28:01 -07001479 mPhoneSignalScanningTimer.startRunningLocked(this);
1480 }
1481 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001482
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001483 if (!scanning) {
1484 // If we are no longer scanning, then stop the scanning timer.
1485 if (mPhoneSignalScanningTimer.isRunningLocked()) {
1486 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
1487 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
1488 + Integer.toHexString(mHistoryCur.states));
1489 addHistoryRecordLocked(SystemClock.elapsedRealtime());
1490 mPhoneSignalScanningTimer.stopRunningLocked(this);
1491 }
1492 }
1493
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001494 if (mPhoneServiceState != state) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001495 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
1496 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001497 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + bin + " to: "
1498 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001499 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001500 mPhoneServiceState = state;
1501 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001502 }
1503
Wink Savillee9b06d72009-05-18 21:47:50 -07001504 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07001505 // Bin the strength.
1506 int bin;
Amith Yamasanif37447b2009-10-08 18:28:01 -07001507 if (mPhoneServiceState == ServiceState.STATE_POWER_OFF
1508 || mPhoneServiceState == ServiceState.STATE_OUT_OF_SERVICE) {
1509 // Ignore any signal strength changes when radio was turned off or out of service.
1510 return;
1511 }
Wink Savillee9b06d72009-05-18 21:47:50 -07001512 if (!signalStrength.isGsm()) {
1513 int dBm = signalStrength.getCdmaDbm();
Amith Yamasanif37447b2009-10-08 18:28:01 -07001514 if (dBm >= -75) bin = SIGNAL_STRENGTH_GREAT;
1515 else if (dBm >= -85) bin = SIGNAL_STRENGTH_GOOD;
1516 else if (dBm >= -95) bin = SIGNAL_STRENGTH_MODERATE;
1517 else if (dBm >= -100) bin = SIGNAL_STRENGTH_POOR;
1518 else bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Wink Savillee9b06d72009-05-18 21:47:50 -07001519 } else {
1520 int asu = signalStrength.getGsmSignalStrength();
1521 if (asu < 0 || asu >= 99) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
1522 else if (asu >= 16) bin = SIGNAL_STRENGTH_GREAT;
1523 else if (asu >= 8) bin = SIGNAL_STRENGTH_GOOD;
1524 else if (asu >= 4) bin = SIGNAL_STRENGTH_MODERATE;
1525 else bin = SIGNAL_STRENGTH_POOR;
1526 }
Dianne Hackborn627bba72009-03-24 22:32:56 -07001527 if (mPhoneSignalStrengthBin != bin) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001528 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
1529 | (bin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001530 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: "
1531 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001532 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn627bba72009-03-24 22:32:56 -07001533 if (mPhoneSignalStrengthBin >= 0) {
1534 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
1535 }
1536 mPhoneSignalStrengthBin = bin;
1537 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
1538 }
1539 }
1540
1541 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
1542 int bin = DATA_CONNECTION_NONE;
1543 if (hasData) {
1544 switch (dataType) {
1545 case TelephonyManager.NETWORK_TYPE_EDGE:
1546 bin = DATA_CONNECTION_EDGE;
1547 break;
1548 case TelephonyManager.NETWORK_TYPE_GPRS:
1549 bin = DATA_CONNECTION_GPRS;
1550 break;
1551 case TelephonyManager.NETWORK_TYPE_UMTS:
1552 bin = DATA_CONNECTION_UMTS;
1553 break;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001554 case TelephonyManager.NETWORK_TYPE_CDMA:
1555 bin = DATA_CONNECTION_CDMA;
1556 break;
1557 case TelephonyManager.NETWORK_TYPE_EVDO_0:
1558 bin = DATA_CONNECTION_EVDO_0;
1559 break;
1560 case TelephonyManager.NETWORK_TYPE_EVDO_A:
1561 bin = DATA_CONNECTION_EVDO_A;
1562 break;
1563 case TelephonyManager.NETWORK_TYPE_1xRTT:
1564 bin = DATA_CONNECTION_1xRTT;
1565 break;
1566 case TelephonyManager.NETWORK_TYPE_HSDPA:
1567 bin = DATA_CONNECTION_HSDPA;
1568 break;
1569 case TelephonyManager.NETWORK_TYPE_HSUPA:
1570 bin = DATA_CONNECTION_HSUPA;
1571 break;
1572 case TelephonyManager.NETWORK_TYPE_HSPA:
1573 bin = DATA_CONNECTION_HSPA;
1574 break;
1575 case TelephonyManager.NETWORK_TYPE_IDEN:
1576 bin = DATA_CONNECTION_IDEN;
1577 break;
1578 case TelephonyManager.NETWORK_TYPE_EVDO_B:
1579 bin = DATA_CONNECTION_EVDO_B;
1580 break;
Dianne Hackborn627bba72009-03-24 22:32:56 -07001581 default:
1582 bin = DATA_CONNECTION_OTHER;
1583 break;
1584 }
1585 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001586 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001587 if (mPhoneDataConnectionType != bin) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001588 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
1589 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001590 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
1591 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001592 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn627bba72009-03-24 22:32:56 -07001593 if (mPhoneDataConnectionType >= 0) {
1594 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this);
1595 }
1596 mPhoneDataConnectionType = bin;
1597 mPhoneDataConnectionsTimer[bin].startRunningLocked(this);
1598 }
1599 }
1600
Dianne Hackborn617f8772009-03-31 15:04:46 -07001601 public void noteWifiOnLocked(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001602 if (!mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001603 mHistoryCur.states |= HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001604 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
1605 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001606 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07001607 mWifiOn = true;
1608 mWifiOnTimer.startRunningLocked(this);
1609 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001610 if (mWifiOnUid != uid) {
1611 if (mWifiOnUid >= 0) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001612 getUidStatsLocked(mWifiOnUid).noteWifiTurnedOffLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001613 }
1614 mWifiOnUid = uid;
Dianne Hackborn2e418422009-06-22 20:00:17 -07001615 getUidStatsLocked(uid).noteWifiTurnedOnLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001616 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001617 }
1618
Dianne Hackborn617f8772009-03-31 15:04:46 -07001619 public void noteWifiOffLocked(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001620 if (mWifiOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001621 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001622 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
1623 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001624 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07001625 mWifiOn = false;
1626 mWifiOnTimer.stopRunningLocked(this);
1627 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001628 if (mWifiOnUid >= 0) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001629 getUidStatsLocked(mWifiOnUid).noteWifiTurnedOffLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001630 mWifiOnUid = -1;
1631 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001632 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001633
1634 public void noteAudioOnLocked(int uid) {
1635 if (!mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001636 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001637 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
1638 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001639 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001640 mAudioOn = true;
1641 mAudioOnTimer.startRunningLocked(this);
1642 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001643 getUidStatsLocked(uid).noteAudioTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001644 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001645
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001646 public void noteAudioOffLocked(int uid) {
1647 if (mAudioOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001648 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001649 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
1650 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001651 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001652 mAudioOn = false;
1653 mAudioOnTimer.stopRunningLocked(this);
1654 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001655 getUidStatsLocked(uid).noteAudioTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001656 }
1657
1658 public void noteVideoOnLocked(int uid) {
1659 if (!mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001660 mHistoryCur.states |= HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001661 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
1662 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001663 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001664 mVideoOn = true;
1665 mVideoOnTimer.startRunningLocked(this);
1666 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001667 getUidStatsLocked(uid).noteVideoTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001668 }
1669
1670 public void noteVideoOffLocked(int uid) {
1671 if (mVideoOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001672 mHistoryCur.states &= ~HistoryItem.STATE_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001673 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
1674 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001675 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001676 mVideoOn = false;
1677 mVideoOnTimer.stopRunningLocked(this);
1678 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001679 getUidStatsLocked(uid).noteVideoTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001680 }
1681
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001682 public void noteWifiRunningLocked() {
1683 if (!mWifiRunning) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001684 mHistoryCur.states |= HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001685 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
1686 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001687 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001688 mWifiRunning = true;
1689 mWifiRunningTimer.startRunningLocked(this);
1690 }
1691 }
1692
1693 public void noteWifiStoppedLocked() {
1694 if (mWifiRunning) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001695 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001696 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
1697 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001698 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001699 mWifiRunning = false;
1700 mWifiRunningTimer.stopRunningLocked(this);
1701 }
1702 }
1703
The Android Open Source Project10592532009-03-18 17:39:46 -07001704 public void noteBluetoothOnLocked() {
1705 if (!mBluetoothOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001706 mHistoryCur.states |= HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001707 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: "
1708 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001709 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07001710 mBluetoothOn = true;
1711 mBluetoothOnTimer.startRunningLocked(this);
1712 }
1713 }
1714
1715 public void noteBluetoothOffLocked() {
1716 if (mBluetoothOn) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001717 mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001718 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: "
1719 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001720 addHistoryRecordLocked(SystemClock.elapsedRealtime());
The Android Open Source Project10592532009-03-18 17:39:46 -07001721 mBluetoothOn = false;
1722 mBluetoothOnTimer.stopRunningLocked(this);
1723 }
1724 }
1725
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001726 int mWifiFullLockNesting = 0;
1727
The Android Open Source Project10592532009-03-18 17:39:46 -07001728 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001729 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001730 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001731 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
1732 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001733 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001734 }
1735 mWifiFullLockNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07001736 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001737 }
1738
1739 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001740 mWifiFullLockNesting--;
1741 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001742 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001743 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
1744 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001745 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001746 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001747 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001748 }
1749
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001750 int mWifiScanLockNesting = 0;
1751
The Android Open Source Project10592532009-03-18 17:39:46 -07001752 public void noteScanWifiLockAcquiredLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001753 if (mWifiScanLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001754 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001755 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock on to: "
1756 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001757 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001758 }
1759 mWifiScanLockNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07001760 getUidStatsLocked(uid).noteScanWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001761 }
1762
1763 public void noteScanWifiLockReleasedLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001764 mWifiScanLockNesting--;
1765 if (mWifiScanLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001766 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001767 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock off to: "
1768 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001769 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001770 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001771 getUidStatsLocked(uid).noteScanWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001772 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001773
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001774 int mWifiMulticastNesting = 0;
1775
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001776 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001777 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001778 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001779 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
1780 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001781 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001782 }
1783 mWifiMulticastNesting++;
Dianne Hackborn2e418422009-06-22 20:00:17 -07001784 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001785 }
1786
1787 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001788 mWifiMulticastNesting--;
1789 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001790 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001791 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
1792 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001793 addHistoryRecordLocked(SystemClock.elapsedRealtime());
Dianne Hackborn32907cf2010-06-10 17:50:20 -07001794 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001795 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001796 }
1797
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001798 @Override public long getScreenOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001799 return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001800 }
1801
Dianne Hackborn617f8772009-03-31 15:04:46 -07001802 @Override public long getScreenBrightnessTime(int brightnessBin,
1803 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001804 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn617f8772009-03-31 15:04:46 -07001805 batteryRealtime, which);
1806 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001807
Dianne Hackborn617f8772009-03-31 15:04:46 -07001808 @Override public int getInputEventCount(int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001809 return mInputEventCounter.getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001810 }
1811
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001812 @Override public long getPhoneOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001813 return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001814 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001815
Dianne Hackborn627bba72009-03-24 22:32:56 -07001816 @Override public long getPhoneSignalStrengthTime(int strengthBin,
1817 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001818 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07001819 batteryRealtime, which);
1820 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07001821
1822 @Override public long getPhoneSignalScanningTime(
1823 long batteryRealtime, int which) {
1824 return mPhoneSignalScanningTimer.getTotalTimeLocked(
1825 batteryRealtime, which);
1826 }
1827
Dianne Hackborn617f8772009-03-31 15:04:46 -07001828 @Override public int getPhoneSignalStrengthCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001829 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001830 }
1831
Dianne Hackborn627bba72009-03-24 22:32:56 -07001832 @Override public long getPhoneDataConnectionTime(int dataType,
1833 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001834 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07001835 batteryRealtime, which);
1836 }
1837
Dianne Hackborn617f8772009-03-31 15:04:46 -07001838 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001839 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001840 }
1841
The Android Open Source Project10592532009-03-18 17:39:46 -07001842 @Override public long getWifiOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001843 return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001844 }
1845
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001846 @Override public long getWifiRunningTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001847 return mWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001848 }
1849
The Android Open Source Project10592532009-03-18 17:39:46 -07001850 @Override public long getBluetoothOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001851 return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001852 }
1853
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001854 @Override public boolean getIsOnBattery() {
1855 return mOnBattery;
1856 }
1857
1858 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
1859 return mUidStats;
1860 }
1861
1862 /**
1863 * The statistics associated with a particular uid.
1864 */
1865 public final class Uid extends BatteryStats.Uid {
1866
1867 final int mUid;
1868 long mLoadedTcpBytesReceived;
1869 long mLoadedTcpBytesSent;
1870 long mCurrentTcpBytesReceived;
1871 long mCurrentTcpBytesSent;
1872 long mTcpBytesReceivedAtLastUnplug;
1873 long mTcpBytesSentAtLastUnplug;
1874
1875 // These are not saved/restored when parcelling, since we want
1876 // to return from the parcel with a snapshot of the state.
1877 long mStartedTcpBytesReceived = -1;
1878 long mStartedTcpBytesSent = -1;
1879
Dianne Hackborn617f8772009-03-31 15:04:46 -07001880 boolean mWifiTurnedOn;
Evan Millarc64edde2009-04-18 12:26:32 -07001881 StopwatchTimer mWifiTurnedOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -07001882
The Android Open Source Project10592532009-03-18 17:39:46 -07001883 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07001884 StopwatchTimer mFullWifiLockTimer;
The Android Open Source Project10592532009-03-18 17:39:46 -07001885
1886 boolean mScanWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07001887 StopwatchTimer mScanWifiLockTimer;
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001888
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001889 boolean mWifiMulticastEnabled;
1890 StopwatchTimer mWifiMulticastTimer;
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001891
1892 boolean mAudioTurnedOn;
1893 StopwatchTimer mAudioTurnedOnTimer;
1894
1895 boolean mVideoTurnedOn;
1896 StopwatchTimer mVideoTurnedOnTimer;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001897
Dianne Hackborn617f8772009-03-31 15:04:46 -07001898 Counter[] mUserActivityCounters;
1899
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001900 /**
1901 * The statistics we have collected for this uid's wake locks.
1902 */
1903 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>();
1904
1905 /**
1906 * The statistics we have collected for this uid's sensor activations.
1907 */
1908 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>();
1909
1910 /**
1911 * The statistics we have collected for this uid's processes.
1912 */
1913 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>();
1914
1915 /**
1916 * The statistics we have collected for this uid's processes.
1917 */
1918 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>();
1919
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001920 /**
1921 * The transient wake stats we have collected for this uid's pids.
1922 */
1923 final SparseArray<Pid> mPids = new SparseArray<Pid>();
1924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001925 public Uid(int uid) {
1926 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001927 mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, null, mUnpluggables);
1928 mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables);
1929 mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001930 mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED,
1931 null, mUnpluggables);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001932 mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, null, mUnpluggables);
1933 mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001934 }
1935
1936 @Override
1937 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
1938 return mWakelockStats;
1939 }
1940
1941 @Override
1942 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() {
1943 return mSensorStats;
1944 }
1945
1946 @Override
1947 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
1948 return mProcessStats;
1949 }
1950
1951 @Override
1952 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
1953 return mPackageStats;
1954 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001955
1956 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001957 public int getUid() {
1958 return mUid;
1959 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001960
1961 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001962 public long getTcpBytesReceived(int which) {
1963 if (which == STATS_LAST) {
1964 return mLoadedTcpBytesReceived;
1965 } else {
1966 long current = computeCurrentTcpBytesReceived();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001967 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001968 current -= mTcpBytesReceivedAtLastUnplug;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001969 } else if (which == STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001970 current += mLoadedTcpBytesReceived;
1971 }
1972 return current;
1973 }
1974 }
1975
1976 public long computeCurrentTcpBytesReceived() {
1977 return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0
Ken Shirriff1719a392009-12-07 15:57:35 -08001978 ? (TrafficStats.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001979 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001980
1981 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001982 public long getTcpBytesSent(int which) {
1983 if (which == STATS_LAST) {
1984 return mLoadedTcpBytesSent;
1985 } else {
1986 long current = computeCurrentTcpBytesSent();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001987 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001988 current -= mTcpBytesSentAtLastUnplug;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001989 } else if (which == STATS_SINCE_CHARGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001990 current += mLoadedTcpBytesSent;
1991 }
1992 return current;
1993 }
1994 }
1995
The Android Open Source Project10592532009-03-18 17:39:46 -07001996 @Override
Dianne Hackborn617f8772009-03-31 15:04:46 -07001997 public void noteWifiTurnedOnLocked() {
1998 if (!mWifiTurnedOn) {
1999 mWifiTurnedOn = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002000 if (mWifiTurnedOnTimer == null) {
2001 mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON,
2002 null, mUnpluggables);
2003 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07002004 mWifiTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
2005 }
2006 }
2007
2008 @Override
2009 public void noteWifiTurnedOffLocked() {
2010 if (mWifiTurnedOn) {
2011 mWifiTurnedOn = false;
2012 mWifiTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
2013 }
2014 }
2015
2016 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002017 public void noteFullWifiLockAcquiredLocked() {
2018 if (!mFullWifiLockOut) {
2019 mFullWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002020 if (mFullWifiLockTimer == null) {
2021 mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK,
2022 null, mUnpluggables);
2023 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002024 mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
2025 }
2026 }
2027
2028 @Override
2029 public void noteFullWifiLockReleasedLocked() {
2030 if (mFullWifiLockOut) {
2031 mFullWifiLockOut = false;
2032 mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
2033 }
2034 }
2035
2036 @Override
2037 public void noteScanWifiLockAcquiredLocked() {
2038 if (!mScanWifiLockOut) {
2039 mScanWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002040 if (mScanWifiLockTimer == null) {
2041 mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK,
2042 null, mUnpluggables);
2043 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002044 mScanWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
2045 }
2046 }
2047
2048 @Override
2049 public void noteScanWifiLockReleasedLocked() {
2050 if (mScanWifiLockOut) {
2051 mScanWifiLockOut = false;
2052 mScanWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
2053 }
2054 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002055
2056 @Override
2057 public void noteWifiMulticastEnabledLocked() {
2058 if (!mWifiMulticastEnabled) {
2059 mWifiMulticastEnabled = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002060 if (mWifiMulticastTimer == null) {
2061 mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED,
2062 null, mUnpluggables);
2063 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002064 mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this);
2065 }
2066 }
2067
2068 @Override
2069 public void noteWifiMulticastDisabledLocked() {
2070 if (mWifiMulticastEnabled) {
2071 mWifiMulticastEnabled = false;
2072 mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this);
2073 }
2074 }
2075
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002076 @Override
2077 public void noteAudioTurnedOnLocked() {
2078 if (!mAudioTurnedOn) {
2079 mAudioTurnedOn = true;
2080 if (mAudioTurnedOnTimer == null) {
2081 mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON,
2082 null, mUnpluggables);
2083 }
2084 mAudioTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
2085 }
2086 }
2087
2088 @Override
2089 public void noteAudioTurnedOffLocked() {
2090 if (mAudioTurnedOn) {
2091 mAudioTurnedOn = false;
2092 mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
2093 }
2094 }
2095
2096 @Override
2097 public void noteVideoTurnedOnLocked() {
2098 if (!mVideoTurnedOn) {
2099 mVideoTurnedOn = true;
2100 if (mVideoTurnedOnTimer == null) {
2101 mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON,
2102 null, mUnpluggables);
2103 }
2104 mVideoTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
2105 }
2106 }
2107
2108 @Override
2109 public void noteVideoTurnedOffLocked() {
2110 if (mVideoTurnedOn) {
2111 mVideoTurnedOn = false;
2112 mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
2113 }
2114 }
2115
Dianne Hackborn617f8772009-03-31 15:04:46 -07002116 @Override
2117 public long getWifiTurnedOnTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002118 if (mWifiTurnedOnTimer == null) {
2119 return 0;
2120 }
Evan Millarc64edde2009-04-18 12:26:32 -07002121 return mWifiTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002122 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002123
2124 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07002125 public long getFullWifiLockTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002126 if (mFullWifiLockTimer == null) {
2127 return 0;
2128 }
Evan Millarc64edde2009-04-18 12:26:32 -07002129 return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002130 }
2131
2132 @Override
2133 public long getScanWifiLockTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002134 if (mScanWifiLockTimer == null) {
2135 return 0;
2136 }
Evan Millarc64edde2009-04-18 12:26:32 -07002137 return mScanWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07002138 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002139
2140 @Override
2141 public long getWifiMulticastTime(long batteryRealtime, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002142 if (mWifiMulticastTimer == null) {
2143 return 0;
2144 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002145 return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime,
2146 which);
2147 }
2148
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002149 @Override
2150 public long getAudioTurnedOnTime(long batteryRealtime, int which) {
2151 if (mAudioTurnedOnTimer == null) {
2152 return 0;
2153 }
2154 return mAudioTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
2155 }
2156
2157 @Override
2158 public long getVideoTurnedOnTime(long batteryRealtime, int which) {
2159 if (mVideoTurnedOnTimer == null) {
2160 return 0;
2161 }
2162 return mVideoTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
2163 }
2164
Dianne Hackborn617f8772009-03-31 15:04:46 -07002165 @Override
2166 public void noteUserActivityLocked(int type) {
2167 if (mUserActivityCounters == null) {
2168 initUserActivityLocked();
2169 }
2170 if (type < 0) type = 0;
2171 else if (type >= NUM_USER_ACTIVITY_TYPES) type = NUM_USER_ACTIVITY_TYPES-1;
Christopher Tate4cee7252010-03-19 14:50:40 -07002172 mUserActivityCounters[type].stepAtomic();
Dianne Hackborn617f8772009-03-31 15:04:46 -07002173 }
2174
2175 @Override
2176 public boolean hasUserActivity() {
2177 return mUserActivityCounters != null;
2178 }
2179
2180 @Override
2181 public int getUserActivityCount(int type, int which) {
2182 if (mUserActivityCounters == null) {
2183 return 0;
2184 }
Evan Millarc64edde2009-04-18 12:26:32 -07002185 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002186 }
2187
2188 void initUserActivityLocked() {
2189 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
2190 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2191 mUserActivityCounters[i] = new Counter(mUnpluggables);
2192 }
2193 }
2194
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002195 public long computeCurrentTcpBytesSent() {
2196 return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0
Ken Shirriff1719a392009-12-07 15:57:35 -08002197 ? (TrafficStats.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002198 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002199
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002200 /**
2201 * Clear all stats for this uid. Returns true if the uid is completely
2202 * inactive so can be dropped.
2203 */
2204 boolean reset() {
2205 boolean active = false;
2206
2207 if (mWifiTurnedOnTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002208 active |= !mWifiTurnedOnTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002209 active |= mWifiTurnedOn;
2210 }
2211 if (mFullWifiLockTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002212 active |= !mFullWifiLockTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002213 active |= mFullWifiLockOut;
2214 }
2215 if (mScanWifiLockTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002216 active |= !mScanWifiLockTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002217 active |= mScanWifiLockOut;
2218 }
2219 if (mWifiMulticastTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002220 active |= !mWifiMulticastTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002221 active |= mWifiMulticastEnabled;
2222 }
2223 if (mAudioTurnedOnTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002224 active |= !mAudioTurnedOnTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002225 active |= mAudioTurnedOn;
2226 }
2227 if (mVideoTurnedOnTimer != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002228 active |= !mVideoTurnedOnTimer.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002229 active |= mVideoTurnedOn;
2230 }
2231
2232 mLoadedTcpBytesReceived = mLoadedTcpBytesSent = 0;
2233 mCurrentTcpBytesReceived = mCurrentTcpBytesSent = 0;
2234
2235 if (mUserActivityCounters != null) {
2236 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2237 mUserActivityCounters[i].reset(false);
2238 }
2239 }
2240
2241 if (mWakelockStats.size() > 0) {
2242 Iterator<Map.Entry<String, Wakelock>> it = mWakelockStats.entrySet().iterator();
2243 while (it.hasNext()) {
2244 Map.Entry<String, Wakelock> wakelockEntry = it.next();
2245 Wakelock wl = wakelockEntry.getValue();
2246 if (wl.reset()) {
2247 it.remove();
2248 } else {
2249 active = true;
2250 }
2251 }
2252 }
2253 if (mSensorStats.size() > 0) {
2254 Iterator<Map.Entry<Integer, Sensor>> it = mSensorStats.entrySet().iterator();
2255 while (it.hasNext()) {
2256 Map.Entry<Integer, Sensor> sensorEntry = it.next();
2257 Sensor s = sensorEntry.getValue();
2258 if (s.reset()) {
2259 it.remove();
2260 } else {
2261 active = true;
2262 }
2263 }
2264 }
2265 if (mProcessStats.size() > 0) {
2266 Iterator<Map.Entry<String, Proc>> it = mProcessStats.entrySet().iterator();
2267 while (it.hasNext()) {
2268 Map.Entry<String, Proc> procEntry = it.next();
2269 procEntry.getValue().detach();
2270 }
2271 mProcessStats.clear();
2272 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002273 if (mPids.size() > 0) {
2274 for (int i=0; !active && i<mPids.size(); i++) {
2275 Pid pid = mPids.valueAt(i);
2276 if (pid.mWakeStart != 0) {
2277 active = true;
2278 }
2279 }
2280 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002281 if (mPackageStats.size() > 0) {
2282 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator();
2283 while (it.hasNext()) {
2284 Map.Entry<String, Pkg> pkgEntry = it.next();
2285 Pkg p = pkgEntry.getValue();
2286 p.detach();
2287 if (p.mServiceStats.size() > 0) {
2288 Iterator<Map.Entry<String, Pkg.Serv>> it2
2289 = p.mServiceStats.entrySet().iterator();
2290 while (it2.hasNext()) {
2291 Map.Entry<String, Pkg.Serv> servEntry = it2.next();
2292 servEntry.getValue().detach();
2293 }
2294 }
2295 }
2296 mPackageStats.clear();
2297 }
2298
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002299 mPids.clear();
2300
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002301 if (!active) {
2302 if (mWifiTurnedOnTimer != null) {
2303 mWifiTurnedOnTimer.detach();
2304 }
2305 if (mFullWifiLockTimer != null) {
2306 mFullWifiLockTimer.detach();
2307 }
2308 if (mScanWifiLockTimer != null) {
2309 mScanWifiLockTimer.detach();
2310 }
2311 if (mWifiMulticastTimer != null) {
2312 mWifiMulticastTimer.detach();
2313 }
2314 if (mAudioTurnedOnTimer != null) {
2315 mAudioTurnedOnTimer.detach();
2316 }
2317 if (mVideoTurnedOnTimer != null) {
2318 mVideoTurnedOnTimer.detach();
2319 }
2320 if (mUserActivityCounters != null) {
2321 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2322 mUserActivityCounters[i].detach();
2323 }
2324 }
2325 }
2326
2327 return !active;
2328 }
2329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002330 void writeToParcelLocked(Parcel out, long batteryRealtime) {
2331 out.writeInt(mWakelockStats.size());
2332 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
2333 out.writeString(wakelockEntry.getKey());
2334 Uid.Wakelock wakelock = wakelockEntry.getValue();
2335 wakelock.writeToParcelLocked(out, batteryRealtime);
2336 }
2337
2338 out.writeInt(mSensorStats.size());
2339 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) {
2340 out.writeInt(sensorEntry.getKey());
2341 Uid.Sensor sensor = sensorEntry.getValue();
2342 sensor.writeToParcelLocked(out, batteryRealtime);
2343 }
2344
2345 out.writeInt(mProcessStats.size());
2346 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) {
2347 out.writeString(procEntry.getKey());
2348 Uid.Proc proc = procEntry.getValue();
2349 proc.writeToParcelLocked(out);
2350 }
2351
2352 out.writeInt(mPackageStats.size());
2353 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
2354 out.writeString(pkgEntry.getKey());
2355 Uid.Pkg pkg = pkgEntry.getValue();
2356 pkg.writeToParcelLocked(out);
2357 }
2358
2359 out.writeLong(mLoadedTcpBytesReceived);
2360 out.writeLong(mLoadedTcpBytesSent);
2361 out.writeLong(computeCurrentTcpBytesReceived());
2362 out.writeLong(computeCurrentTcpBytesSent());
2363 out.writeLong(mTcpBytesReceivedAtLastUnplug);
2364 out.writeLong(mTcpBytesSentAtLastUnplug);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002365 if (mWifiTurnedOnTimer != null) {
2366 out.writeInt(1);
2367 mWifiTurnedOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002368 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002369 out.writeInt(0);
2370 }
2371 if (mFullWifiLockTimer != null) {
2372 out.writeInt(1);
2373 mFullWifiLockTimer.writeToParcel(out, batteryRealtime);
2374 } else {
2375 out.writeInt(0);
2376 }
2377 if (mScanWifiLockTimer != null) {
2378 out.writeInt(1);
2379 mScanWifiLockTimer.writeToParcel(out, batteryRealtime);
2380 } else {
2381 out.writeInt(0);
2382 }
2383 if (mWifiMulticastTimer != null) {
2384 out.writeInt(1);
2385 mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
2386 } else {
2387 out.writeInt(0);
2388 }
2389 if (mAudioTurnedOnTimer != null) {
2390 out.writeInt(1);
2391 mAudioTurnedOnTimer.writeToParcel(out, batteryRealtime);
2392 } else {
2393 out.writeInt(0);
2394 }
2395 if (mVideoTurnedOnTimer != null) {
2396 out.writeInt(1);
2397 mVideoTurnedOnTimer.writeToParcel(out, batteryRealtime);
2398 } else {
2399 out.writeInt(0);
2400 }
2401 if (mUserActivityCounters != null) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07002402 out.writeInt(1);
2403 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2404 mUserActivityCounters[i].writeToParcel(out);
2405 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002406 } else {
2407 out.writeInt(0);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002409 }
2410
2411 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
2412 int numWakelocks = in.readInt();
2413 mWakelockStats.clear();
2414 for (int j = 0; j < numWakelocks; j++) {
2415 String wakelockName = in.readString();
2416 Uid.Wakelock wakelock = new Wakelock();
2417 wakelock.readFromParcelLocked(unpluggables, in);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08002418 if (mWakelockStats.size() < MAX_WAKELOCKS_PER_UID) {
2419 // We will just drop some random set of wakelocks if
2420 // the previous run of the system was an older version
2421 // that didn't impose a limit.
2422 mWakelockStats.put(wakelockName, wakelock);
2423 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002424 }
2425
2426 int numSensors = in.readInt();
2427 mSensorStats.clear();
2428 for (int k = 0; k < numSensors; k++) {
2429 int sensorNumber = in.readInt();
2430 Uid.Sensor sensor = new Sensor(sensorNumber);
2431 sensor.readFromParcelLocked(mUnpluggables, in);
2432 mSensorStats.put(sensorNumber, sensor);
2433 }
2434
2435 int numProcs = in.readInt();
2436 mProcessStats.clear();
2437 for (int k = 0; k < numProcs; k++) {
2438 String processName = in.readString();
2439 Uid.Proc proc = new Proc();
2440 proc.readFromParcelLocked(in);
2441 mProcessStats.put(processName, proc);
2442 }
2443
2444 int numPkgs = in.readInt();
2445 mPackageStats.clear();
2446 for (int l = 0; l < numPkgs; l++) {
2447 String packageName = in.readString();
2448 Uid.Pkg pkg = new Pkg();
2449 pkg.readFromParcelLocked(in);
2450 mPackageStats.put(packageName, pkg);
2451 }
2452
2453 mLoadedTcpBytesReceived = in.readLong();
2454 mLoadedTcpBytesSent = in.readLong();
2455 mCurrentTcpBytesReceived = in.readLong();
2456 mCurrentTcpBytesSent = in.readLong();
2457 mTcpBytesReceivedAtLastUnplug = in.readLong();
2458 mTcpBytesSentAtLastUnplug = in.readLong();
Dianne Hackborn617f8772009-03-31 15:04:46 -07002459 mWifiTurnedOn = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002460 if (in.readInt() != 0) {
2461 mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON,
2462 null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002463 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002464 mWifiTurnedOnTimer = null;
2465 }
2466 mFullWifiLockOut = false;
2467 if (in.readInt() != 0) {
2468 mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK,
2469 null, mUnpluggables, in);
2470 } else {
2471 mFullWifiLockTimer = null;
2472 }
2473 mScanWifiLockOut = false;
2474 if (in.readInt() != 0) {
2475 mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK,
2476 null, mUnpluggables, in);
2477 } else {
2478 mScanWifiLockTimer = null;
2479 }
2480 mWifiMulticastEnabled = false;
2481 if (in.readInt() != 0) {
2482 mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED,
2483 null, mUnpluggables, in);
2484 } else {
2485 mWifiMulticastTimer = null;
2486 }
2487 mAudioTurnedOn = false;
2488 if (in.readInt() != 0) {
2489 mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON,
2490 null, mUnpluggables, in);
2491 } else {
2492 mAudioTurnedOnTimer = null;
2493 }
2494 mVideoTurnedOn = false;
2495 if (in.readInt() != 0) {
2496 mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON,
2497 null, mUnpluggables, in);
2498 } else {
2499 mVideoTurnedOnTimer = null;
2500 }
2501 if (in.readInt() != 0) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07002502 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
2503 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
2504 mUserActivityCounters[i] = new Counter(mUnpluggables, in);
2505 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002506 } else {
2507 mUserActivityCounters = null;
Dianne Hackborn617f8772009-03-31 15:04:46 -07002508 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002509 }
2510
2511 /**
2512 * The statistics associated with a particular wake lock.
2513 */
2514 public final class Wakelock extends BatteryStats.Uid.Wakelock {
2515 /**
2516 * How long (in ms) this uid has been keeping the device partially awake.
2517 */
Evan Millarc64edde2009-04-18 12:26:32 -07002518 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002519
2520 /**
2521 * How long (in ms) this uid has been keeping the device fully awake.
2522 */
Evan Millarc64edde2009-04-18 12:26:32 -07002523 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002524
2525 /**
2526 * How long (in ms) this uid has had a window keeping the device awake.
2527 */
Evan Millarc64edde2009-04-18 12:26:32 -07002528 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002529
2530 /**
2531 * Reads a possibly null Timer from a Parcel. The timer is associated with the
2532 * proper timer pool from the given BatteryStatsImpl object.
2533 *
2534 * @param in the Parcel to be read from.
2535 * return a new Timer, or null.
2536 */
Evan Millarc64edde2009-04-18 12:26:32 -07002537 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002538 ArrayList<Unpluggable> unpluggables, Parcel in) {
2539 if (in.readInt() == 0) {
2540 return null;
2541 }
2542
Evan Millarc64edde2009-04-18 12:26:32 -07002543 return new StopwatchTimer(type, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002544 }
2545
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002546 boolean reset() {
2547 boolean wlactive = false;
2548 if (mTimerFull != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002549 wlactive |= !mTimerFull.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002550 }
2551 if (mTimerPartial != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002552 wlactive |= !mTimerPartial.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002553 }
2554 if (mTimerWindow != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002555 wlactive |= !mTimerWindow.reset(BatteryStatsImpl.this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002556 }
2557 if (!wlactive) {
2558 if (mTimerFull != null) {
2559 mTimerFull.detach();
2560 mTimerFull = null;
2561 }
2562 if (mTimerPartial != null) {
2563 mTimerPartial.detach();
2564 mTimerPartial = null;
2565 }
2566 if (mTimerWindow != null) {
2567 mTimerWindow.detach();
2568 mTimerWindow = null;
2569 }
2570 }
2571 return !wlactive;
2572 }
2573
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002574 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
2575 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
2576 mPartialTimers, unpluggables, in);
2577 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
2578 mFullTimers, unpluggables, in);
2579 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
2580 mWindowTimers, unpluggables, in);
2581 }
2582
2583 void writeToParcelLocked(Parcel out, long batteryRealtime) {
2584 Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime);
2585 Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime);
2586 Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime);
2587 }
2588
2589 @Override
2590 public Timer getWakeTime(int type) {
2591 switch (type) {
2592 case WAKE_TYPE_FULL: return mTimerFull;
2593 case WAKE_TYPE_PARTIAL: return mTimerPartial;
2594 case WAKE_TYPE_WINDOW: return mTimerWindow;
2595 default: throw new IllegalArgumentException("type = " + type);
2596 }
2597 }
2598 }
2599
2600 public final class Sensor extends BatteryStats.Uid.Sensor {
2601 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07002602 StopwatchTimer mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002603
2604 public Sensor(int handle) {
2605 mHandle = handle;
2606 }
2607
Evan Millarc64edde2009-04-18 12:26:32 -07002608 private StopwatchTimer readTimerFromParcel(ArrayList<Unpluggable> unpluggables,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002609 Parcel in) {
2610 if (in.readInt() == 0) {
2611 return null;
2612 }
2613
Evan Millarc64edde2009-04-18 12:26:32 -07002614 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002615 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002616 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002617 mSensorTimers.put(mHandle, pool);
2618 }
Evan Millarc64edde2009-04-18 12:26:32 -07002619 return new StopwatchTimer(0, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002620 }
2621
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002622 boolean reset() {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002623 if (mTimer.reset(BatteryStatsImpl.this, true)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002624 mTimer = null;
2625 return true;
2626 }
2627 return false;
2628 }
2629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002630 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
2631 mTimer = readTimerFromParcel(unpluggables, in);
2632 }
2633
2634 void writeToParcelLocked(Parcel out, long batteryRealtime) {
2635 Timer.writeTimerToParcel(out, mTimer, batteryRealtime);
2636 }
2637
2638 @Override
2639 public Timer getSensorTime() {
2640 return mTimer;
2641 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002642
2643 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002644 public int getHandle() {
2645 return mHandle;
2646 }
2647 }
2648
2649 /**
2650 * The statistics associated with a particular process.
2651 */
2652 public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable {
2653 /**
2654 * Total time (in 1/100 sec) spent executing in user code.
2655 */
2656 long mUserTime;
2657
2658 /**
2659 * Total time (in 1/100 sec) spent executing in kernel code.
2660 */
2661 long mSystemTime;
2662
2663 /**
2664 * Number of times the process has been started.
2665 */
2666 int mStarts;
2667
2668 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002669 * Amount of time the process was running in the foreground.
2670 */
2671 long mForegroundTime;
2672
2673 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002674 * The amount of user time loaded from a previous save.
2675 */
2676 long mLoadedUserTime;
2677
2678 /**
2679 * The amount of system time loaded from a previous save.
2680 */
2681 long mLoadedSystemTime;
2682
2683 /**
2684 * The number of times the process has started from a previous save.
2685 */
2686 int mLoadedStarts;
2687
2688 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002689 * The amount of foreground time loaded from a previous save.
2690 */
2691 long mLoadedForegroundTime;
2692
2693 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002694 * The amount of user time loaded from the previous run.
2695 */
2696 long mLastUserTime;
2697
2698 /**
2699 * The amount of system time loaded from the previous run.
2700 */
2701 long mLastSystemTime;
2702
2703 /**
2704 * The number of times the process has started from the previous run.
2705 */
2706 int mLastStarts;
2707
2708 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002709 * The amount of foreground time loaded from the previous run
2710 */
2711 long mLastForegroundTime;
2712
2713 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002714 * The amount of user time when last unplugged.
2715 */
2716 long mUnpluggedUserTime;
2717
2718 /**
2719 * The amount of system time when last unplugged.
2720 */
2721 long mUnpluggedSystemTime;
2722
2723 /**
2724 * The number of times the process has started before unplugged.
2725 */
2726 int mUnpluggedStarts;
2727
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002728 /**
2729 * The amount of foreground time since unplugged.
2730 */
2731 long mUnpluggedForegroundTime;
2732
Amith Yamasanie43530a2009-08-21 13:11:37 -07002733 SamplingCounter[] mSpeedBins;
2734
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002735 ArrayList<ExcessiveWake> mExcessiveWake;
2736
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002737 Proc() {
2738 mUnpluggables.add(this);
Amith Yamasanie43530a2009-08-21 13:11:37 -07002739 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002740 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07002741
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002742 public void unplug(long batteryUptime, long batteryRealtime) {
2743 mUnpluggedUserTime = mUserTime;
2744 mUnpluggedSystemTime = mSystemTime;
2745 mUnpluggedStarts = mStarts;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002746 mUnpluggedForegroundTime = mForegroundTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002747 }
2748
2749 public void plug(long batteryUptime, long batteryRealtime) {
2750 }
2751
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002752 void detach() {
2753 mUnpluggables.remove(this);
2754 for (int i = 0; i < mSpeedBins.length; i++) {
2755 SamplingCounter c = mSpeedBins[i];
2756 if (c != null) {
2757 mUnpluggables.remove(c);
2758 mSpeedBins[i] = null;
2759 }
2760 }
2761 }
2762
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002763 public int countExcessiveWakes() {
2764 return mExcessiveWake != null ? mExcessiveWake.size() : 0;
2765 }
2766
2767 public ExcessiveWake getExcessiveWake(int i) {
2768 if (mExcessiveWake != null) {
2769 return mExcessiveWake.get(i);
2770 }
2771 return null;
2772 }
2773
2774 public void addExcessiveWake(long overTime, long usedTime) {
2775 if (mExcessiveWake == null) {
2776 mExcessiveWake = new ArrayList<ExcessiveWake>();
2777 }
2778 ExcessiveWake ew = new ExcessiveWake();
2779 ew.overTime = overTime;
2780 ew.usedTime = usedTime;
2781 mExcessiveWake.add(ew);
2782 }
2783
2784 void writeExcessiveWakeToParcelLocked(Parcel out) {
2785 if (mExcessiveWake == null) {
2786 out.writeInt(0);
2787 return;
2788 }
2789
2790 final int N = mExcessiveWake.size();
2791 out.writeInt(N);
2792 for (int i=0; i<N; i++) {
2793 ExcessiveWake ew = mExcessiveWake.get(i);
2794 out.writeLong(ew.overTime);
2795 out.writeLong(ew.usedTime);
2796 }
2797 }
2798
2799 void readExcessiveWakeFromParcelLocked(Parcel in) {
2800 final int N = in.readInt();
2801 if (N == 0) {
2802 mExcessiveWake = null;
2803 return;
2804 }
2805
2806 mExcessiveWake = new ArrayList<ExcessiveWake>();
2807 for (int i=0; i<N; i++) {
2808 ExcessiveWake ew = new ExcessiveWake();
2809 ew.overTime = in.readLong();
2810 ew.usedTime = in.readLong();
2811 mExcessiveWake.add(ew);
2812 }
2813 }
2814
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002815 void writeToParcelLocked(Parcel out) {
2816 out.writeLong(mUserTime);
2817 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002818 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002819 out.writeInt(mStarts);
2820 out.writeLong(mLoadedUserTime);
2821 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002822 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002823 out.writeInt(mLoadedStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002824 out.writeLong(mUnpluggedUserTime);
2825 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002826 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002827 out.writeInt(mUnpluggedStarts);
Amith Yamasanie43530a2009-08-21 13:11:37 -07002828
2829 out.writeInt(mSpeedBins.length);
2830 for (int i = 0; i < mSpeedBins.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002831 SamplingCounter c = mSpeedBins[i];
2832 if (c != null) {
2833 out.writeInt(1);
2834 c.writeToParcel(out);
2835 } else {
2836 out.writeInt(0);
2837 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07002838 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002839
2840 writeExcessiveWakeToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002841 }
2842
2843 void readFromParcelLocked(Parcel in) {
2844 mUserTime = in.readLong();
2845 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002846 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002847 mStarts = in.readInt();
2848 mLoadedUserTime = in.readLong();
2849 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002850 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002851 mLoadedStarts = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07002852 mLastUserTime = 0;
2853 mLastSystemTime = 0;
2854 mLastForegroundTime = 0;
2855 mLastStarts = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002856 mUnpluggedUserTime = in.readLong();
2857 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002858 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002859 mUnpluggedStarts = in.readInt();
Amith Yamasanie43530a2009-08-21 13:11:37 -07002860
2861 int bins = in.readInt();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002862 int steps = getCpuSpeedSteps();
2863 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps];
Amith Yamasanie43530a2009-08-21 13:11:37 -07002864 for (int i = 0; i < bins; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002865 if (in.readInt() != 0) {
2866 mSpeedBins[i] = new SamplingCounter(mUnpluggables, in);
2867 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07002868 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002869
2870 readExcessiveWakeFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002871 }
2872
2873 public BatteryStatsImpl getBatteryStats() {
2874 return BatteryStatsImpl.this;
2875 }
2876
2877 public void addCpuTimeLocked(int utime, int stime) {
2878 mUserTime += utime;
2879 mSystemTime += stime;
2880 }
2881
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002882 public void addForegroundTimeLocked(long ttime) {
2883 mForegroundTime += ttime;
2884 }
2885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002886 public void incStartsLocked() {
2887 mStarts++;
2888 }
2889
2890 @Override
2891 public long getUserTime(int which) {
2892 long val;
2893 if (which == STATS_LAST) {
2894 val = mLastUserTime;
2895 } else {
2896 val = mUserTime;
2897 if (which == STATS_CURRENT) {
2898 val -= mLoadedUserTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002899 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002900 val -= mUnpluggedUserTime;
2901 }
2902 }
2903 return val;
2904 }
2905
2906 @Override
2907 public long getSystemTime(int which) {
2908 long val;
2909 if (which == STATS_LAST) {
2910 val = mLastSystemTime;
2911 } else {
2912 val = mSystemTime;
2913 if (which == STATS_CURRENT) {
2914 val -= mLoadedSystemTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002915 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002916 val -= mUnpluggedSystemTime;
2917 }
2918 }
2919 return val;
2920 }
2921
2922 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002923 public long getForegroundTime(int which) {
2924 long val;
2925 if (which == STATS_LAST) {
2926 val = mLastForegroundTime;
2927 } else {
2928 val = mForegroundTime;
2929 if (which == STATS_CURRENT) {
2930 val -= mLoadedForegroundTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002931 } else if (which == STATS_SINCE_UNPLUGGED) {
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002932 val -= mUnpluggedForegroundTime;
2933 }
2934 }
2935 return val;
2936 }
2937
2938 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002939 public int getStarts(int which) {
2940 int val;
2941 if (which == STATS_LAST) {
2942 val = mLastStarts;
2943 } else {
2944 val = mStarts;
2945 if (which == STATS_CURRENT) {
2946 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002947 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002948 val -= mUnpluggedStarts;
2949 }
2950 }
2951 return val;
2952 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07002953
2954 /* Called by ActivityManagerService when CPU times are updated. */
2955 public void addSpeedStepTimes(long[] values) {
2956 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002957 long amt = values[i];
2958 if (amt != 0) {
2959 SamplingCounter c = mSpeedBins[i];
2960 if (c == null) {
2961 mSpeedBins[i] = c = new SamplingCounter(mUnpluggables);
2962 }
2963 c.addCountAtomic(values[i]);
2964 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07002965 }
2966 }
2967
2968 @Override
2969 public long getTimeAtCpuSpeedStep(int speedStep, int which) {
2970 if (speedStep < mSpeedBins.length) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002971 SamplingCounter c = mSpeedBins[speedStep];
2972 return c != null ? c.getCountLocked(which) : 0;
Amith Yamasanie43530a2009-08-21 13:11:37 -07002973 } else {
2974 return 0;
2975 }
2976 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002977 }
2978
2979 /**
2980 * The statistics associated with a particular package.
2981 */
2982 public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable {
2983 /**
2984 * Number of times this package has done something that could wake up the
2985 * device from sleep.
2986 */
2987 int mWakeups;
2988
2989 /**
2990 * Number of things that could wake up the device loaded from a
2991 * previous save.
2992 */
2993 int mLoadedWakeups;
2994
2995 /**
2996 * Number of things that could wake up the device as of the
2997 * last run.
2998 */
2999 int mLastWakeups;
3000
3001 /**
3002 * Number of things that could wake up the device as of the
3003 * last run.
3004 */
3005 int mUnpluggedWakeups;
3006
3007 /**
3008 * The statics we have collected for this package's services.
3009 */
3010 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
3011
3012 Pkg() {
3013 mUnpluggables.add(this);
3014 }
3015
3016 public void unplug(long batteryUptime, long batteryRealtime) {
3017 mUnpluggedWakeups = mWakeups;
3018 }
3019
3020 public void plug(long batteryUptime, long batteryRealtime) {
3021 }
3022
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003023 void detach() {
3024 mUnpluggables.remove(this);
3025 }
3026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003027 void readFromParcelLocked(Parcel in) {
3028 mWakeups = in.readInt();
3029 mLoadedWakeups = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003030 mLastWakeups = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003031 mUnpluggedWakeups = in.readInt();
3032
3033 int numServs = in.readInt();
3034 mServiceStats.clear();
3035 for (int m = 0; m < numServs; m++) {
3036 String serviceName = in.readString();
3037 Uid.Pkg.Serv serv = new Serv();
3038 mServiceStats.put(serviceName, serv);
3039
3040 serv.readFromParcelLocked(in);
3041 }
3042 }
3043
3044 void writeToParcelLocked(Parcel out) {
3045 out.writeInt(mWakeups);
3046 out.writeInt(mLoadedWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003047 out.writeInt(mUnpluggedWakeups);
3048
3049 out.writeInt(mServiceStats.size());
3050 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
3051 out.writeString(servEntry.getKey());
3052 Uid.Pkg.Serv serv = servEntry.getValue();
3053
3054 serv.writeToParcelLocked(out);
3055 }
3056 }
3057
3058 @Override
3059 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
3060 return mServiceStats;
3061 }
3062
3063 @Override
3064 public int getWakeups(int which) {
3065 int val;
3066 if (which == STATS_LAST) {
3067 val = mLastWakeups;
3068 } else {
3069 val = mWakeups;
3070 if (which == STATS_CURRENT) {
3071 val -= mLoadedWakeups;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003072 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003073 val -= mUnpluggedWakeups;
3074 }
3075 }
3076
3077 return val;
3078 }
3079
3080 /**
3081 * The statistics associated with a particular service.
3082 */
3083 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable {
3084 /**
3085 * Total time (ms in battery uptime) the service has been left started.
3086 */
3087 long mStartTime;
3088
3089 /**
3090 * If service has been started and not yet stopped, this is
3091 * when it was started.
3092 */
3093 long mRunningSince;
3094
3095 /**
3096 * True if we are currently running.
3097 */
3098 boolean mRunning;
3099
3100 /**
3101 * Total number of times startService() has been called.
3102 */
3103 int mStarts;
3104
3105 /**
3106 * Total time (ms in battery uptime) the service has been left launched.
3107 */
3108 long mLaunchedTime;
3109
3110 /**
3111 * If service has been launched and not yet exited, this is
3112 * when it was launched (ms in battery uptime).
3113 */
3114 long mLaunchedSince;
3115
3116 /**
3117 * True if we are currently launched.
3118 */
3119 boolean mLaunched;
3120
3121 /**
3122 * Total number times the service has been launched.
3123 */
3124 int mLaunches;
3125
3126 /**
3127 * The amount of time spent started loaded from a previous save
3128 * (ms in battery uptime).
3129 */
3130 long mLoadedStartTime;
3131
3132 /**
3133 * The number of starts loaded from a previous save.
3134 */
3135 int mLoadedStarts;
3136
3137 /**
3138 * The number of launches loaded from a previous save.
3139 */
3140 int mLoadedLaunches;
3141
3142 /**
3143 * The amount of time spent started as of the last run (ms
3144 * in battery uptime).
3145 */
3146 long mLastStartTime;
3147
3148 /**
3149 * The number of starts as of the last run.
3150 */
3151 int mLastStarts;
3152
3153 /**
3154 * The number of launches as of the last run.
3155 */
3156 int mLastLaunches;
3157
3158 /**
3159 * The amount of time spent started when last unplugged (ms
3160 * in battery uptime).
3161 */
3162 long mUnpluggedStartTime;
3163
3164 /**
3165 * The number of starts when last unplugged.
3166 */
3167 int mUnpluggedStarts;
3168
3169 /**
3170 * The number of launches when last unplugged.
3171 */
3172 int mUnpluggedLaunches;
3173
3174 Serv() {
3175 mUnpluggables.add(this);
3176 }
3177
3178 public void unplug(long batteryUptime, long batteryRealtime) {
3179 mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime);
3180 mUnpluggedStarts = mStarts;
3181 mUnpluggedLaunches = mLaunches;
3182 }
3183
3184 public void plug(long batteryUptime, long batteryRealtime) {
3185 }
3186
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003187 void detach() {
3188 mUnpluggables.remove(this);
3189 }
3190
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003191 void readFromParcelLocked(Parcel in) {
3192 mStartTime = in.readLong();
3193 mRunningSince = in.readLong();
3194 mRunning = in.readInt() != 0;
3195 mStarts = in.readInt();
3196 mLaunchedTime = in.readLong();
3197 mLaunchedSince = in.readLong();
3198 mLaunched = in.readInt() != 0;
3199 mLaunches = in.readInt();
3200 mLoadedStartTime = in.readLong();
3201 mLoadedStarts = in.readInt();
3202 mLoadedLaunches = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003203 mLastStartTime = 0;
3204 mLastStarts = 0;
3205 mLastLaunches = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003206 mUnpluggedStartTime = in.readLong();
3207 mUnpluggedStarts = in.readInt();
3208 mUnpluggedLaunches = in.readInt();
3209 }
3210
3211 void writeToParcelLocked(Parcel out) {
3212 out.writeLong(mStartTime);
3213 out.writeLong(mRunningSince);
3214 out.writeInt(mRunning ? 1 : 0);
3215 out.writeInt(mStarts);
3216 out.writeLong(mLaunchedTime);
3217 out.writeLong(mLaunchedSince);
3218 out.writeInt(mLaunched ? 1 : 0);
3219 out.writeInt(mLaunches);
3220 out.writeLong(mLoadedStartTime);
3221 out.writeInt(mLoadedStarts);
3222 out.writeInt(mLoadedLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003223 out.writeLong(mUnpluggedStartTime);
3224 out.writeInt(mUnpluggedStarts);
3225 out.writeInt(mUnpluggedLaunches);
3226 }
3227
3228 long getLaunchTimeToNowLocked(long batteryUptime) {
3229 if (!mLaunched) return mLaunchedTime;
3230 return mLaunchedTime + batteryUptime - mLaunchedSince;
3231 }
3232
3233 long getStartTimeToNowLocked(long batteryUptime) {
3234 if (!mRunning) return mStartTime;
3235 return mStartTime + batteryUptime - mRunningSince;
3236 }
3237
3238 public void startLaunchedLocked() {
3239 if (!mLaunched) {
3240 mLaunches++;
3241 mLaunchedSince = getBatteryUptimeLocked();
3242 mLaunched = true;
3243 }
3244 }
3245
3246 public void stopLaunchedLocked() {
3247 if (mLaunched) {
3248 long time = getBatteryUptimeLocked() - mLaunchedSince;
3249 if (time > 0) {
3250 mLaunchedTime += time;
3251 } else {
3252 mLaunches--;
3253 }
3254 mLaunched = false;
3255 }
3256 }
3257
3258 public void startRunningLocked() {
3259 if (!mRunning) {
3260 mStarts++;
3261 mRunningSince = getBatteryUptimeLocked();
3262 mRunning = true;
3263 }
3264 }
3265
3266 public void stopRunningLocked() {
3267 if (mRunning) {
3268 long time = getBatteryUptimeLocked() - mRunningSince;
3269 if (time > 0) {
3270 mStartTime += time;
3271 } else {
3272 mStarts--;
3273 }
3274 mRunning = false;
3275 }
3276 }
3277
3278 public BatteryStatsImpl getBatteryStats() {
3279 return BatteryStatsImpl.this;
3280 }
3281
3282 @Override
3283 public int getLaunches(int which) {
3284 int val;
3285
3286 if (which == STATS_LAST) {
3287 val = mLastLaunches;
3288 } else {
3289 val = mLaunches;
3290 if (which == STATS_CURRENT) {
3291 val -= mLoadedLaunches;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003292 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003293 val -= mUnpluggedLaunches;
3294 }
3295 }
3296
3297 return val;
3298 }
3299
3300 @Override
3301 public long getStartTime(long now, int which) {
3302 long val;
3303 if (which == STATS_LAST) {
3304 val = mLastStartTime;
3305 } else {
3306 val = getStartTimeToNowLocked(now);
3307 if (which == STATS_CURRENT) {
3308 val -= mLoadedStartTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003309 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003310 val -= mUnpluggedStartTime;
3311 }
3312 }
3313
3314 return val;
3315 }
3316
3317 @Override
3318 public int getStarts(int which) {
3319 int val;
3320 if (which == STATS_LAST) {
3321 val = mLastStarts;
3322 } else {
3323 val = mStarts;
3324 if (which == STATS_CURRENT) {
3325 val -= mLoadedStarts;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003326 } else if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003327 val -= mUnpluggedStarts;
3328 }
3329 }
3330
3331 return val;
3332 }
3333 }
3334
3335 public BatteryStatsImpl getBatteryStats() {
3336 return BatteryStatsImpl.this;
3337 }
3338
3339 public void incWakeupsLocked() {
3340 mWakeups++;
3341 }
3342
3343 final Serv newServiceStatsLocked() {
3344 return new Serv();
3345 }
3346 }
3347
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003348 public class Pid {
3349 long mWakeSum;
3350 long mWakeStart;
3351 }
3352
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003353 /**
3354 * Retrieve the statistics object for a particular process, creating
3355 * if needed.
3356 */
3357 public Proc getProcessStatsLocked(String name) {
3358 Proc ps = mProcessStats.get(name);
3359 if (ps == null) {
3360 ps = new Proc();
3361 mProcessStats.put(name, ps);
3362 }
3363
3364 return ps;
3365 }
3366
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003367 public Pid getPidStatsLocked(int pid) {
3368 Pid p = mPids.get(pid);
3369 if (p == null) {
3370 p = new Pid();
3371 mPids.put(pid, p);
3372 }
3373 return p;
3374 }
3375
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003376 /**
3377 * Retrieve the statistics object for a particular service, creating
3378 * if needed.
3379 */
3380 public Pkg getPackageStatsLocked(String name) {
3381 Pkg ps = mPackageStats.get(name);
3382 if (ps == null) {
3383 ps = new Pkg();
3384 mPackageStats.put(name, ps);
3385 }
3386
3387 return ps;
3388 }
3389
3390 /**
3391 * Retrieve the statistics object for a particular service, creating
3392 * if needed.
3393 */
3394 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
3395 Pkg ps = getPackageStatsLocked(pkg);
3396 Pkg.Serv ss = ps.mServiceStats.get(serv);
3397 if (ss == null) {
3398 ss = ps.newServiceStatsLocked();
3399 ps.mServiceStats.put(serv, ss);
3400 }
3401
3402 return ss;
3403 }
3404
Evan Millarc64edde2009-04-18 12:26:32 -07003405 public StopwatchTimer getWakeTimerLocked(String name, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003406 Wakelock wl = mWakelockStats.get(name);
3407 if (wl == null) {
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08003408 if (mWakelockStats.size() > MAX_WAKELOCKS_PER_UID) {
3409 name = BATCHED_WAKELOCK_NAME;
3410 wl = mWakelockStats.get(name);
3411 }
3412 if (wl == null) {
3413 wl = new Wakelock();
3414 mWakelockStats.put(name, wl);
3415 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003416 }
Evan Millarc64edde2009-04-18 12:26:32 -07003417 StopwatchTimer t = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003418 switch (type) {
3419 case WAKE_TYPE_PARTIAL:
3420 t = wl.mTimerPartial;
3421 if (t == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07003422 t = new StopwatchTimer(WAKE_TYPE_PARTIAL, mPartialTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003423 wl.mTimerPartial = t;
3424 }
3425 return t;
3426 case WAKE_TYPE_FULL:
3427 t = wl.mTimerFull;
3428 if (t == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07003429 t = new StopwatchTimer(WAKE_TYPE_FULL, mFullTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003430 wl.mTimerFull = t;
3431 }
3432 return t;
3433 case WAKE_TYPE_WINDOW:
3434 t = wl.mTimerWindow;
3435 if (t == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07003436 t = new StopwatchTimer(WAKE_TYPE_WINDOW, mWindowTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003437 wl.mTimerWindow = t;
3438 }
3439 return t;
3440 default:
3441 throw new IllegalArgumentException("type=" + type);
3442 }
3443 }
3444
Evan Millarc64edde2009-04-18 12:26:32 -07003445 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003446 Sensor se = mSensorStats.get(sensor);
3447 if (se == null) {
3448 if (!create) {
3449 return null;
3450 }
3451 se = new Sensor(sensor);
3452 mSensorStats.put(sensor, se);
3453 }
Evan Millarc64edde2009-04-18 12:26:32 -07003454 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003455 if (t != null) {
3456 return t;
3457 }
Evan Millarc64edde2009-04-18 12:26:32 -07003458 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003459 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07003460 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003461 mSensorTimers.put(sensor, timers);
3462 }
Evan Millarc64edde2009-04-18 12:26:32 -07003463 t = new StopwatchTimer(BatteryStats.SENSOR, timers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003464 se.mTimer = t;
3465 return t;
3466 }
3467
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003468 public void noteStartWakeLocked(int pid, String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07003469 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003470 if (t != null) {
3471 t.startRunningLocked(BatteryStatsImpl.this);
3472 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003473 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003474 Pid p = getPidStatsLocked(pid);
3475 p.mWakeStart = SystemClock.elapsedRealtime();
3476 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003477 }
3478
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003479 public void noteStopWakeLocked(int pid, String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07003480 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003481 if (t != null) {
3482 t.stopRunningLocked(BatteryStatsImpl.this);
3483 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003484 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003485 Pid p = mPids.get(pid);
3486 if (p != null) {
3487 p.mWakeSum += SystemClock.elapsedRealtime() - p.mWakeStart;
3488 p.mWakeStart = 0;
3489 }
3490 }
3491 }
3492
3493 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) {
3494 Proc p = getProcessStatsLocked(proc);
3495 if (p != null) {
3496 p.addExcessiveWake(overTime, usedTime);
3497 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003498 }
3499
3500 public void noteStartSensor(int sensor) {
Evan Millarc64edde2009-04-18 12:26:32 -07003501 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003502 if (t != null) {
3503 t.startRunningLocked(BatteryStatsImpl.this);
3504 }
3505 }
3506
3507 public void noteStopSensor(int sensor) {
3508 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07003509 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003510 if (t != null) {
3511 t.stopRunningLocked(BatteryStatsImpl.this);
3512 }
3513 }
3514
3515 public void noteStartGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07003516 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003517 if (t != null) {
3518 t.startRunningLocked(BatteryStatsImpl.this);
3519 }
3520 }
3521
3522 public void noteStopGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07003523 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003524 if (t != null) {
3525 t.stopRunningLocked(BatteryStatsImpl.this);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003526 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003527 }
3528
3529 public BatteryStatsImpl getBatteryStats() {
3530 return BatteryStatsImpl.this;
3531 }
3532 }
3533
3534 public BatteryStatsImpl(String filename) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003535 mFile = new JournaledFile(new File(filename), new File(filename + ".tmp"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003536 mStartCount++;
Evan Millarc64edde2009-04-18 12:26:32 -07003537 mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003538 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07003539 mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003540 }
3541 mInputEventCounter = new Counter(mUnpluggables);
Evan Millarc64edde2009-04-18 12:26:32 -07003542 mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003543 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07003544 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003545 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07003546 mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003547 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07003548 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003549 }
Evan Millarc64edde2009-04-18 12:26:32 -07003550 mWifiOnTimer = new StopwatchTimer(-3, null, mUnpluggables);
3551 mWifiRunningTimer = new StopwatchTimer(-4, null, mUnpluggables);
3552 mBluetoothOnTimer = new StopwatchTimer(-5, null, mUnpluggables);
Mike Chan18d200f2010-02-02 10:33:45 -08003553 mAudioOnTimer = new StopwatchTimer(-6, null, mUnpluggables);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003554 mVideoOnTimer = new StopwatchTimer(-7, null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003555 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003556 initTimes();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003557 mTrackBatteryPastUptime = 0;
3558 mTrackBatteryPastRealtime = 0;
3559 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
3560 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
3561 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
3562 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
Evan Millar633a1742009-04-02 16:36:33 -07003563 mDischargeStartLevel = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003564 mDischargeUnplugLevel = 0;
Evan Millar633a1742009-04-02 16:36:33 -07003565 mDischargeCurrentLevel = 0;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003566 mLowDischargeAmountSinceCharge = 0;
3567 mHighDischargeAmountSinceCharge = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003568 }
3569
3570 public BatteryStatsImpl(Parcel p) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003571 mFile = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003572 readFromParcel(p);
3573 }
3574
Amith Yamasanie43530a2009-08-21 13:11:37 -07003575 public void setNumSpeedSteps(int steps) {
3576 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
3577 }
3578
Amith Yamasanif37447b2009-10-08 18:28:01 -07003579 public void setRadioScanningTimeout(long timeout) {
3580 if (mPhoneSignalScanningTimer != null) {
3581 mPhoneSignalScanningTimer.setTimeout(timeout);
3582 }
3583 }
3584
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003585 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003586 public HistoryItem getHistory() {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003587 return mHistory;
3588 }
3589
3590 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003591 public int getStartCount() {
3592 return mStartCount;
3593 }
3594
3595 public boolean isOnBattery() {
3596 return mOnBattery;
3597 }
3598
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003599 public boolean isScreenOn() {
3600 return mScreenOn;
3601 }
3602
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003603 void initTimes() {
3604 mBatteryRealtime = mTrackBatteryPastUptime = 0;
3605 mBatteryUptime = mTrackBatteryPastRealtime = 0;
3606 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
3607 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
3608 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
3609 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
3610 }
3611
3612 public void resetAllStatsLocked() {
3613 mStartCount = 0;
3614 initTimes();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003615 mScreenOnTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003616 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003617 mScreenBrightnessTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003618 }
3619 mInputEventCounter.reset(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003620 mPhoneOnTimer.reset(this, false);
3621 mAudioOnTimer.reset(this, false);
3622 mVideoOnTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003623 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003624 mPhoneSignalStrengthsTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003625 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003626 mPhoneSignalScanningTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003627 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003628 mPhoneDataConnectionsTimer[i].reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003629 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003630 mWifiOnTimer.reset(this, false);
3631 mWifiRunningTimer.reset(this, false);
3632 mBluetoothOnTimer.reset(this, false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003633
3634 for (int i=0; i<mUidStats.size(); i++) {
3635 if (mUidStats.valueAt(i).reset()) {
3636 mUidStats.remove(mUidStats.keyAt(i));
3637 i--;
3638 }
3639 }
3640
3641 if (mKernelWakelockStats.size() > 0) {
3642 for (SamplingTimer timer : mKernelWakelockStats.values()) {
3643 mUnpluggables.remove(timer);
3644 }
3645 mKernelWakelockStats.clear();
3646 }
3647
3648 clearHistoryLocked();
3649 }
3650
3651 void setOnBattery(boolean onBattery, int oldStatus, int level) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003652 synchronized(this) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003653 boolean doWrite = false;
3654 mOnBattery = mOnBatteryInternal = onBattery;
3655
3656 long uptime = SystemClock.uptimeMillis() * 1000;
3657 long mSecRealtime = SystemClock.elapsedRealtime();
3658 long realtime = mSecRealtime * 1000;
3659 if (onBattery) {
3660 // We will reset our status if we are unplugging after the
3661 // battery was last full, or the level is at 100, or
3662 // we have gone through a significant charge (from a very low
3663 // level to a now very high level).
3664 if (oldStatus == BatteryManager.BATTERY_STATUS_FULL
3665 || level >= 100
3666 || (mDischargeCurrentLevel < 20 && level > 90)) {
3667 doWrite = true;
3668 resetAllStatsLocked();
3669 mDischargeStartLevel = level;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003670 mLowDischargeAmountSinceCharge = 0;
3671 mHighDischargeAmountSinceCharge = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003672 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003673 updateKernelWakelocksLocked();
3674 mHistoryCur.batteryLevel = (byte)level;
3675 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
3676 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
3677 + Integer.toHexString(mHistoryCur.states));
3678 addHistoryRecordLocked(mSecRealtime);
3679 mTrackBatteryUptimeStart = uptime;
3680 mTrackBatteryRealtimeStart = realtime;
3681 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
3682 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
3683 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
3684 doUnplugLocked(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
3685 } else {
3686 updateKernelWakelocksLocked();
3687 mHistoryCur.batteryLevel = (byte)level;
3688 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
3689 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
3690 + Integer.toHexString(mHistoryCur.states));
3691 addHistoryRecordLocked(mSecRealtime);
3692 mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
3693 mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
3694 mDischargeCurrentLevel = level;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003695 if (level < mDischargeUnplugLevel) {
Dianne Hackborn99d04522010-08-20 13:43:00 -07003696 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
3697 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003698 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003699 doPlugLocked(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
3700 }
3701 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
3702 if (mFile != null) {
3703 writeLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003704 }
3705 }
3706 }
3707 }
Evan Millar633a1742009-04-02 16:36:33 -07003708
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003709 // This should probably be exposed in the API, though it's not critical
3710 private static final int BATTERY_PLUGGED_NONE = 0;
3711
3712 public void setBatteryState(int status, int health, int plugType, int level,
3713 int temp, int volt) {
3714 boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
3715 int oldStatus = mHistoryCur.batteryStatus;
3716 if (!mHaveBatteryLevel) {
3717 mHaveBatteryLevel = true;
3718 // We start out assuming that the device is plugged in (not
3719 // on battery). If our first report is now that we are indeed
3720 // plugged in, then twiddle our state to correctly reflect that
3721 // since we won't be going through the full setOnBattery().
3722 if (onBattery == mOnBattery) {
3723 if (onBattery) {
3724 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
3725 } else {
3726 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
3727 }
3728 }
3729 oldStatus = status;
3730 }
3731 if (onBattery) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003732 mDischargeCurrentLevel = level;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003733 mRecordingHistory = true;
3734 }
3735 if (onBattery != mOnBattery) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003736 mHistoryCur.batteryLevel = (byte)level;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003737 mHistoryCur.batteryStatus = (byte)status;
3738 mHistoryCur.batteryHealth = (byte)health;
3739 mHistoryCur.batteryPlugType = (byte)plugType;
3740 mHistoryCur.batteryTemperature = (char)temp;
3741 mHistoryCur.batteryVoltage = (char)volt;
3742 setOnBattery(onBattery, oldStatus, level);
3743 } else {
3744 boolean changed = false;
3745 if (mHistoryCur.batteryLevel != level) {
3746 mHistoryCur.batteryLevel = (byte)level;
3747 changed = true;
3748 }
3749 if (mHistoryCur.batteryStatus != status) {
3750 mHistoryCur.batteryStatus = (byte)status;
3751 changed = true;
3752 }
3753 if (mHistoryCur.batteryHealth != health) {
3754 mHistoryCur.batteryHealth = (byte)health;
3755 changed = true;
3756 }
3757 if (mHistoryCur.batteryPlugType != plugType) {
3758 mHistoryCur.batteryPlugType = (byte)plugType;
3759 changed = true;
3760 }
3761 if (mHistoryCur.batteryTemperature != temp) {
3762 mHistoryCur.batteryTemperature = (char)temp;
3763 changed = true;
3764 }
3765 if (mHistoryCur.batteryVoltage != volt) {
3766 mHistoryCur.batteryVoltage = (char)volt;
3767 changed = true;
3768 }
3769 if (changed) {
3770 addHistoryRecordLocked(SystemClock.elapsedRealtime());
3771 }
3772 }
3773 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
3774 // We don't record history while we are plugged in and fully charged.
3775 // The next time we are unplugged, history will be cleared.
3776 mRecordingHistory = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003777 }
Evan Millar633a1742009-04-02 16:36:33 -07003778 }
Evan Millarc64edde2009-04-18 12:26:32 -07003779
3780 public void updateKernelWakelocksLocked() {
3781 Map<String, KernelWakelockStats> m = readKernelWakelockStats();
3782
Marco Nelissend8593312009-04-30 14:45:06 -07003783 if (m == null) {
3784 // Not crashing might make board bringup easier.
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07003785 Slog.w(TAG, "Couldn't get kernel wake lock stats");
Marco Nelissend8593312009-04-30 14:45:06 -07003786 return;
3787 }
3788
Evan Millarc64edde2009-04-18 12:26:32 -07003789 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) {
3790 String name = ent.getKey();
3791 KernelWakelockStats kws = ent.getValue();
3792
3793 SamplingTimer kwlt = mKernelWakelockStats.get(name);
3794 if (kwlt == null) {
3795 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
3796 true /* track reported values */);
3797 mKernelWakelockStats.put(name, kwlt);
3798 }
3799 kwlt.updateCurrentReportedCount(kws.mCount);
3800 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
3801 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion);
3802 }
3803
3804 if (m.size() != mKernelWakelockStats.size()) {
3805 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
3806 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
3807 SamplingTimer st = ent.getValue();
3808 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) {
3809 st.setStale();
3810 }
3811 }
3812 }
3813 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003814
3815 public long getAwakeTimeBattery() {
3816 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
3817 }
3818
3819 public long getAwakeTimePlugged() {
3820 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
3821 }
3822
3823 @Override
3824 public long computeUptime(long curTime, int which) {
3825 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003826 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003827 case STATS_LAST: return mLastUptime;
3828 case STATS_CURRENT: return (curTime-mUptimeStart);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003829 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003830 }
3831 return 0;
3832 }
3833
3834 @Override
3835 public long computeRealtime(long curTime, int which) {
3836 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003837 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003838 case STATS_LAST: return mLastRealtime;
3839 case STATS_CURRENT: return (curTime-mRealtimeStart);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003840 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003841 }
3842 return 0;
3843 }
3844
3845 @Override
3846 public long computeBatteryUptime(long curTime, int which) {
3847 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003848 case STATS_SINCE_CHARGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003849 return mBatteryUptime + getBatteryUptime(curTime);
3850 case STATS_LAST:
3851 return mBatteryLastUptime;
3852 case STATS_CURRENT:
3853 return getBatteryUptime(curTime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003854 case STATS_SINCE_UNPLUGGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003855 return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime;
3856 }
3857 return 0;
3858 }
3859
3860 @Override
3861 public long computeBatteryRealtime(long curTime, int which) {
3862 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003863 case STATS_SINCE_CHARGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003864 return mBatteryRealtime + getBatteryRealtimeLocked(curTime);
3865 case STATS_LAST:
3866 return mBatteryLastRealtime;
3867 case STATS_CURRENT:
3868 return getBatteryRealtimeLocked(curTime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003869 case STATS_SINCE_UNPLUGGED:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003870 return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime;
3871 }
3872 return 0;
3873 }
3874
3875 long getBatteryUptimeLocked(long curTime) {
3876 long time = mTrackBatteryPastUptime;
3877 if (mOnBatteryInternal) {
3878 time += curTime - mTrackBatteryUptimeStart;
3879 }
3880 return time;
3881 }
3882
3883 long getBatteryUptimeLocked() {
3884 return getBatteryUptime(SystemClock.uptimeMillis() * 1000);
3885 }
3886
3887 @Override
3888 public long getBatteryUptime(long curTime) {
3889 return getBatteryUptimeLocked(curTime);
3890 }
3891
3892 long getBatteryRealtimeLocked(long curTime) {
3893 long time = mTrackBatteryPastRealtime;
3894 if (mOnBatteryInternal) {
3895 time += curTime - mTrackBatteryRealtimeStart;
3896 }
3897 return time;
3898 }
3899
3900 @Override
3901 public long getBatteryRealtime(long curTime) {
3902 return getBatteryRealtimeLocked(curTime);
3903 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003904
3905 private long getTcpBytes(long current, long[] dataBytes, int which) {
3906 if (which == STATS_LAST) {
3907 return dataBytes[STATS_LAST];
3908 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003909 if (which == STATS_SINCE_UNPLUGGED) {
3910 if (dataBytes[STATS_SINCE_UNPLUGGED] < 0) {
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003911 return dataBytes[STATS_LAST];
3912 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003913 return current - dataBytes[STATS_SINCE_UNPLUGGED];
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003914 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003915 } else if (which == STATS_SINCE_CHARGED) {
3916 return (current - dataBytes[STATS_CURRENT]) + dataBytes[STATS_SINCE_CHARGED];
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003917 }
3918 return current - dataBytes[STATS_CURRENT];
3919 }
3920 }
3921
3922 /** Only STATS_UNPLUGGED works properly */
3923 public long getMobileTcpBytesSent(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08003924 return getTcpBytes(TrafficStats.getMobileTxBytes(), mMobileDataTx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003925 }
3926
3927 /** Only STATS_UNPLUGGED works properly */
3928 public long getMobileTcpBytesReceived(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08003929 return getTcpBytes(TrafficStats.getMobileRxBytes(), mMobileDataRx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003930 }
3931
3932 /** Only STATS_UNPLUGGED works properly */
3933 public long getTotalTcpBytesSent(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08003934 return getTcpBytes(TrafficStats.getTotalTxBytes(), mTotalDataTx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003935 }
3936
3937 /** Only STATS_UNPLUGGED works properly */
3938 public long getTotalTcpBytesReceived(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08003939 return getTcpBytes(TrafficStats.getTotalRxBytes(), mTotalDataRx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003940 }
3941
The Android Open Source Project10592532009-03-18 17:39:46 -07003942 @Override
Evan Millar633a1742009-04-02 16:36:33 -07003943 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07003944 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07003945 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07003946 }
3947 }
3948
Evan Millar633a1742009-04-02 16:36:33 -07003949 public int getDischargeStartLevelLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003950 return mDischargeUnplugLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07003951 }
3952
3953 @Override
Evan Millar633a1742009-04-02 16:36:33 -07003954 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07003955 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07003956 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07003957 }
3958 }
3959
Evan Millar633a1742009-04-02 16:36:33 -07003960 public int getDischargeCurrentLevelLocked() {
3961 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07003962 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003963
Amith Yamasanie43530a2009-08-21 13:11:37 -07003964 @Override
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003965 public int getLowDischargeAmountSinceCharge() {
3966 synchronized(this) {
3967 return mLowDischargeAmountSinceCharge;
3968 }
3969 }
3970
3971 @Override
3972 public int getHighDischargeAmountSinceCharge() {
3973 synchronized(this) {
3974 return mHighDischargeAmountSinceCharge;
3975 }
3976 }
3977
3978 @Override
Amith Yamasanie43530a2009-08-21 13:11:37 -07003979 public int getCpuSpeedSteps() {
3980 return sNumSpeedSteps;
3981 }
3982
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003983 /**
3984 * Retrieve the statistics object for a particular uid, creating if needed.
3985 */
3986 public Uid getUidStatsLocked(int uid) {
3987 Uid u = mUidStats.get(uid);
3988 if (u == null) {
3989 u = new Uid(uid);
3990 mUidStats.put(uid, u);
3991 }
3992 return u;
3993 }
3994
3995 /**
3996 * Remove the statistics object for a particular uid.
3997 */
3998 public void removeUidStatsLocked(int uid) {
3999 mUidStats.remove(uid);
4000 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004001
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004002 /**
4003 * Retrieve the statistics object for a particular process, creating
4004 * if needed.
4005 */
4006 public Uid.Proc getProcessStatsLocked(int uid, String name) {
4007 Uid u = getUidStatsLocked(uid);
4008 return u.getProcessStatsLocked(name);
4009 }
4010
4011 /**
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004012 * Retrieve the statistics object for a particular process, given
4013 * the name of the process.
4014 * @param name process name
4015 * @return the statistics object for the process
4016 */
Amith Yamasani819f9282009-06-24 23:18:15 -07004017 public Uid.Proc getProcessStatsLocked(String name, int pid) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004018 int uid;
4019 if (mUidCache.containsKey(name)) {
4020 uid = mUidCache.get(name);
4021 } else {
Amith Yamasani819f9282009-06-24 23:18:15 -07004022 uid = Process.getUidForPid(pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004023 mUidCache.put(name, uid);
4024 }
4025 Uid u = getUidStatsLocked(uid);
4026 return u.getProcessStatsLocked(name);
4027 }
4028
4029 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004030 * Retrieve the statistics object for a particular process, creating
4031 * if needed.
4032 */
4033 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
4034 Uid u = getUidStatsLocked(uid);
4035 return u.getPackageStatsLocked(pkg);
4036 }
4037
4038 /**
4039 * Retrieve the statistics object for a particular service, creating
4040 * if needed.
4041 */
4042 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
4043 Uid u = getUidStatsLocked(uid);
4044 return u.getServiceStatsLocked(pkg, name);
4045 }
4046
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004047 public void shutdownLocked() {
4048 writeLocked();
4049 mShuttingDown = true;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004050 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004051
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004052 public void writeLocked() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004053 if (mFile == null) {
4054 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004055 return;
4056 }
4057
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004058 if (mShuttingDown) {
4059 return;
4060 }
4061
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004062 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004063 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004064 Parcel out = Parcel.obtain();
4065 writeSummaryToParcel(out);
4066 stream.write(out.marshall());
4067 out.recycle();
4068
4069 stream.flush();
4070 stream.close();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004071 mFile.commit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004072
4073 mLastWriteTime = SystemClock.elapsedRealtime();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07004074 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004075 } catch (IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004076 Slog.w("BatteryStats", "Error writing battery statistics", e);
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07004077 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004078 mFile.rollback();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004079 }
4080
4081 static byte[] readFully(FileInputStream stream) throws java.io.IOException {
4082 int pos = 0;
4083 int avail = stream.available();
4084 byte[] data = new byte[avail];
4085 while (true) {
4086 int amt = stream.read(data, pos, data.length-pos);
4087 //Log.i("foo", "Read " + amt + " bytes at " + pos
4088 // + " of avail " + data.length);
4089 if (amt <= 0) {
4090 //Log.i("foo", "**** FINISHED READING: pos=" + pos
4091 // + " len=" + data.length);
4092 return data;
4093 }
4094 pos += amt;
4095 avail = stream.available();
4096 if (avail > data.length-pos) {
4097 byte[] newData = new byte[pos+avail];
4098 System.arraycopy(data, 0, newData, 0, pos);
4099 data = newData;
4100 }
4101 }
4102 }
4103
4104 public void readLocked() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004105 if (mFile == null) {
4106 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004107 return;
4108 }
4109
4110 mUidStats.clear();
4111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004112 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004113 File file = mFile.chooseForRead();
4114 if (!file.exists()) {
4115 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004116 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004117 FileInputStream stream = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004118
4119 byte[] raw = readFully(stream);
4120 Parcel in = Parcel.obtain();
4121 in.unmarshall(raw, 0, raw.length);
4122 in.setDataPosition(0);
4123 stream.close();
4124
4125 readSummaryFromParcel(in);
4126 } catch(java.io.IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004127 Slog.e("BatteryStats", "Error reading battery statistics", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004128 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004129
4130 addHistoryRecordLocked(SystemClock.elapsedRealtime(), HistoryItem.CMD_START);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004131 }
4132
4133 public int describeContents() {
4134 return 0;
4135 }
4136
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004137 void readHistory(Parcel in) {
4138 mHistory = mHistoryEnd = mHistoryCache = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004139 mHistoryBaseTime = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004140 long time;
4141 while ((time=in.readLong()) >= 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004142 HistoryItem rec = new HistoryItem(time, in);
4143 addHistoryRecordLocked(rec);
4144 if (rec.time > mHistoryBaseTime) {
4145 mHistoryBaseTime = rec.time;
4146 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004147 }
Dianne Hackborn1e4b9f32010-06-23 14:10:57 -07004148
4149 long oldnow = SystemClock.elapsedRealtime() - (5*60*100);
4150 if (oldnow > 0) {
4151 // If the system process has restarted, but not the entire
4152 // system, then the mHistoryBaseTime already accounts for
4153 // much of the elapsed time. We thus want to adjust it back,
4154 // to avoid large gaps in the data. We determine we are
4155 // in this case by arbitrarily saying it is so if at this
4156 // point in boot the elapsed time is already more than 5 seconds.
4157 mHistoryBaseTime -= oldnow;
4158 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004159 }
4160
4161 void writeHistory(Parcel out) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004162 HistoryItem rec = mHistory;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004163 while (rec != null) {
4164 if (rec.time >= 0) rec.writeToParcel(out, 0);
4165 rec = rec.next;
4166 }
4167 out.writeLong(-1);
4168 }
4169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004170 private void readSummaryFromParcel(Parcel in) {
4171 final int version = in.readInt();
4172 if (version != VERSION) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004173 Slog.w("BatteryStats", "readFromParcel: version got " + version
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004174 + ", expected " + VERSION + "; erasing old stats");
4175 return;
4176 }
4177
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004178 readHistory(in);
4179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004180 mStartCount = in.readInt();
4181 mBatteryUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004182 mBatteryRealtime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004183 mUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004184 mRealtime = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004185 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07004186 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004187 mLowDischargeAmountSinceCharge = in.readInt();
4188 mHighDischargeAmountSinceCharge = in.readInt();
The Android Open Source Project10592532009-03-18 17:39:46 -07004189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004190 mStartCount++;
4191
4192 mScreenOn = false;
4193 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004194 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
4195 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
4196 }
4197 mInputEventCounter.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004198 mPhoneOn = false;
4199 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004200 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
4201 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
4202 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07004203 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004204 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
4205 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
4206 }
The Android Open Source Project10592532009-03-18 17:39:46 -07004207 mWifiOn = false;
4208 mWifiOnTimer.readSummaryFromParcelLocked(in);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07004209 mWifiRunning = false;
4210 mWifiRunningTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07004211 mBluetoothOn = false;
4212 mBluetoothOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004213
Evan Millarc64edde2009-04-18 12:26:32 -07004214 int NKW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004215 if (NKW > 10000) {
4216 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW);
4217 return;
4218 }
Evan Millarc64edde2009-04-18 12:26:32 -07004219 for (int ikw = 0; ikw < NKW; ikw++) {
4220 if (in.readInt() != 0) {
4221 String kwltName = in.readString();
4222 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
4223 }
4224 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004225
4226 sNumSpeedSteps = in.readInt();
4227
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004228 final int NU = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004229 if (NU > 10000) {
4230 Slog.w(TAG, "File corrupt: too many uids " + NU);
4231 return;
4232 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004233 for (int iu = 0; iu < NU; iu++) {
4234 int uid = in.readInt();
4235 Uid u = new Uid(uid);
4236 mUidStats.put(uid, u);
4237
Dianne Hackborn617f8772009-03-31 15:04:46 -07004238 u.mWifiTurnedOn = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004239 if (in.readInt() != 0) {
4240 u.mWifiTurnedOnTimer.readSummaryFromParcelLocked(in);
4241 }
The Android Open Source Project10592532009-03-18 17:39:46 -07004242 u.mFullWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004243 if (in.readInt() != 0) {
4244 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
4245 }
The Android Open Source Project10592532009-03-18 17:39:46 -07004246 u.mScanWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004247 if (in.readInt() != 0) {
4248 u.mScanWifiLockTimer.readSummaryFromParcelLocked(in);
4249 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004250 u.mWifiMulticastEnabled = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004251 if (in.readInt() != 0) {
4252 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
4253 }
4254 u.mAudioTurnedOn = false;
4255 if (in.readInt() != 0) {
4256 u.mAudioTurnedOnTimer.readSummaryFromParcelLocked(in);
4257 }
4258 u.mVideoTurnedOn = false;
4259 if (in.readInt() != 0) {
4260 u.mVideoTurnedOnTimer.readSummaryFromParcelLocked(in);
4261 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004262
Dianne Hackborn617f8772009-03-31 15:04:46 -07004263 if (in.readInt() != 0) {
4264 if (u.mUserActivityCounters == null) {
4265 u.initUserActivityLocked();
4266 }
4267 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
4268 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
4269 }
4270 }
4271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004272 int NW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004273 if (NW > 10000) {
4274 Slog.w(TAG, "File corrupt: too many wake locks " + NW);
4275 return;
4276 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004277 for (int iw = 0; iw < NW; iw++) {
4278 String wlName = in.readString();
4279 if (in.readInt() != 0) {
4280 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
4281 }
4282 if (in.readInt() != 0) {
4283 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
4284 }
4285 if (in.readInt() != 0) {
4286 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
4287 }
4288 }
4289
4290 int NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004291 if (NP > 10000) {
4292 Slog.w(TAG, "File corrupt: too many sensors " + NP);
4293 return;
4294 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004295 for (int is = 0; is < NP; is++) {
4296 int seNumber = in.readInt();
4297 if (in.readInt() != 0) {
4298 u.getSensorTimerLocked(seNumber, true)
4299 .readSummaryFromParcelLocked(in);
4300 }
4301 }
4302
4303 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004304 if (NP > 10000) {
4305 Slog.w(TAG, "File corrupt: too many processes " + NP);
4306 return;
4307 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004308 for (int ip = 0; ip < NP; ip++) {
4309 String procName = in.readString();
4310 Uid.Proc p = u.getProcessStatsLocked(procName);
4311 p.mUserTime = p.mLoadedUserTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004312 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004313 p.mStarts = p.mLoadedStarts = in.readInt();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004314 p.readExcessiveWakeFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004315 }
4316
4317 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07004318 if (NP > 10000) {
4319 Slog.w(TAG, "File corrupt: too many packages " + NP);
4320 return;
4321 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004322 for (int ip = 0; ip < NP; ip++) {
4323 String pkgName = in.readString();
4324 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
4325 p.mWakeups = p.mLoadedWakeups = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004326 final int NS = in.readInt();
4327 for (int is = 0; is < NS; is++) {
4328 String servName = in.readString();
4329 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
4330 s.mStartTime = s.mLoadedStartTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004331 s.mStarts = s.mLoadedStarts = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004332 s.mLaunches = s.mLoadedLaunches = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004333 }
4334 }
4335
4336 u.mLoadedTcpBytesReceived = in.readLong();
4337 u.mLoadedTcpBytesSent = in.readLong();
4338 }
4339 }
4340
4341 /**
4342 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
4343 * disk. This format does not allow a lossless round-trip.
4344 *
4345 * @param out the Parcel to be written to.
4346 */
4347 public void writeSummaryToParcel(Parcel out) {
4348 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
4349 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
4350 final long NOW = getBatteryUptimeLocked(NOW_SYS);
4351 final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS);
4352
4353 out.writeInt(VERSION);
4354
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004355 writeHistory(out);
4356
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004357 out.writeInt(mStartCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004358 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004359 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004360 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004361 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004362 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07004363 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004364 out.writeInt(mLowDischargeAmountSinceCharge);
4365 out.writeInt(mHighDischargeAmountSinceCharge);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004366
4367 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004368 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
4369 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
4370 }
4371 mInputEventCounter.writeSummaryFromParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004372 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004373 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
4374 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
4375 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07004376 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004377 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
4378 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
4379 }
The Android Open Source Project10592532009-03-18 17:39:46 -07004380 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07004381 mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07004382 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004383
Evan Millarc64edde2009-04-18 12:26:32 -07004384 out.writeInt(mKernelWakelockStats.size());
4385 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
4386 Timer kwlt = ent.getValue();
4387 if (kwlt != null) {
4388 out.writeInt(1);
4389 out.writeString(ent.getKey());
4390 ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL);
4391 } else {
4392 out.writeInt(0);
4393 }
4394 }
4395
Amith Yamasanie43530a2009-08-21 13:11:37 -07004396 out.writeInt(sNumSpeedSteps);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004397 final int NU = mUidStats.size();
4398 out.writeInt(NU);
4399 for (int iu = 0; iu < NU; iu++) {
4400 out.writeInt(mUidStats.keyAt(iu));
4401 Uid u = mUidStats.valueAt(iu);
The Android Open Source Project10592532009-03-18 17:39:46 -07004402
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004403 if (u.mWifiTurnedOnTimer != null) {
4404 out.writeInt(1);
4405 u.mWifiTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
4406 } else {
4407 out.writeInt(0);
4408 }
4409 if (u.mFullWifiLockTimer != null) {
4410 out.writeInt(1);
4411 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
4412 } else {
4413 out.writeInt(0);
4414 }
4415 if (u.mScanWifiLockTimer != null) {
4416 out.writeInt(1);
4417 u.mScanWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
4418 } else {
4419 out.writeInt(0);
4420 }
4421 if (u.mWifiMulticastTimer != null) {
4422 out.writeInt(1);
4423 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL);
4424 } else {
4425 out.writeInt(0);
4426 }
4427 if (u.mAudioTurnedOnTimer != null) {
4428 out.writeInt(1);
4429 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
4430 } else {
4431 out.writeInt(0);
4432 }
4433 if (u.mVideoTurnedOnTimer != null) {
4434 out.writeInt(1);
4435 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
4436 } else {
4437 out.writeInt(0);
4438 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004439
Dianne Hackborn617f8772009-03-31 15:04:46 -07004440 if (u.mUserActivityCounters == null) {
4441 out.writeInt(0);
4442 } else {
4443 out.writeInt(1);
4444 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
4445 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
4446 }
4447 }
4448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004449 int NW = u.mWakelockStats.size();
4450 out.writeInt(NW);
4451 if (NW > 0) {
4452 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent
4453 : u.mWakelockStats.entrySet()) {
4454 out.writeString(ent.getKey());
4455 Uid.Wakelock wl = ent.getValue();
4456 if (wl.mTimerFull != null) {
4457 out.writeInt(1);
4458 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL);
4459 } else {
4460 out.writeInt(0);
4461 }
4462 if (wl.mTimerPartial != null) {
4463 out.writeInt(1);
4464 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL);
4465 } else {
4466 out.writeInt(0);
4467 }
4468 if (wl.mTimerWindow != null) {
4469 out.writeInt(1);
4470 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL);
4471 } else {
4472 out.writeInt(0);
4473 }
4474 }
4475 }
4476
4477 int NSE = u.mSensorStats.size();
4478 out.writeInt(NSE);
4479 if (NSE > 0) {
4480 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent
4481 : u.mSensorStats.entrySet()) {
4482 out.writeInt(ent.getKey());
4483 Uid.Sensor se = ent.getValue();
4484 if (se.mTimer != null) {
4485 out.writeInt(1);
4486 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL);
4487 } else {
4488 out.writeInt(0);
4489 }
4490 }
4491 }
4492
4493 int NP = u.mProcessStats.size();
4494 out.writeInt(NP);
4495 if (NP > 0) {
4496 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent
4497 : u.mProcessStats.entrySet()) {
4498 out.writeString(ent.getKey());
4499 Uid.Proc ps = ent.getValue();
4500 out.writeLong(ps.mUserTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004501 out.writeLong(ps.mSystemTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004502 out.writeInt(ps.mStarts);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004503 ps.writeExcessiveWakeToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004504 }
4505 }
4506
4507 NP = u.mPackageStats.size();
4508 out.writeInt(NP);
4509 if (NP > 0) {
4510 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
4511 : u.mPackageStats.entrySet()) {
4512 out.writeString(ent.getKey());
4513 Uid.Pkg ps = ent.getValue();
4514 out.writeInt(ps.mWakeups);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004515 final int NS = ps.mServiceStats.size();
4516 out.writeInt(NS);
4517 if (NS > 0) {
4518 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
4519 : ps.mServiceStats.entrySet()) {
4520 out.writeString(sent.getKey());
4521 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
4522 long time = ss.getStartTimeToNowLocked(NOW);
4523 out.writeLong(time);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004524 out.writeInt(ss.mStarts);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004525 out.writeInt(ss.mLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004526 }
4527 }
4528 }
4529 }
4530
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004531 out.writeLong(u.getTcpBytesReceived(STATS_SINCE_CHARGED));
4532 out.writeLong(u.getTcpBytesSent(STATS_SINCE_CHARGED));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004533 }
4534 }
4535
4536 public void readFromParcel(Parcel in) {
4537 readFromParcelLocked(in);
4538 }
4539
4540 void readFromParcelLocked(Parcel in) {
4541 int magic = in.readInt();
4542 if (magic != MAGIC) {
4543 throw new ParcelFormatException("Bad magic number");
4544 }
4545
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004546 readHistory(in);
4547
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004548 mStartCount = in.readInt();
4549 mBatteryUptime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004550 mBatteryLastUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004551 mBatteryRealtime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004552 mBatteryLastRealtime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004553 mScreenOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07004554 mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004555 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07004556 mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004557 }
4558 mInputEventCounter = new Counter(mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004559 mPhoneOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07004560 mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004561 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07004562 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004563 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07004564 mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004565 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07004566 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004567 }
The Android Open Source Project10592532009-03-18 17:39:46 -07004568 mWifiOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07004569 mWifiOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07004570 mWifiRunning = false;
Evan Millarc64edde2009-04-18 12:26:32 -07004571 mWifiRunningTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07004572 mBluetoothOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07004573 mBluetoothOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004574 mUptime = in.readLong();
4575 mUptimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004576 mLastUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004577 mRealtime = in.readLong();
4578 mRealtimeStart = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004579 mLastRealtime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004580 mOnBattery = in.readInt() != 0;
4581 mOnBatteryInternal = false; // we are no longer really running.
4582 mTrackBatteryPastUptime = in.readLong();
4583 mTrackBatteryUptimeStart = in.readLong();
4584 mTrackBatteryPastRealtime = in.readLong();
4585 mTrackBatteryRealtimeStart = in.readLong();
4586 mUnpluggedBatteryUptime = in.readLong();
4587 mUnpluggedBatteryRealtime = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004588 mDischargeUnplugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07004589 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004590 mLowDischargeAmountSinceCharge = in.readInt();
4591 mHighDischargeAmountSinceCharge = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004592 mLastWriteTime = in.readLong();
4593
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004594 mMobileDataRx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004595 mMobileDataRx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004596 mMobileDataTx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004597 mMobileDataTx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004598 mTotalDataRx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004599 mTotalDataRx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004600 mTotalDataTx[STATS_LAST] = in.readLong();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004601 mTotalDataTx[STATS_SINCE_UNPLUGGED] = -1;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004602
4603 mRadioDataUptime = in.readLong();
4604 mRadioDataStart = -1;
4605
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07004606 mBluetoothPingCount = in.readInt();
4607 mBluetoothPingStart = -1;
4608
Evan Millarc64edde2009-04-18 12:26:32 -07004609 mKernelWakelockStats.clear();
4610 int NKW = in.readInt();
4611 for (int ikw = 0; ikw < NKW; ikw++) {
4612 if (in.readInt() != 0) {
4613 String wakelockName = in.readString();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004614 in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel
Evan Millarc64edde2009-04-18 12:26:32 -07004615 SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in);
4616 mKernelWakelockStats.put(wakelockName, kwlt);
4617 }
4618 }
4619
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004620 mPartialTimers.clear();
4621 mFullTimers.clear();
4622 mWindowTimers.clear();
4623
Amith Yamasanie43530a2009-08-21 13:11:37 -07004624 sNumSpeedSteps = in.readInt();
4625
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004626 int numUids = in.readInt();
4627 mUidStats.clear();
4628 for (int i = 0; i < numUids; i++) {
4629 int uid = in.readInt();
4630 Uid u = new Uid(uid);
4631 u.readFromParcelLocked(mUnpluggables, in);
4632 mUidStats.append(uid, u);
4633 }
4634 }
4635
4636 public void writeToParcel(Parcel out, int flags) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004637 writeToParcelLocked(out, true, flags);
4638 }
4639
4640 public void writeToParcelWithoutUids(Parcel out, int flags) {
4641 writeToParcelLocked(out, false, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004642 }
4643
4644 @SuppressWarnings("unused")
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004645 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004646 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
4647 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
4648 final long batteryUptime = getBatteryUptimeLocked(uSecUptime);
4649 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
4650
4651 out.writeInt(MAGIC);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004652
4653 writeHistory(out);
4654
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004655 out.writeInt(mStartCount);
4656 out.writeLong(mBatteryUptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004657 out.writeLong(mBatteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004658 mScreenOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004659 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
4660 mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime);
4661 }
4662 mInputEventCounter.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004663 mPhoneOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004664 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
4665 mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
4666 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07004667 mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004668 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
4669 mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime);
4670 }
The Android Open Source Project10592532009-03-18 17:39:46 -07004671 mWifiOnTimer.writeToParcel(out, batteryRealtime);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07004672 mWifiRunningTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07004673 mBluetoothOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004674 out.writeLong(mUptime);
4675 out.writeLong(mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004676 out.writeLong(mRealtime);
4677 out.writeLong(mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004678 out.writeInt(mOnBattery ? 1 : 0);
4679 out.writeLong(batteryUptime);
4680 out.writeLong(mTrackBatteryUptimeStart);
4681 out.writeLong(batteryRealtime);
4682 out.writeLong(mTrackBatteryRealtimeStart);
4683 out.writeLong(mUnpluggedBatteryUptime);
4684 out.writeLong(mUnpluggedBatteryRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004685 out.writeInt(mDischargeUnplugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07004686 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004687 out.writeInt(mLowDischargeAmountSinceCharge);
4688 out.writeInt(mHighDischargeAmountSinceCharge);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004689 out.writeLong(mLastWriteTime);
4690
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004691 out.writeLong(getMobileTcpBytesReceived(STATS_SINCE_UNPLUGGED));
4692 out.writeLong(getMobileTcpBytesSent(STATS_SINCE_UNPLUGGED));
4693 out.writeLong(getTotalTcpBytesReceived(STATS_SINCE_UNPLUGGED));
4694 out.writeLong(getTotalTcpBytesSent(STATS_SINCE_UNPLUGGED));
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004695
4696 // Write radio uptime for data
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07004697 out.writeLong(getRadioDataUptime());
4698
4699 out.writeInt(getBluetoothPingCount());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004700
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004701 if (inclUids) {
4702 out.writeInt(mKernelWakelockStats.size());
4703 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
4704 SamplingTimer kwlt = ent.getValue();
4705 if (kwlt != null) {
4706 out.writeInt(1);
4707 out.writeString(ent.getKey());
4708 Timer.writeTimerToParcel(out, kwlt, batteryRealtime);
4709 } else {
4710 out.writeInt(0);
4711 }
Evan Millarc64edde2009-04-18 12:26:32 -07004712 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004713 } else {
4714 out.writeInt(0);
Evan Millarc64edde2009-04-18 12:26:32 -07004715 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07004716
4717 out.writeInt(sNumSpeedSteps);
4718
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004719 if (inclUids) {
4720 int size = mUidStats.size();
4721 out.writeInt(size);
4722 for (int i = 0; i < size; i++) {
4723 out.writeInt(mUidStats.keyAt(i));
4724 Uid uid = mUidStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004725
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004726 uid.writeToParcelLocked(out, batteryRealtime);
4727 }
4728 } else {
4729 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004730 }
4731 }
4732
4733 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
4734 new Parcelable.Creator<BatteryStatsImpl>() {
4735 public BatteryStatsImpl createFromParcel(Parcel in) {
4736 return new BatteryStatsImpl(in);
4737 }
4738
4739 public BatteryStatsImpl[] newArray(int size) {
4740 return new BatteryStatsImpl[size];
4741 }
4742 };
4743
Dianne Hackborn1d442e02009-04-20 18:14:05 -07004744 public void dumpLocked(PrintWriter pw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004745 if (DEBUG) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07004746 Printer pr = new PrintWriterPrinter(pw);
4747 pr.println("*** Screen timer:");
4748 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07004749 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07004750 pr.println("*** Screen brightness #" + i + ":");
4751 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07004752 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07004753 pr.println("*** Input event counter:");
4754 mInputEventCounter.logState(pr, " ");
4755 pr.println("*** Phone timer:");
4756 mPhoneOnTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07004757 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07004758 pr.println("*** Signal strength #" + i + ":");
4759 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07004760 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07004761 pr.println("*** Signal scanning :");
4762 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07004763 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07004764 pr.println("*** Data connection type #" + i + ":");
4765 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07004766 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07004767 pr.println("*** Wifi timer:");
4768 mWifiOnTimer.logState(pr, " ");
4769 pr.println("*** WifiRunning timer:");
4770 mWifiRunningTimer.logState(pr, " ");
4771 pr.println("*** Bluetooth timer:");
4772 mBluetoothOnTimer.logState(pr, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004773 }
4774 super.dumpLocked(pw);
4775 }
4776}