blob: 71ccb3b1cba37e50ff0ac951a41f60af55929df1 [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
Amith Yamasani3f7e35c2009-07-13 16:02:45 -070019import android.bluetooth.BluetoothHeadset;
Ken Shirriff1719a392009-12-07 15:57:35 -080020import android.net.TrafficStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import android.os.BatteryStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.os.Parcel;
23import android.os.ParcelFormatException;
24import android.os.Parcelable;
Evan Millarc64edde2009-04-18 12:26:32 -070025import android.os.Process;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import android.os.SystemClock;
Amith Yamasanif37447b2009-10-08 18:28:01 -070027import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070028import android.telephony.SignalStrength;
Dianne Hackborn627bba72009-03-24 22:32:56 -070029import android.telephony.TelephonyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.util.Log;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070031import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.util.Printer;
33import android.util.SparseArray;
34
Amith Yamasani3718aaa2009-06-09 06:32:35 -070035import java.io.BufferedReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import java.io.File;
37import java.io.FileInputStream;
38import java.io.FileOutputStream;
Amith Yamasani3718aaa2009-06-09 06:32:35 -070039import java.io.FileReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070041import java.io.PrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import java.util.ArrayList;
43import java.util.HashMap;
Evan Millarc64edde2009-04-18 12:26:32 -070044import java.util.Iterator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import java.util.Map;
46
47/**
48 * All information we are collecting about things that can happen that impact
49 * battery life. All times are represented in microseconds except where indicated
50 * otherwise.
51 */
52public final class BatteryStatsImpl extends BatteryStats {
53 private static final String TAG = "BatteryStatsImpl";
54 private static final boolean DEBUG = false;
55
56 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
57 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
58
59 // Current on-disk Parcel version
Amith Yamasanicfc893d2009-11-18 10:39:14 -080060 private static final int VERSION = 42;
Amith Yamasanie43530a2009-08-21 13:11:37 -070061
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -080062 // The maximum number of names wakelocks we will keep track of
63 // per uid; once the limit is reached, we batch the remaining wakelocks
64 // in to one common name.
65 private static final int MAX_WAKELOCKS_PER_UID = 20;
66
67 private static final String BATCHED_WAKELOCK_NAME = "*overflow*";
68
Amith Yamasanie43530a2009-08-21 13:11:37 -070069 private static int sNumSpeedSteps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070
71 private final File mFile;
72 private final File mBackupFile;
73
74 /**
75 * The statistics we have collected organized by uids.
76 */
77 final SparseArray<BatteryStatsImpl.Uid> mUidStats =
78 new SparseArray<BatteryStatsImpl.Uid>();
79
80 // A set of pools of currently active timers. When a timer is queried, we will divide the
81 // elapsed time by the number of active timers to arrive at that timer's share of the time.
82 // In order to do this, we must refresh each timer whenever the number of active timers
83 // changes.
Evan Millarc64edde2009-04-18 12:26:32 -070084 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>();
85 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>();
86 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>();
87 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers
88 = new SparseArray<ArrayList<StopwatchTimer>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089
90 // These are the objects that will want to do something when the device
91 // is unplugged from power.
92 final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>();
93
94 int mStartCount;
95
96 long mBatteryUptime;
97 long mBatteryLastUptime;
98 long mBatteryRealtime;
99 long mBatteryLastRealtime;
100
101 long mUptime;
102 long mUptimeStart;
103 long mLastUptime;
104 long mRealtime;
105 long mRealtimeStart;
106 long mLastRealtime;
107
108 boolean mScreenOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700109 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700110
Dianne Hackborn617f8772009-03-31 15:04:46 -0700111 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700112 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Dianne Hackborn617f8772009-03-31 15:04:46 -0700113
114 Counter mInputEventCounter;
115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700117 StopwatchTimer mPhoneOnTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700119 boolean mAudioOn;
120 StopwatchTimer mAudioOnTimer;
121
122 boolean mVideoOn;
123 StopwatchTimer mVideoOnTimer;
124
Dianne Hackborn627bba72009-03-24 22:32:56 -0700125 int mPhoneSignalStrengthBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700126 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
127 new StopwatchTimer[NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700128
129 StopwatchTimer mPhoneSignalScanningTimer;
130
Dianne Hackborn627bba72009-03-24 22:32:56 -0700131 int mPhoneDataConnectionType = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700132 final StopwatchTimer[] mPhoneDataConnectionsTimer =
133 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Dianne Hackborn627bba72009-03-24 22:32:56 -0700134
The Android Open Source Project10592532009-03-18 17:39:46 -0700135 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700136 StopwatchTimer mWifiOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700137 int mWifiOnUid = -1;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700138
139 boolean mWifiRunning;
Evan Millarc64edde2009-04-18 12:26:32 -0700140 StopwatchTimer mWifiRunningTimer;
The Android Open Source Project10592532009-03-18 17:39:46 -0700141
142 boolean mBluetoothOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700143 StopwatchTimer mBluetoothOnTimer;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700144
145 /** Bluetooth headset object */
146 BluetoothHeadset mBtHeadset;
147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148 /**
149 * These provide time bases that discount the time the device is plugged
150 * in to power.
151 */
152 boolean mOnBattery;
153 boolean mOnBatteryInternal;
154 long mTrackBatteryPastUptime;
155 long mTrackBatteryUptimeStart;
156 long mTrackBatteryPastRealtime;
157 long mTrackBatteryRealtimeStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700158
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 long mUnpluggedBatteryUptime;
160 long mUnpluggedBatteryRealtime;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700161
The Android Open Source Project10592532009-03-18 17:39:46 -0700162 /*
163 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
164 */
Evan Millar633a1742009-04-02 16:36:33 -0700165 int mDischargeStartLevel;
166 int mDischargeCurrentLevel;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700169
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700170 // Mobile data transferred while on battery
171 private long[] mMobileDataTx = new long[4];
172 private long[] mMobileDataRx = new long[4];
173 private long[] mTotalDataTx = new long[4];
174 private long[] mTotalDataRx = new long[4];
175
176 private long mRadioDataUptime;
177 private long mRadioDataStart;
178
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700179 private int mBluetoothPingCount;
180 private int mBluetoothPingStart = -1;
181
Amith Yamasanif37447b2009-10-08 18:28:01 -0700182 private int mPhoneServiceState = -1;
183
Evan Millarc64edde2009-04-18 12:26:32 -0700184 /*
185 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
186 */
187 private final HashMap<String, SamplingTimer> mKernelWakelockStats =
188 new HashMap<String, SamplingTimer>();
189
190 public Map<String, ? extends SamplingTimer> getKernelWakelockStats() {
191 return mKernelWakelockStats;
192 }
193
194 private static int sKernelWakelockUpdateVersion = 0;
195
196 private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
197 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name
198 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count
199 Process.PROC_TAB_TERM,
200 Process.PROC_TAB_TERM,
201 Process.PROC_TAB_TERM,
202 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime
203 };
204
205 private final String[] mProcWakelocksName = new String[3];
206 private final long[] mProcWakelocksData = new long[3];
207
208 /*
209 * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added
210 * to mKernelWakelockStats.
211 */
212 private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
213 new HashMap<String, KernelWakelockStats>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700215 private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>();
216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217 // For debugging
218 public BatteryStatsImpl() {
219 mFile = mBackupFile = null;
220 }
221
222 public static interface Unpluggable {
223 void unplug(long batteryUptime, long batteryRealtime);
224 void plug(long batteryUptime, long batteryRealtime);
225 }
226
227 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700228 * State for keeping track of counting information.
229 */
Amith Yamasanie43530a2009-08-21 13:11:37 -0700230 public static class Counter extends BatteryStats.Counter implements Unpluggable {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700231 int mCount;
232 int mLoadedCount;
233 int mLastCount;
234 int mUnpluggedCount;
235 int mPluggedCount;
236
237 Counter(ArrayList<Unpluggable> unpluggables, Parcel in) {
238 mPluggedCount = mCount = in.readInt();
239 mLoadedCount = in.readInt();
240 mLastCount = in.readInt();
241 mUnpluggedCount = in.readInt();
242 unpluggables.add(this);
243 }
244
245 Counter(ArrayList<Unpluggable> unpluggables) {
246 unpluggables.add(this);
247 }
248
249 public void writeToParcel(Parcel out) {
250 out.writeInt(mCount);
251 out.writeInt(mLoadedCount);
252 out.writeInt(mLastCount);
253 out.writeInt(mUnpluggedCount);
254 }
255
256 public void unplug(long batteryUptime, long batteryRealtime) {
257 mUnpluggedCount = mCount = mPluggedCount;
258 }
259
260 public void plug(long batteryUptime, long batteryRealtime) {
261 mPluggedCount = mCount;
262 }
263
264 /**
265 * Writes a possibly null Counter to a Parcel.
266 *
267 * @param out the Parcel to be written to.
268 * @param counter a Counter, or null.
269 */
270 public static void writeCounterToParcel(Parcel out, Counter counter) {
271 if (counter == null) {
272 out.writeInt(0); // indicates null
273 return;
274 }
275 out.writeInt(1); // indicates non-null
276
277 counter.writeToParcel(out);
278 }
279
280 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700281 public int getCountLocked(int which) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700282 int val;
283 if (which == STATS_LAST) {
284 val = mLastCount;
285 } else {
286 val = mCount;
287 if (which == STATS_UNPLUGGED) {
288 val -= mUnpluggedCount;
289 } else if (which != STATS_TOTAL) {
290 val -= mLoadedCount;
291 }
292 }
293
294 return val;
295 }
296
297 public void logState(Printer pw, String prefix) {
298 pw.println(prefix + "mCount=" + mCount
299 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
300 + " mUnpluggedCount=" + mUnpluggedCount
301 + " mPluggedCount=" + mPluggedCount);
302 }
303
304 void stepLocked() {
305 mCount++;
306 }
307
308 void writeSummaryFromParcelLocked(Parcel out) {
309 out.writeInt(mCount);
310 out.writeInt(mCount - mLoadedCount);
311 }
312
313 void readSummaryFromParcelLocked(Parcel in) {
314 mCount = mLoadedCount = in.readInt();
315 mLastCount = in.readInt();
316 mUnpluggedCount = mPluggedCount = mCount;
317 }
318 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700319
320 public static class SamplingCounter extends Counter {
321
322 SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
323 super(unpluggables, in);
324 }
325
326 SamplingCounter(ArrayList<Unpluggable> unpluggables) {
327 super(unpluggables);
328 }
329
330 public void addCountLocked(long count) {
331 mCount += count;
332 }
333 }
334
Dianne Hackborn617f8772009-03-31 15:04:46 -0700335 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 * State for keeping track of timing information.
337 */
Evan Millarc64edde2009-04-18 12:26:32 -0700338 public static abstract class Timer extends BatteryStats.Timer implements Unpluggable {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339 final int mType;
Evan Millarc64edde2009-04-18 12:26:32 -0700340
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341
342 int mCount;
343 int mLoadedCount;
344 int mLastCount;
345 int mUnpluggedCount;
346
347 // Times are in microseconds for better accuracy when dividing by the
348 // lock count, and are in "battery realtime" units.
349
350 /**
351 * The total time we have accumulated since the start of the original
352 * boot, to the last time something interesting happened in the
353 * current run.
354 */
355 long mTotalTime;
356
357 /**
358 * The total time we loaded for the previous runs. Subtract this from
359 * mTotalTime to find the time for the current run of the system.
360 */
361 long mLoadedTime;
362
363 /**
364 * The run time of the last run of the system, as loaded from the
365 * saved data.
366 */
367 long mLastTime;
368
369 /**
370 * The value of mTotalTime when unplug() was last called. Subtract
371 * this from mTotalTime to find the time since the last unplug from
372 * power.
373 */
374 long mUnpluggedTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800375
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700376 /**
377 * Constructs from a parcel.
378 * @param type
379 * @param unpluggables
380 * @param powerType
381 * @param in
382 */
Evan Millarc64edde2009-04-18 12:26:32 -0700383 Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384 mType = type;
Evan Millarc64edde2009-04-18 12:26:32 -0700385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 mCount = in.readInt();
387 mLoadedCount = in.readInt();
388 mLastCount = in.readInt();
389 mUnpluggedCount = in.readInt();
390 mTotalTime = in.readLong();
391 mLoadedTime = in.readLong();
392 mLastTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 mUnpluggedTime = in.readLong();
394 unpluggables.add(this);
395 }
396
Evan Millarc64edde2009-04-18 12:26:32 -0700397 Timer(int type, ArrayList<Unpluggable> unpluggables) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 mType = type;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 unpluggables.add(this);
400 }
Evan Millarc64edde2009-04-18 12:26:32 -0700401
402 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
403
404 protected abstract int computeCurrentCountLocked();
405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800406
407 public void writeToParcel(Parcel out, long batteryRealtime) {
408 out.writeInt(mCount);
409 out.writeInt(mLoadedCount);
410 out.writeInt(mLastCount);
411 out.writeInt(mUnpluggedCount);
412 out.writeLong(computeRunTimeLocked(batteryRealtime));
413 out.writeLong(mLoadedTime);
414 out.writeLong(mLastTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 out.writeLong(mUnpluggedTime);
416 }
417
418 public void unplug(long batteryUptime, long batteryRealtime) {
419 if (DEBUG && mType < 0) {
420 Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime
421 + " old mUnpluggedTime=" + mUnpluggedTime
422 + " old mUnpluggedCount=" + mUnpluggedCount);
423 }
424 mUnpluggedTime = computeRunTimeLocked(batteryRealtime);
425 mUnpluggedCount = mCount;
426 if (DEBUG && mType < 0) {
427 Log.v(TAG, "unplug #" + mType
428 + ": new mUnpluggedTime=" + mUnpluggedTime
429 + " new mUnpluggedCount=" + mUnpluggedCount);
430 }
431 }
432
433 public void plug(long batteryUptime, long batteryRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -0700434 if (DEBUG && mType < 0) {
435 Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime
436 + " old mTotalTime=" + mTotalTime);
437 }
438 mTotalTime = computeRunTimeLocked(batteryRealtime);
439 mCount = computeCurrentCountLocked();
440 if (DEBUG && mType < 0) {
441 Log.v(TAG, "plug #" + mType
442 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443 }
444 }
445
446 /**
447 * Writes a possibly null Timer to a Parcel.
448 *
449 * @param out the Parcel to be written to.
450 * @param timer a Timer, or null.
451 */
452 public static void writeTimerToParcel(Parcel out, Timer timer,
453 long batteryRealtime) {
454 if (timer == null) {
455 out.writeInt(0); // indicates null
456 return;
457 }
458 out.writeInt(1); // indicates non-null
459
460 timer.writeToParcel(out, batteryRealtime);
461 }
462
463 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700464 public long getTotalTimeLocked(long batteryRealtime, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 long val;
466 if (which == STATS_LAST) {
467 val = mLastTime;
468 } else {
469 val = computeRunTimeLocked(batteryRealtime);
470 if (which == STATS_UNPLUGGED) {
471 val -= mUnpluggedTime;
472 } else if (which != STATS_TOTAL) {
473 val -= mLoadedTime;
474 }
475 }
476
477 return val;
478 }
479
480 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700481 public int getCountLocked(int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800482 int val;
483 if (which == STATS_LAST) {
484 val = mLastCount;
485 } else {
Evan Millarc64edde2009-04-18 12:26:32 -0700486 val = computeCurrentCountLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800487 if (which == STATS_UNPLUGGED) {
488 val -= mUnpluggedCount;
489 } else if (which != STATS_TOTAL) {
490 val -= mLoadedCount;
491 }
492 }
493
494 return val;
495 }
496
Dianne Hackborn627bba72009-03-24 22:32:56 -0700497 public void logState(Printer pw, String prefix) {
Evan Millarc64edde2009-04-18 12:26:32 -0700498 pw.println(prefix + " mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800499 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
500 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700501 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700503 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -0700505 }
506
507
508 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
509 long runTime = computeRunTimeLocked(batteryRealtime);
510 // Divide by 1000 for backwards compatibility
511 out.writeLong((runTime + 500) / 1000);
512 out.writeLong(((runTime - mLoadedTime) + 500) / 1000);
513 out.writeInt(mCount);
514 out.writeInt(mCount - mLoadedCount);
515 }
516
517 void readSummaryFromParcelLocked(Parcel in) {
518 // Multiply by 1000 for backwards compatibility
519 mTotalTime = mLoadedTime = in.readLong() * 1000;
520 mLastTime = in.readLong() * 1000;
521 mUnpluggedTime = mTotalTime;
522 mCount = mLoadedCount = in.readInt();
523 mLastCount = in.readInt();
524 mUnpluggedCount = mCount;
525 }
526 }
527
528 public static final class SamplingTimer extends Timer {
529
530 /**
531 * The most recent reported count from /proc/wakelocks.
532 */
533 int mCurrentReportedCount;
534
535 /**
536 * The reported count from /proc/wakelocks when unplug() was last
537 * called.
538 */
539 int mUnpluggedReportedCount;
540
541 /**
542 * The most recent reported total_time from /proc/wakelocks.
543 */
544 long mCurrentReportedTotalTime;
545
546
547 /**
548 * The reported total_time from /proc/wakelocks when unplug() was last
549 * called.
550 */
551 long mUnpluggedReportedTotalTime;
552
553 /**
554 * Whether we are currently in a discharge cycle.
555 */
556 boolean mInDischarge;
557
558 /**
559 * Whether we are currently recording reported values.
560 */
561 boolean mTrackingReportedValues;
562
563 /*
564 * A sequnce counter, incremented once for each update of the stats.
565 */
566 int mUpdateVersion;
567
568 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) {
569 super(0, unpluggables, in);
570 mCurrentReportedCount = in.readInt();
571 mUnpluggedReportedCount = in.readInt();
572 mCurrentReportedTotalTime = in.readLong();
573 mUnpluggedReportedTotalTime = in.readLong();
574 mTrackingReportedValues = in.readInt() == 1;
575 mInDischarge = inDischarge;
576 }
577
578 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge,
579 boolean trackReportedValues) {
580 super(0, unpluggables);
581 mTrackingReportedValues = trackReportedValues;
582 mInDischarge = inDischarge;
583 }
584
585 public void setStale() {
586 mTrackingReportedValues = false;
587 mUnpluggedReportedTotalTime = 0;
588 mUnpluggedReportedCount = 0;
589 }
590
591 public void setUpdateVersion(int version) {
592 mUpdateVersion = version;
593 }
594
595 public int getUpdateVersion() {
596 return mUpdateVersion;
597 }
598
599 public void updateCurrentReportedCount(int count) {
600 if (mInDischarge && mUnpluggedReportedCount == 0) {
601 // Updating the reported value for the first time.
602 mUnpluggedReportedCount = count;
603 // If we are receiving an update update mTrackingReportedValues;
604 mTrackingReportedValues = true;
605 }
606 mCurrentReportedCount = count;
607 }
608
609 public void updateCurrentReportedTotalTime(long totalTime) {
610 if (mInDischarge && mUnpluggedReportedTotalTime == 0) {
611 // Updating the reported value for the first time.
612 mUnpluggedReportedTotalTime = totalTime;
613 // If we are receiving an update update mTrackingReportedValues;
614 mTrackingReportedValues = true;
615 }
616 mCurrentReportedTotalTime = totalTime;
617 }
618
619 public void unplug(long batteryUptime, long batteryRealtime) {
620 super.unplug(batteryUptime, batteryRealtime);
621 if (mTrackingReportedValues) {
622 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
623 mUnpluggedReportedCount = mCurrentReportedCount;
624 }
625 mInDischarge = true;
626 }
627
628 public void plug(long batteryUptime, long batteryRealtime) {
629 super.plug(batteryUptime, batteryRealtime);
630 mInDischarge = false;
631 }
632
633 public void logState(Printer pw, String prefix) {
634 super.logState(pw, prefix);
635 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
636 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
637 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
638 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
639 }
640
641 protected long computeRunTimeLocked(long curBatteryRealtime) {
642 return mTotalTime + (mInDischarge && mTrackingReportedValues
643 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
644 }
645
646 protected int computeCurrentCountLocked() {
647 return mCount + (mInDischarge && mTrackingReportedValues
648 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
649 }
650
651 public void writeToParcel(Parcel out, long batteryRealtime) {
652 super.writeToParcel(out, batteryRealtime);
653 out.writeInt(mCurrentReportedCount);
654 out.writeInt(mUnpluggedReportedCount);
655 out.writeLong(mCurrentReportedTotalTime);
656 out.writeLong(mUnpluggedReportedTotalTime);
657 out.writeInt(mTrackingReportedValues ? 1 : 0);
658 }
659
660 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
661 super.writeSummaryFromParcelLocked(out, batteryRealtime);
662 out.writeLong(mCurrentReportedTotalTime);
663 out.writeInt(mCurrentReportedCount);
664 out.writeInt(mTrackingReportedValues ? 1 : 0);
665 }
666
667 void readSummaryFromParcelLocked(Parcel in) {
668 super.readSummaryFromParcelLocked(in);
669 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
670 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
671 mTrackingReportedValues = in.readInt() == 1;
672 }
673 }
674
675 /**
676 * State for keeping track of timing information.
677 */
678 public static final class StopwatchTimer extends Timer {
679 final ArrayList<StopwatchTimer> mTimerPool;
680 int mNesting;
681
682
683 /**
684 * The last time at which we updated the timer. If mNesting is > 0,
685 * subtract this from the current battery time to find the amount of
686 * time we have been running since we last computed an update.
687 */
688 long mUpdateTime;
689
690 /**
691 * The total time at which the timer was acquired, to determine if
692 * was actually held for an interesting duration.
693 */
694 long mAcquireTime;
Evan Millarc64edde2009-04-18 12:26:32 -0700695
Amith Yamasanif37447b2009-10-08 18:28:01 -0700696 long mTimeout;
697
Evan Millarc64edde2009-04-18 12:26:32 -0700698 StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool,
699 ArrayList<Unpluggable> unpluggables, Parcel in) {
700 super(type, unpluggables, in);
701 mTimerPool = timerPool;
702 mUpdateTime = in.readLong();
703 }
704
705 StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool,
706 ArrayList<Unpluggable> unpluggables) {
707 super(type, unpluggables);
708 mTimerPool = timerPool;
709 }
710
Amith Yamasanif37447b2009-10-08 18:28:01 -0700711 void setTimeout(long timeout) {
712 mTimeout = timeout;
713 }
714
Evan Millarc64edde2009-04-18 12:26:32 -0700715 public void writeToParcel(Parcel out, long batteryRealtime) {
716 super.writeToParcel(out, batteryRealtime);
717 out.writeLong(mUpdateTime);
718 }
719
720 public void plug(long batteryUptime, long batteryRealtime) {
721 if (mNesting > 0) {
722 if (DEBUG && mType < 0) {
723 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
724 }
725 super.plug(batteryUptime, batteryRealtime);
726 mUpdateTime = batteryRealtime;
727 if (DEBUG && mType < 0) {
728 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
729 }
730 }
731 }
732
733 public void logState(Printer pw, String prefix) {
734 super.logState(pw, prefix);
735 pw.println(prefix + "mNesting=" + mNesting + "mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800736 + " mAcquireTime=" + mAcquireTime);
737 }
738
739 void startRunningLocked(BatteryStatsImpl stats) {
740 if (mNesting++ == 0) {
741 mUpdateTime = stats.getBatteryRealtimeLocked(
742 SystemClock.elapsedRealtime() * 1000);
743 if (mTimerPool != null) {
744 // Accumulate time to all currently active timers before adding
745 // this new one to the pool.
746 refreshTimersLocked(stats, mTimerPool);
747 // Add this timer to the active pool
748 mTimerPool.add(this);
749 }
750 // Increment the count
751 mCount++;
752 mAcquireTime = mTotalTime;
753 if (DEBUG && mType < 0) {
754 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
755 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
756 + " mAcquireTime=" + mAcquireTime);
757 }
758 }
759 }
760
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700761 boolean isRunningLocked() {
762 return mNesting > 0;
763 }
764
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800765 void stopRunningLocked(BatteryStatsImpl stats) {
766 // Ignore attempt to stop a timer that isn't running
767 if (mNesting == 0) {
768 return;
769 }
770 if (--mNesting == 0) {
771 if (mTimerPool != null) {
772 // Accumulate time to all active counters, scaled by the total
773 // active in the pool, before taking this one out of the pool.
774 refreshTimersLocked(stats, mTimerPool);
775 // Remove this timer from the active pool
776 mTimerPool.remove(this);
777 } else {
778 final long realtime = SystemClock.elapsedRealtime() * 1000;
779 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
780 mNesting = 1;
781 mTotalTime = computeRunTimeLocked(batteryRealtime);
782 mNesting = 0;
783 }
784
785 if (DEBUG && mType < 0) {
786 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
787 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
788 + " mAcquireTime=" + mAcquireTime);
789 }
790
791 if (mTotalTime == mAcquireTime) {
792 // If there was no change in the time, then discard this
793 // count. A somewhat cheezy strategy, but hey.
794 mCount--;
795 }
796 }
797 }
798
799 // Update the total time for all other running Timers with the same type as this Timer
800 // due to a change in timer count
801 private static void refreshTimersLocked(final BatteryStatsImpl stats,
Evan Millarc64edde2009-04-18 12:26:32 -0700802 final ArrayList<StopwatchTimer> pool) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800803 final long realtime = SystemClock.elapsedRealtime() * 1000;
804 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
805 final int N = pool.size();
806 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -0700807 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800808 long heldTime = batteryRealtime - t.mUpdateTime;
809 if (heldTime > 0) {
810 t.mTotalTime += heldTime / N;
811 }
812 t.mUpdateTime = batteryRealtime;
813 }
814 }
815
Evan Millarc64edde2009-04-18 12:26:32 -0700816 @Override
817 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -0700818 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
819 curBatteryRealtime = mUpdateTime + mTimeout;
820 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800821 return mTotalTime + (mNesting > 0
822 ? (curBatteryRealtime - mUpdateTime)
823 / (mTimerPool != null ? mTimerPool.size() : 1)
824 : 0);
825 }
826
Evan Millarc64edde2009-04-18 12:26:32 -0700827 @Override
828 protected int computeCurrentCountLocked() {
829 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 }
831
832 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -0700833 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800834 mNesting = 0;
835 }
836 }
837
Evan Millarc64edde2009-04-18 12:26:32 -0700838 private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
839
840 byte[] buffer = new byte[4096];
841 int len;
842
843 try {
844 FileInputStream is = new FileInputStream("/proc/wakelocks");
845 len = is.read(buffer);
846 is.close();
847
848 if (len > 0) {
849 int i;
850 for (i=0; i<len; i++) {
851 if (buffer[i] == '\0') {
852 len = i;
853 break;
854 }
855 }
856 }
857 } catch (java.io.FileNotFoundException e) {
858 return null;
859 } catch (java.io.IOException e) {
860 return null;
861 }
862
863 return parseProcWakelocks(buffer, len);
864 }
865
866 private final Map<String, KernelWakelockStats> parseProcWakelocks(
867 byte[] wlBuffer, int len) {
868 String name;
869 int count;
870 long totalTime;
871 int startIndex, endIndex;
872 int numUpdatedWlNames = 0;
873
874 // Advance past the first line.
875 int i;
876 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++);
877 startIndex = endIndex = i + 1;
878
879 synchronized(this) {
880 Map<String, KernelWakelockStats> m = mProcWakelockFileStats;
881
882 sKernelWakelockUpdateVersion++;
883 while (endIndex < len) {
884 for (endIndex=startIndex;
885 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
886 endIndex++);
887 endIndex++; // endIndex is an exclusive upper bound.
888
889 String[] nameStringArray = mProcWakelocksName;
890 long[] wlData = mProcWakelocksData;
Amith Yamasani53b707b2009-09-30 11:05:30 -0700891 boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex,
892 PROC_WAKELOCKS_FORMAT, nameStringArray, wlData, null);
Evan Millarc64edde2009-04-18 12:26:32 -0700893
894 name = nameStringArray[0];
895 count = (int) wlData[1];
896 // convert nanoseconds to microseconds with rounding.
897 totalTime = (wlData[2] + 500) / 1000;
898
Amith Yamasani53b707b2009-09-30 11:05:30 -0700899 if (parsed && name.length() > 0) {
Evan Millarc64edde2009-04-18 12:26:32 -0700900 if (!m.containsKey(name)) {
901 m.put(name, new KernelWakelockStats(count, totalTime,
902 sKernelWakelockUpdateVersion));
903 numUpdatedWlNames++;
904 } else {
905 KernelWakelockStats kwlStats = m.get(name);
906 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) {
907 kwlStats.mCount += count;
908 kwlStats.mTotalTime += totalTime;
909 } else {
910 kwlStats.mCount = count;
911 kwlStats.mTotalTime = totalTime;
912 kwlStats.mVersion = sKernelWakelockUpdateVersion;
913 numUpdatedWlNames++;
914 }
915 }
Amith Yamasani53b707b2009-09-30 11:05:30 -0700916 }
Evan Millarc64edde2009-04-18 12:26:32 -0700917 startIndex = endIndex;
918 }
919
920 if (m.size() != numUpdatedWlNames) {
921 // Don't report old data.
922 Iterator<KernelWakelockStats> itr = m.values().iterator();
923 while (itr.hasNext()) {
924 if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
925 itr.remove();
926 }
927 }
928 }
929 return m;
930 }
931 }
932
933 private class KernelWakelockStats {
934 public int mCount;
935 public long mTotalTime;
936 public int mVersion;
937
938 KernelWakelockStats(int count, long totalTime, int version) {
939 mCount = count;
940 mTotalTime = totalTime;
941 mVersion = version;
942 }
943 }
944
945 /*
946 * Get the KernelWakelockTimer associated with name, and create a new one if one
947 * doesn't already exist.
948 */
949 public SamplingTimer getKernelWakelockTimerLocked(String name) {
950 SamplingTimer kwlt = mKernelWakelockStats.get(name);
951 if (kwlt == null) {
952 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
953 true /* track reported values */);
954 mKernelWakelockStats.put(name, kwlt);
955 }
956 return kwlt;
957 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700958
959 private void doDataPlug(long[] dataTransfer, long currentBytes) {
960 dataTransfer[STATS_LAST] = dataTransfer[STATS_UNPLUGGED];
961 dataTransfer[STATS_UNPLUGGED] = -1;
962 }
963
964 private void doDataUnplug(long[] dataTransfer, long currentBytes) {
965 dataTransfer[STATS_UNPLUGGED] = currentBytes;
966 }
967
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700968 /**
969 * Radio uptime in microseconds when transferring data. This value is very approximate.
970 * @return
971 */
972 private long getCurrentRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700973 try {
974 File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms");
975 if (!awakeTimeFile.exists()) return 0;
976 BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile));
977 String line = br.readLine();
978 br.close();
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700979 return Long.parseLong(line) * 1000;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700980 } catch (NumberFormatException nfe) {
981 // Nothing
982 } catch (IOException ioe) {
983 // Nothing
984 }
985 return 0;
986 }
987
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700988 /**
989 * @deprecated use getRadioDataUptime
990 */
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700991 public long getRadioDataUptimeMs() {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700992 return getRadioDataUptime() / 1000;
993 }
994
995 /**
996 * Returns the duration that the cell radio was up for data transfers.
997 */
998 public long getRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700999 if (mRadioDataStart == -1) {
1000 return mRadioDataUptime;
1001 } else {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001002 return getCurrentRadioDataUptime() - mRadioDataStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001003 }
1004 }
1005
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001006 private int getCurrentBluetoothPingCount() {
1007 if (mBtHeadset != null) {
1008 return mBtHeadset.getBatteryUsageHint();
1009 }
1010 return -1;
1011 }
1012
1013 public int getBluetoothPingCount() {
1014 if (mBluetoothPingStart == -1) {
1015 return mBluetoothPingCount;
1016 } else if (mBtHeadset != null) {
1017 return getCurrentBluetoothPingCount() - mBluetoothPingStart;
1018 }
Amith Yamasani82cb0292009-08-18 11:29:28 -07001019 return 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001020 }
1021
1022 public void setBtHeadset(BluetoothHeadset headset) {
Amith Yamasani82cb0292009-08-18 11:29:28 -07001023 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) {
1024 mBluetoothPingStart = getCurrentBluetoothPingCount();
1025 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001026 mBtHeadset = headset;
1027 }
1028
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001029 public void doUnplug(long batteryUptime, long batteryRealtime) {
1030 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
1031 Uid u = mUidStats.valueAt(iu);
Ken Shirriff1719a392009-12-07 15:57:35 -08001032 u.mStartedTcpBytesReceived = TrafficStats.getUidRxBytes(u.mUid);
1033 u.mStartedTcpBytesSent = TrafficStats.getUidTxBytes(u.mUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001034 u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived;
1035 u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent;
1036 }
1037 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
1038 mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime);
1039 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001040 // Track total mobile data
Ken Shirriff1719a392009-12-07 15:57:35 -08001041 doDataUnplug(mMobileDataRx, TrafficStats.getMobileRxBytes());
1042 doDataUnplug(mMobileDataTx, TrafficStats.getMobileTxBytes());
1043 doDataUnplug(mTotalDataRx, TrafficStats.getTotalRxBytes());
1044 doDataUnplug(mTotalDataTx, TrafficStats.getTotalTxBytes());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001045 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001046 mRadioDataStart = getCurrentRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001047 mRadioDataUptime = 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001048 // Track bt headset ping count
1049 mBluetoothPingStart = getCurrentBluetoothPingCount();
1050 mBluetoothPingCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001051 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001053 public void doPlug(long batteryUptime, long batteryRealtime) {
1054 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
1055 Uid u = mUidStats.valueAt(iu);
1056 if (u.mStartedTcpBytesReceived >= 0) {
1057 u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived();
1058 u.mStartedTcpBytesReceived = -1;
1059 }
1060 if (u.mStartedTcpBytesSent >= 0) {
1061 u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent();
1062 u.mStartedTcpBytesSent = -1;
1063 }
1064 }
1065 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
1066 mUnpluggables.get(i).plug(batteryUptime, batteryRealtime);
1067 }
Ken Shirriff1719a392009-12-07 15:57:35 -08001068 doDataPlug(mMobileDataRx, TrafficStats.getMobileRxBytes());
1069 doDataPlug(mMobileDataTx, TrafficStats.getMobileTxBytes());
1070 doDataPlug(mTotalDataRx, TrafficStats.getTotalRxBytes());
1071 doDataPlug(mTotalDataTx, TrafficStats.getTotalTxBytes());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001072 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001073 mRadioDataUptime = getRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001074 mRadioDataStart = -1;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001075
1076 // Track bt headset ping count
1077 mBluetoothPingCount = getBluetoothPingCount();
1078 mBluetoothPingStart = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001079 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001080
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001081 public void noteStartGps(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001082 getUidStatsLocked(uid).noteStartGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001083 }
1084
1085 public void noteStopGps(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001086 getUidStatsLocked(uid).noteStopGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001087 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001089 public void noteScreenOnLocked() {
1090 if (!mScreenOn) {
1091 mScreenOn = true;
1092 mScreenOnTimer.startRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001093 if (mScreenBrightnessBin >= 0) {
1094 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this);
1095 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001096 }
1097 }
1098
1099 public void noteScreenOffLocked() {
1100 if (mScreenOn) {
1101 mScreenOn = false;
1102 mScreenOnTimer.stopRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001103 if (mScreenBrightnessBin >= 0) {
1104 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1105 }
1106 }
1107 }
1108
1109 public void noteScreenBrightnessLocked(int brightness) {
1110 // Bin the brightness.
1111 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
1112 if (bin < 0) bin = 0;
1113 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
1114 if (mScreenBrightnessBin != bin) {
1115 if (mScreenOn) {
1116 if (mScreenBrightnessBin >= 0) {
1117 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1118 }
1119 mScreenBrightnessTimer[bin].startRunningLocked(this);
1120 }
1121 mScreenBrightnessBin = bin;
1122 }
1123 }
1124
1125 public void noteInputEventLocked() {
1126 mInputEventCounter.stepLocked();
1127 }
1128
1129 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001130 getUidStatsLocked(uid).noteUserActivityLocked(event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001131 }
1132
1133 public void notePhoneOnLocked() {
1134 if (!mPhoneOn) {
1135 mPhoneOn = true;
1136 mPhoneOnTimer.startRunningLocked(this);
1137 }
1138 }
1139
1140 public void notePhoneOffLocked() {
1141 if (mPhoneOn) {
1142 mPhoneOn = false;
1143 mPhoneOnTimer.stopRunningLocked(this);
1144 }
1145 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001146
Amith Yamasanif37447b2009-10-08 18:28:01 -07001147 /**
1148 * Telephony stack updates the phone state.
1149 * @param state phone state from ServiceState.getState()
1150 */
1151 public void notePhoneStateLocked(int state) {
1152 int bin = mPhoneSignalStrengthBin;
1153 boolean isAirplaneMode = state == ServiceState.STATE_POWER_OFF;
1154 // Stop all timers
1155 if (isAirplaneMode || state == ServiceState.STATE_OUT_OF_SERVICE) {
1156 for (int i = 0; i < NUM_SIGNAL_STRENGTH_BINS; i++) {
1157 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
1158 mPhoneSignalStrengthsTimer[i].stopRunningLocked(this);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001159 }
1160 }
1161 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07001162 // Stop Signal Scanning timer, in case we're going into service
1163 while (mPhoneSignalScanningTimer.isRunningLocked()) {
1164 mPhoneSignalScanningTimer.stopRunningLocked(this);
1165 }
1166
1167 // If we're back in service or continuing in service, restart the old timer.
1168 if (state == ServiceState.STATE_IN_SERVICE) {
1169 if (bin == -1) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
1170 if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
1171 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
1172 }
1173 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
1174 mPhoneSignalStrengthBin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
1175 if (!mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].isRunningLocked()) {
1176 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].startRunningLocked(this);
1177 }
1178 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
1179 mPhoneSignalScanningTimer.startRunningLocked(this);
1180 }
1181 }
1182 mPhoneServiceState = state;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001183 }
1184
Wink Savillee9b06d72009-05-18 21:47:50 -07001185 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07001186 // Bin the strength.
1187 int bin;
Amith Yamasanif37447b2009-10-08 18:28:01 -07001188 if (mPhoneServiceState == ServiceState.STATE_POWER_OFF
1189 || mPhoneServiceState == ServiceState.STATE_OUT_OF_SERVICE) {
1190 // Ignore any signal strength changes when radio was turned off or out of service.
1191 return;
1192 }
Wink Savillee9b06d72009-05-18 21:47:50 -07001193 if (!signalStrength.isGsm()) {
1194 int dBm = signalStrength.getCdmaDbm();
Amith Yamasanif37447b2009-10-08 18:28:01 -07001195 if (dBm >= -75) bin = SIGNAL_STRENGTH_GREAT;
1196 else if (dBm >= -85) bin = SIGNAL_STRENGTH_GOOD;
1197 else if (dBm >= -95) bin = SIGNAL_STRENGTH_MODERATE;
1198 else if (dBm >= -100) bin = SIGNAL_STRENGTH_POOR;
1199 else bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Wink Savillee9b06d72009-05-18 21:47:50 -07001200 } else {
1201 int asu = signalStrength.getGsmSignalStrength();
1202 if (asu < 0 || asu >= 99) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
1203 else if (asu >= 16) bin = SIGNAL_STRENGTH_GREAT;
1204 else if (asu >= 8) bin = SIGNAL_STRENGTH_GOOD;
1205 else if (asu >= 4) bin = SIGNAL_STRENGTH_MODERATE;
1206 else bin = SIGNAL_STRENGTH_POOR;
1207 }
Dianne Hackborn627bba72009-03-24 22:32:56 -07001208 if (mPhoneSignalStrengthBin != bin) {
1209 if (mPhoneSignalStrengthBin >= 0) {
1210 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
1211 }
1212 mPhoneSignalStrengthBin = bin;
1213 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
1214 }
1215 }
1216
1217 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
1218 int bin = DATA_CONNECTION_NONE;
1219 if (hasData) {
1220 switch (dataType) {
1221 case TelephonyManager.NETWORK_TYPE_EDGE:
1222 bin = DATA_CONNECTION_EDGE;
1223 break;
1224 case TelephonyManager.NETWORK_TYPE_GPRS:
1225 bin = DATA_CONNECTION_GPRS;
1226 break;
1227 case TelephonyManager.NETWORK_TYPE_UMTS:
1228 bin = DATA_CONNECTION_UMTS;
1229 break;
1230 default:
1231 bin = DATA_CONNECTION_OTHER;
1232 break;
1233 }
1234 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001235 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001236 if (mPhoneDataConnectionType != bin) {
1237 if (mPhoneDataConnectionType >= 0) {
1238 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this);
1239 }
1240 mPhoneDataConnectionType = bin;
1241 mPhoneDataConnectionsTimer[bin].startRunningLocked(this);
1242 }
1243 }
1244
Dianne Hackborn617f8772009-03-31 15:04:46 -07001245 public void noteWifiOnLocked(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001246 if (!mWifiOn) {
1247 mWifiOn = true;
1248 mWifiOnTimer.startRunningLocked(this);
1249 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001250 if (mWifiOnUid != uid) {
1251 if (mWifiOnUid >= 0) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001252 getUidStatsLocked(mWifiOnUid).noteWifiTurnedOffLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001253 }
1254 mWifiOnUid = uid;
Dianne Hackborn2e418422009-06-22 20:00:17 -07001255 getUidStatsLocked(uid).noteWifiTurnedOnLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001256 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001257 }
1258
Dianne Hackborn617f8772009-03-31 15:04:46 -07001259 public void noteWifiOffLocked(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001260 if (mWifiOn) {
1261 mWifiOn = false;
1262 mWifiOnTimer.stopRunningLocked(this);
1263 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001264 if (mWifiOnUid >= 0) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001265 getUidStatsLocked(mWifiOnUid).noteWifiTurnedOffLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001266 mWifiOnUid = -1;
1267 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001268 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001269
1270 public void noteAudioOnLocked(int uid) {
1271 if (!mAudioOn) {
1272 mAudioOn = true;
1273 mAudioOnTimer.startRunningLocked(this);
1274 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001275 getUidStatsLocked(uid).noteAudioTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001276 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001277
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001278 public void noteAudioOffLocked(int uid) {
1279 if (mAudioOn) {
1280 mAudioOn = false;
1281 mAudioOnTimer.stopRunningLocked(this);
1282 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001283 getUidStatsLocked(uid).noteAudioTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001284 }
1285
1286 public void noteVideoOnLocked(int uid) {
1287 if (!mVideoOn) {
1288 mVideoOn = true;
1289 mVideoOnTimer.startRunningLocked(this);
1290 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001291 getUidStatsLocked(uid).noteVideoTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001292 }
1293
1294 public void noteVideoOffLocked(int uid) {
1295 if (mVideoOn) {
1296 mVideoOn = false;
1297 mVideoOnTimer.stopRunningLocked(this);
1298 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001299 getUidStatsLocked(uid).noteVideoTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001300 }
1301
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001302 public void noteWifiRunningLocked() {
1303 if (!mWifiRunning) {
1304 mWifiRunning = true;
1305 mWifiRunningTimer.startRunningLocked(this);
1306 }
1307 }
1308
1309 public void noteWifiStoppedLocked() {
1310 if (mWifiRunning) {
1311 mWifiRunning = false;
1312 mWifiRunningTimer.stopRunningLocked(this);
1313 }
1314 }
1315
The Android Open Source Project10592532009-03-18 17:39:46 -07001316 public void noteBluetoothOnLocked() {
1317 if (!mBluetoothOn) {
1318 mBluetoothOn = true;
1319 mBluetoothOnTimer.startRunningLocked(this);
1320 }
1321 }
1322
1323 public void noteBluetoothOffLocked() {
1324 if (mBluetoothOn) {
1325 mBluetoothOn = false;
1326 mBluetoothOnTimer.stopRunningLocked(this);
1327 }
1328 }
1329
1330 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001331 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001332 }
1333
1334 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001335 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001336 }
1337
1338 public void noteScanWifiLockAcquiredLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001339 getUidStatsLocked(uid).noteScanWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001340 }
1341
1342 public void noteScanWifiLockReleasedLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001343 getUidStatsLocked(uid).noteScanWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001344 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001345
1346 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001347 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001348 }
1349
1350 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001351 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001352 }
1353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001354 @Override public long getScreenOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001355 return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001356 }
1357
Dianne Hackborn617f8772009-03-31 15:04:46 -07001358 @Override public long getScreenBrightnessTime(int brightnessBin,
1359 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001360 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn617f8772009-03-31 15:04:46 -07001361 batteryRealtime, which);
1362 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001363
Dianne Hackborn617f8772009-03-31 15:04:46 -07001364 @Override public int getInputEventCount(int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001365 return mInputEventCounter.getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001366 }
1367
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001368 @Override public long getPhoneOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001369 return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001370 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001371
Dianne Hackborn627bba72009-03-24 22:32:56 -07001372 @Override public long getPhoneSignalStrengthTime(int strengthBin,
1373 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001374 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07001375 batteryRealtime, which);
1376 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07001377
1378 @Override public long getPhoneSignalScanningTime(
1379 long batteryRealtime, int which) {
1380 return mPhoneSignalScanningTimer.getTotalTimeLocked(
1381 batteryRealtime, which);
1382 }
1383
Dianne Hackborn617f8772009-03-31 15:04:46 -07001384 @Override public int getPhoneSignalStrengthCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001385 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001386 }
1387
Dianne Hackborn627bba72009-03-24 22:32:56 -07001388 @Override public long getPhoneDataConnectionTime(int dataType,
1389 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001390 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07001391 batteryRealtime, which);
1392 }
1393
Dianne Hackborn617f8772009-03-31 15:04:46 -07001394 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001395 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001396 }
1397
The Android Open Source Project10592532009-03-18 17:39:46 -07001398 @Override public long getWifiOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001399 return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001400 }
1401
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001402 @Override public long getWifiRunningTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001403 return mWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001404 }
1405
The Android Open Source Project10592532009-03-18 17:39:46 -07001406 @Override public long getBluetoothOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001407 return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001408 }
1409
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001410 @Override public boolean getIsOnBattery() {
1411 return mOnBattery;
1412 }
1413
1414 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
1415 return mUidStats;
1416 }
1417
1418 /**
1419 * The statistics associated with a particular uid.
1420 */
1421 public final class Uid extends BatteryStats.Uid {
1422
1423 final int mUid;
1424 long mLoadedTcpBytesReceived;
1425 long mLoadedTcpBytesSent;
1426 long mCurrentTcpBytesReceived;
1427 long mCurrentTcpBytesSent;
1428 long mTcpBytesReceivedAtLastUnplug;
1429 long mTcpBytesSentAtLastUnplug;
1430
1431 // These are not saved/restored when parcelling, since we want
1432 // to return from the parcel with a snapshot of the state.
1433 long mStartedTcpBytesReceived = -1;
1434 long mStartedTcpBytesSent = -1;
1435
Dianne Hackborn617f8772009-03-31 15:04:46 -07001436 boolean mWifiTurnedOn;
Evan Millarc64edde2009-04-18 12:26:32 -07001437 StopwatchTimer mWifiTurnedOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -07001438
The Android Open Source Project10592532009-03-18 17:39:46 -07001439 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07001440 StopwatchTimer mFullWifiLockTimer;
The Android Open Source Project10592532009-03-18 17:39:46 -07001441
1442 boolean mScanWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07001443 StopwatchTimer mScanWifiLockTimer;
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001444
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001445 boolean mWifiMulticastEnabled;
1446 StopwatchTimer mWifiMulticastTimer;
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001447
1448 boolean mAudioTurnedOn;
1449 StopwatchTimer mAudioTurnedOnTimer;
1450
1451 boolean mVideoTurnedOn;
1452 StopwatchTimer mVideoTurnedOnTimer;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001453
Dianne Hackborn617f8772009-03-31 15:04:46 -07001454 Counter[] mUserActivityCounters;
1455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456 /**
1457 * The statistics we have collected for this uid's wake locks.
1458 */
1459 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>();
1460
1461 /**
1462 * The statistics we have collected for this uid's sensor activations.
1463 */
1464 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>();
1465
1466 /**
1467 * The statistics we have collected for this uid's processes.
1468 */
1469 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>();
1470
1471 /**
1472 * The statistics we have collected for this uid's processes.
1473 */
1474 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>();
1475
1476 public Uid(int uid) {
1477 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001478 mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, null, mUnpluggables);
1479 mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables);
1480 mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001481 mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED,
1482 null, mUnpluggables);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001483 mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, null, mUnpluggables);
1484 mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001485 }
1486
1487 @Override
1488 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
1489 return mWakelockStats;
1490 }
1491
1492 @Override
1493 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() {
1494 return mSensorStats;
1495 }
1496
1497 @Override
1498 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
1499 return mProcessStats;
1500 }
1501
1502 @Override
1503 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
1504 return mPackageStats;
1505 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001506
1507 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001508 public int getUid() {
1509 return mUid;
1510 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001511
1512 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001513 public long getTcpBytesReceived(int which) {
1514 if (which == STATS_LAST) {
1515 return mLoadedTcpBytesReceived;
1516 } else {
1517 long current = computeCurrentTcpBytesReceived();
1518 if (which == STATS_UNPLUGGED) {
1519 current -= mTcpBytesReceivedAtLastUnplug;
1520 } else if (which == STATS_TOTAL) {
1521 current += mLoadedTcpBytesReceived;
1522 }
1523 return current;
1524 }
1525 }
1526
1527 public long computeCurrentTcpBytesReceived() {
1528 return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0
Ken Shirriff1719a392009-12-07 15:57:35 -08001529 ? (TrafficStats.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001530 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001531
1532 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001533 public long getTcpBytesSent(int which) {
1534 if (which == STATS_LAST) {
1535 return mLoadedTcpBytesSent;
1536 } else {
1537 long current = computeCurrentTcpBytesSent();
1538 if (which == STATS_UNPLUGGED) {
1539 current -= mTcpBytesSentAtLastUnplug;
1540 } else if (which == STATS_TOTAL) {
1541 current += mLoadedTcpBytesSent;
1542 }
1543 return current;
1544 }
1545 }
1546
The Android Open Source Project10592532009-03-18 17:39:46 -07001547 @Override
Dianne Hackborn617f8772009-03-31 15:04:46 -07001548 public void noteWifiTurnedOnLocked() {
1549 if (!mWifiTurnedOn) {
1550 mWifiTurnedOn = true;
1551 mWifiTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
1552 }
1553 }
1554
1555 @Override
1556 public void noteWifiTurnedOffLocked() {
1557 if (mWifiTurnedOn) {
1558 mWifiTurnedOn = false;
1559 mWifiTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
1560 }
1561 }
1562
1563 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07001564 public void noteFullWifiLockAcquiredLocked() {
1565 if (!mFullWifiLockOut) {
1566 mFullWifiLockOut = true;
1567 mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
1568 }
1569 }
1570
1571 @Override
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001572 public void noteVideoTurnedOnLocked() {
1573 if (!mVideoTurnedOn) {
1574 mVideoTurnedOn = true;
1575 mVideoTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
1576 }
1577 }
1578
1579 @Override
1580 public void noteVideoTurnedOffLocked() {
1581 if (mVideoTurnedOn) {
1582 mVideoTurnedOn = false;
1583 mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
1584 }
1585 }
1586
1587 @Override
1588 public void noteAudioTurnedOnLocked() {
1589 if (!mAudioTurnedOn) {
1590 mAudioTurnedOn = true;
1591 mAudioTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
1592 }
1593 }
1594
1595 @Override
1596 public void noteAudioTurnedOffLocked() {
1597 if (mAudioTurnedOn) {
1598 mAudioTurnedOn = false;
1599 mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
1600 }
1601 }
1602
1603 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07001604 public void noteFullWifiLockReleasedLocked() {
1605 if (mFullWifiLockOut) {
1606 mFullWifiLockOut = false;
1607 mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
1608 }
1609 }
1610
1611 @Override
1612 public void noteScanWifiLockAcquiredLocked() {
1613 if (!mScanWifiLockOut) {
1614 mScanWifiLockOut = true;
1615 mScanWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
1616 }
1617 }
1618
1619 @Override
1620 public void noteScanWifiLockReleasedLocked() {
1621 if (mScanWifiLockOut) {
1622 mScanWifiLockOut = false;
1623 mScanWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
1624 }
1625 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001626
1627 @Override
1628 public void noteWifiMulticastEnabledLocked() {
1629 if (!mWifiMulticastEnabled) {
1630 mWifiMulticastEnabled = true;
1631 mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this);
1632 }
1633 }
1634
1635 @Override
1636 public void noteWifiMulticastDisabledLocked() {
1637 if (mWifiMulticastEnabled) {
1638 mWifiMulticastEnabled = false;
1639 mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this);
1640 }
1641 }
1642
Dianne Hackborn617f8772009-03-31 15:04:46 -07001643 @Override
1644 public long getWifiTurnedOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001645 return mWifiTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001646 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001647
1648 @Override
1649 public long getAudioTurnedOnTime(long batteryRealtime, int which) {
1650 return mAudioTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
1651 }
1652
1653 @Override
1654 public long getVideoTurnedOnTime(long batteryRealtime, int which) {
1655 return mVideoTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
1656 }
1657
The Android Open Source Project10592532009-03-18 17:39:46 -07001658 @Override
1659 public long getFullWifiLockTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001660 return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001661 }
1662
1663 @Override
1664 public long getScanWifiLockTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001665 return mScanWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001666 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001667
1668 @Override
1669 public long getWifiMulticastTime(long batteryRealtime, int which) {
1670 return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime,
1671 which);
1672 }
1673
Dianne Hackborn617f8772009-03-31 15:04:46 -07001674 @Override
1675 public void noteUserActivityLocked(int type) {
1676 if (mUserActivityCounters == null) {
1677 initUserActivityLocked();
1678 }
1679 if (type < 0) type = 0;
1680 else if (type >= NUM_USER_ACTIVITY_TYPES) type = NUM_USER_ACTIVITY_TYPES-1;
1681 mUserActivityCounters[type].stepLocked();
1682 }
1683
1684 @Override
1685 public boolean hasUserActivity() {
1686 return mUserActivityCounters != null;
1687 }
1688
1689 @Override
1690 public int getUserActivityCount(int type, int which) {
1691 if (mUserActivityCounters == null) {
1692 return 0;
1693 }
Evan Millarc64edde2009-04-18 12:26:32 -07001694 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001695 }
1696
1697 void initUserActivityLocked() {
1698 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
1699 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
1700 mUserActivityCounters[i] = new Counter(mUnpluggables);
1701 }
1702 }
1703
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001704 public long computeCurrentTcpBytesSent() {
1705 return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0
Ken Shirriff1719a392009-12-07 15:57:35 -08001706 ? (TrafficStats.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001707 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001708
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001709 void writeToParcelLocked(Parcel out, long batteryRealtime) {
1710 out.writeInt(mWakelockStats.size());
1711 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
1712 out.writeString(wakelockEntry.getKey());
1713 Uid.Wakelock wakelock = wakelockEntry.getValue();
1714 wakelock.writeToParcelLocked(out, batteryRealtime);
1715 }
1716
1717 out.writeInt(mSensorStats.size());
1718 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) {
1719 out.writeInt(sensorEntry.getKey());
1720 Uid.Sensor sensor = sensorEntry.getValue();
1721 sensor.writeToParcelLocked(out, batteryRealtime);
1722 }
1723
1724 out.writeInt(mProcessStats.size());
1725 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) {
1726 out.writeString(procEntry.getKey());
1727 Uid.Proc proc = procEntry.getValue();
1728 proc.writeToParcelLocked(out);
1729 }
1730
1731 out.writeInt(mPackageStats.size());
1732 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
1733 out.writeString(pkgEntry.getKey());
1734 Uid.Pkg pkg = pkgEntry.getValue();
1735 pkg.writeToParcelLocked(out);
1736 }
1737
1738 out.writeLong(mLoadedTcpBytesReceived);
1739 out.writeLong(mLoadedTcpBytesSent);
1740 out.writeLong(computeCurrentTcpBytesReceived());
1741 out.writeLong(computeCurrentTcpBytesSent());
1742 out.writeLong(mTcpBytesReceivedAtLastUnplug);
1743 out.writeLong(mTcpBytesSentAtLastUnplug);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001744 mWifiTurnedOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07001745 mFullWifiLockTimer.writeToParcel(out, batteryRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001746 mAudioTurnedOnTimer.writeToParcel(out, batteryRealtime);
1747 mVideoTurnedOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07001748 mScanWifiLockTimer.writeToParcel(out, batteryRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001749 mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001750 if (mUserActivityCounters == null) {
1751 out.writeInt(0);
1752 } else {
1753 out.writeInt(1);
1754 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
1755 mUserActivityCounters[i].writeToParcel(out);
1756 }
1757 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001758 }
1759
1760 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
1761 int numWakelocks = in.readInt();
1762 mWakelockStats.clear();
1763 for (int j = 0; j < numWakelocks; j++) {
1764 String wakelockName = in.readString();
1765 Uid.Wakelock wakelock = new Wakelock();
1766 wakelock.readFromParcelLocked(unpluggables, in);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001767 if (mWakelockStats.size() < MAX_WAKELOCKS_PER_UID) {
1768 // We will just drop some random set of wakelocks if
1769 // the previous run of the system was an older version
1770 // that didn't impose a limit.
1771 mWakelockStats.put(wakelockName, wakelock);
1772 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001773 }
1774
1775 int numSensors = in.readInt();
1776 mSensorStats.clear();
1777 for (int k = 0; k < numSensors; k++) {
1778 int sensorNumber = in.readInt();
1779 Uid.Sensor sensor = new Sensor(sensorNumber);
1780 sensor.readFromParcelLocked(mUnpluggables, in);
1781 mSensorStats.put(sensorNumber, sensor);
1782 }
1783
1784 int numProcs = in.readInt();
1785 mProcessStats.clear();
1786 for (int k = 0; k < numProcs; k++) {
1787 String processName = in.readString();
1788 Uid.Proc proc = new Proc();
1789 proc.readFromParcelLocked(in);
1790 mProcessStats.put(processName, proc);
1791 }
1792
1793 int numPkgs = in.readInt();
1794 mPackageStats.clear();
1795 for (int l = 0; l < numPkgs; l++) {
1796 String packageName = in.readString();
1797 Uid.Pkg pkg = new Pkg();
1798 pkg.readFromParcelLocked(in);
1799 mPackageStats.put(packageName, pkg);
1800 }
1801
1802 mLoadedTcpBytesReceived = in.readLong();
1803 mLoadedTcpBytesSent = in.readLong();
1804 mCurrentTcpBytesReceived = in.readLong();
1805 mCurrentTcpBytesSent = in.readLong();
1806 mTcpBytesReceivedAtLastUnplug = in.readLong();
1807 mTcpBytesSentAtLastUnplug = in.readLong();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001808 mWifiTurnedOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001809 mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07001810 mFullWifiLockOut = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001811 mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables, in);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001812 mAudioTurnedOn = false;
1813 mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, null, mUnpluggables, in);
1814 mVideoTurnedOn = false;
1815 mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07001816 mScanWifiLockOut = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001817 mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables, in);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001818 mWifiMulticastEnabled = false;
1819 mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED,
1820 null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001821 if (in.readInt() == 0) {
1822 mUserActivityCounters = null;
1823 } else {
1824 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
1825 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
1826 mUserActivityCounters[i] = new Counter(mUnpluggables, in);
1827 }
1828 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001829 }
1830
1831 /**
1832 * The statistics associated with a particular wake lock.
1833 */
1834 public final class Wakelock extends BatteryStats.Uid.Wakelock {
1835 /**
1836 * How long (in ms) this uid has been keeping the device partially awake.
1837 */
Evan Millarc64edde2009-04-18 12:26:32 -07001838 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001839
1840 /**
1841 * How long (in ms) this uid has been keeping the device fully awake.
1842 */
Evan Millarc64edde2009-04-18 12:26:32 -07001843 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001844
1845 /**
1846 * How long (in ms) this uid has had a window keeping the device awake.
1847 */
Evan Millarc64edde2009-04-18 12:26:32 -07001848 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001849
1850 /**
1851 * Reads a possibly null Timer from a Parcel. The timer is associated with the
1852 * proper timer pool from the given BatteryStatsImpl object.
1853 *
1854 * @param in the Parcel to be read from.
1855 * return a new Timer, or null.
1856 */
Evan Millarc64edde2009-04-18 12:26:32 -07001857 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001858 ArrayList<Unpluggable> unpluggables, Parcel in) {
1859 if (in.readInt() == 0) {
1860 return null;
1861 }
1862
Evan Millarc64edde2009-04-18 12:26:32 -07001863 return new StopwatchTimer(type, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001864 }
1865
1866 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
1867 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
1868 mPartialTimers, unpluggables, in);
1869 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
1870 mFullTimers, unpluggables, in);
1871 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
1872 mWindowTimers, unpluggables, in);
1873 }
1874
1875 void writeToParcelLocked(Parcel out, long batteryRealtime) {
1876 Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime);
1877 Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime);
1878 Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime);
1879 }
1880
1881 @Override
1882 public Timer getWakeTime(int type) {
1883 switch (type) {
1884 case WAKE_TYPE_FULL: return mTimerFull;
1885 case WAKE_TYPE_PARTIAL: return mTimerPartial;
1886 case WAKE_TYPE_WINDOW: return mTimerWindow;
1887 default: throw new IllegalArgumentException("type = " + type);
1888 }
1889 }
1890 }
1891
1892 public final class Sensor extends BatteryStats.Uid.Sensor {
1893 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07001894 StopwatchTimer mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001895
1896 public Sensor(int handle) {
1897 mHandle = handle;
1898 }
1899
Evan Millarc64edde2009-04-18 12:26:32 -07001900 private StopwatchTimer readTimerFromParcel(ArrayList<Unpluggable> unpluggables,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001901 Parcel in) {
1902 if (in.readInt() == 0) {
1903 return null;
1904 }
1905
Evan Millarc64edde2009-04-18 12:26:32 -07001906 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001907 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001908 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001909 mSensorTimers.put(mHandle, pool);
1910 }
Evan Millarc64edde2009-04-18 12:26:32 -07001911 return new StopwatchTimer(0, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001912 }
1913
1914 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
1915 mTimer = readTimerFromParcel(unpluggables, in);
1916 }
1917
1918 void writeToParcelLocked(Parcel out, long batteryRealtime) {
1919 Timer.writeTimerToParcel(out, mTimer, batteryRealtime);
1920 }
1921
1922 @Override
1923 public Timer getSensorTime() {
1924 return mTimer;
1925 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001926
1927 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001928 public int getHandle() {
1929 return mHandle;
1930 }
1931 }
1932
1933 /**
1934 * The statistics associated with a particular process.
1935 */
1936 public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable {
1937 /**
1938 * Total time (in 1/100 sec) spent executing in user code.
1939 */
1940 long mUserTime;
1941
1942 /**
1943 * Total time (in 1/100 sec) spent executing in kernel code.
1944 */
1945 long mSystemTime;
1946
1947 /**
1948 * Number of times the process has been started.
1949 */
1950 int mStarts;
1951
1952 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001953 * Amount of time the process was running in the foreground.
1954 */
1955 long mForegroundTime;
1956
1957 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001958 * The amount of user time loaded from a previous save.
1959 */
1960 long mLoadedUserTime;
1961
1962 /**
1963 * The amount of system time loaded from a previous save.
1964 */
1965 long mLoadedSystemTime;
1966
1967 /**
1968 * The number of times the process has started from a previous save.
1969 */
1970 int mLoadedStarts;
1971
1972 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001973 * The amount of foreground time loaded from a previous save.
1974 */
1975 long mLoadedForegroundTime;
1976
1977 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001978 * The amount of user time loaded from the previous run.
1979 */
1980 long mLastUserTime;
1981
1982 /**
1983 * The amount of system time loaded from the previous run.
1984 */
1985 long mLastSystemTime;
1986
1987 /**
1988 * The number of times the process has started from the previous run.
1989 */
1990 int mLastStarts;
1991
1992 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001993 * The amount of foreground time loaded from the previous run
1994 */
1995 long mLastForegroundTime;
1996
1997 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001998 * The amount of user time when last unplugged.
1999 */
2000 long mUnpluggedUserTime;
2001
2002 /**
2003 * The amount of system time when last unplugged.
2004 */
2005 long mUnpluggedSystemTime;
2006
2007 /**
2008 * The number of times the process has started before unplugged.
2009 */
2010 int mUnpluggedStarts;
2011
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002012 /**
2013 * The amount of foreground time since unplugged.
2014 */
2015 long mUnpluggedForegroundTime;
2016
Amith Yamasanie43530a2009-08-21 13:11:37 -07002017 SamplingCounter[] mSpeedBins;
2018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002019 Proc() {
2020 mUnpluggables.add(this);
Amith Yamasanie43530a2009-08-21 13:11:37 -07002021 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
2022 for (int i = 0; i < mSpeedBins.length; i++) {
2023 mSpeedBins[i] = new SamplingCounter(mUnpluggables);
2024 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002025 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07002026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002027 public void unplug(long batteryUptime, long batteryRealtime) {
2028 mUnpluggedUserTime = mUserTime;
2029 mUnpluggedSystemTime = mSystemTime;
2030 mUnpluggedStarts = mStarts;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002031 mUnpluggedForegroundTime = mForegroundTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002032 }
2033
2034 public void plug(long batteryUptime, long batteryRealtime) {
2035 }
2036
2037 void writeToParcelLocked(Parcel out) {
The Android Open Source Project10592532009-03-18 17:39:46 -07002038 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
2039 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
2040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002041 out.writeLong(mUserTime);
2042 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002043 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002044 out.writeInt(mStarts);
2045 out.writeLong(mLoadedUserTime);
2046 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002047 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002048 out.writeInt(mLoadedStarts);
2049 out.writeLong(mLastUserTime);
2050 out.writeLong(mLastSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002051 out.writeLong(mLastForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002052 out.writeInt(mLastStarts);
2053 out.writeLong(mUnpluggedUserTime);
2054 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002055 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002056 out.writeInt(mUnpluggedStarts);
Amith Yamasanie43530a2009-08-21 13:11:37 -07002057
2058 out.writeInt(mSpeedBins.length);
2059 for (int i = 0; i < mSpeedBins.length; i++) {
2060 mSpeedBins[i].writeToParcel(out);
2061 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002062 }
2063
2064 void readFromParcelLocked(Parcel in) {
2065 mUserTime = in.readLong();
2066 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002067 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002068 mStarts = in.readInt();
2069 mLoadedUserTime = in.readLong();
2070 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002071 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002072 mLoadedStarts = in.readInt();
2073 mLastUserTime = in.readLong();
2074 mLastSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002075 mLastForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002076 mLastStarts = in.readInt();
2077 mUnpluggedUserTime = in.readLong();
2078 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002079 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002080 mUnpluggedStarts = in.readInt();
Amith Yamasanie43530a2009-08-21 13:11:37 -07002081
2082 int bins = in.readInt();
2083 mSpeedBins = new SamplingCounter[bins];
2084 for (int i = 0; i < bins; i++) {
2085 mSpeedBins[i] = new SamplingCounter(mUnpluggables, in);
2086 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002087 }
2088
2089 public BatteryStatsImpl getBatteryStats() {
2090 return BatteryStatsImpl.this;
2091 }
2092
2093 public void addCpuTimeLocked(int utime, int stime) {
2094 mUserTime += utime;
2095 mSystemTime += stime;
2096 }
2097
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002098 public void addForegroundTimeLocked(long ttime) {
2099 mForegroundTime += ttime;
2100 }
2101
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002102 public void incStartsLocked() {
2103 mStarts++;
2104 }
2105
2106 @Override
2107 public long getUserTime(int which) {
2108 long val;
2109 if (which == STATS_LAST) {
2110 val = mLastUserTime;
2111 } else {
2112 val = mUserTime;
2113 if (which == STATS_CURRENT) {
2114 val -= mLoadedUserTime;
2115 } else if (which == STATS_UNPLUGGED) {
2116 val -= mUnpluggedUserTime;
2117 }
2118 }
2119 return val;
2120 }
2121
2122 @Override
2123 public long getSystemTime(int which) {
2124 long val;
2125 if (which == STATS_LAST) {
2126 val = mLastSystemTime;
2127 } else {
2128 val = mSystemTime;
2129 if (which == STATS_CURRENT) {
2130 val -= mLoadedSystemTime;
2131 } else if (which == STATS_UNPLUGGED) {
2132 val -= mUnpluggedSystemTime;
2133 }
2134 }
2135 return val;
2136 }
2137
2138 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002139 public long getForegroundTime(int which) {
2140 long val;
2141 if (which == STATS_LAST) {
2142 val = mLastForegroundTime;
2143 } else {
2144 val = mForegroundTime;
2145 if (which == STATS_CURRENT) {
2146 val -= mLoadedForegroundTime;
2147 } else if (which == STATS_UNPLUGGED) {
2148 val -= mUnpluggedForegroundTime;
2149 }
2150 }
2151 return val;
2152 }
2153
2154 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002155 public int getStarts(int which) {
2156 int val;
2157 if (which == STATS_LAST) {
2158 val = mLastStarts;
2159 } else {
2160 val = mStarts;
2161 if (which == STATS_CURRENT) {
2162 val -= mLoadedStarts;
2163 } else if (which == STATS_UNPLUGGED) {
2164 val -= mUnpluggedStarts;
2165 }
2166 }
2167 return val;
2168 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07002169
2170 /* Called by ActivityManagerService when CPU times are updated. */
2171 public void addSpeedStepTimes(long[] values) {
2172 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) {
2173 mSpeedBins[i].addCountLocked(values[i]);
2174 }
2175 }
2176
2177 @Override
2178 public long getTimeAtCpuSpeedStep(int speedStep, int which) {
2179 if (speedStep < mSpeedBins.length) {
2180 return mSpeedBins[speedStep].getCountLocked(which);
2181 } else {
2182 return 0;
2183 }
2184 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002185 }
2186
2187 /**
2188 * The statistics associated with a particular package.
2189 */
2190 public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable {
2191 /**
2192 * Number of times this package has done something that could wake up the
2193 * device from sleep.
2194 */
2195 int mWakeups;
2196
2197 /**
2198 * Number of things that could wake up the device loaded from a
2199 * previous save.
2200 */
2201 int mLoadedWakeups;
2202
2203 /**
2204 * Number of things that could wake up the device as of the
2205 * last run.
2206 */
2207 int mLastWakeups;
2208
2209 /**
2210 * Number of things that could wake up the device as of the
2211 * last run.
2212 */
2213 int mUnpluggedWakeups;
2214
2215 /**
2216 * The statics we have collected for this package's services.
2217 */
2218 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
2219
2220 Pkg() {
2221 mUnpluggables.add(this);
2222 }
2223
2224 public void unplug(long batteryUptime, long batteryRealtime) {
2225 mUnpluggedWakeups = mWakeups;
2226 }
2227
2228 public void plug(long batteryUptime, long batteryRealtime) {
2229 }
2230
2231 void readFromParcelLocked(Parcel in) {
2232 mWakeups = in.readInt();
2233 mLoadedWakeups = in.readInt();
2234 mLastWakeups = in.readInt();
2235 mUnpluggedWakeups = in.readInt();
2236
2237 int numServs = in.readInt();
2238 mServiceStats.clear();
2239 for (int m = 0; m < numServs; m++) {
2240 String serviceName = in.readString();
2241 Uid.Pkg.Serv serv = new Serv();
2242 mServiceStats.put(serviceName, serv);
2243
2244 serv.readFromParcelLocked(in);
2245 }
2246 }
2247
2248 void writeToParcelLocked(Parcel out) {
2249 out.writeInt(mWakeups);
2250 out.writeInt(mLoadedWakeups);
2251 out.writeInt(mLastWakeups);
2252 out.writeInt(mUnpluggedWakeups);
2253
2254 out.writeInt(mServiceStats.size());
2255 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
2256 out.writeString(servEntry.getKey());
2257 Uid.Pkg.Serv serv = servEntry.getValue();
2258
2259 serv.writeToParcelLocked(out);
2260 }
2261 }
2262
2263 @Override
2264 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
2265 return mServiceStats;
2266 }
2267
2268 @Override
2269 public int getWakeups(int which) {
2270 int val;
2271 if (which == STATS_LAST) {
2272 val = mLastWakeups;
2273 } else {
2274 val = mWakeups;
2275 if (which == STATS_CURRENT) {
2276 val -= mLoadedWakeups;
2277 } else if (which == STATS_UNPLUGGED) {
2278 val -= mUnpluggedWakeups;
2279 }
2280 }
2281
2282 return val;
2283 }
2284
2285 /**
2286 * The statistics associated with a particular service.
2287 */
2288 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable {
2289 /**
2290 * Total time (ms in battery uptime) the service has been left started.
2291 */
2292 long mStartTime;
2293
2294 /**
2295 * If service has been started and not yet stopped, this is
2296 * when it was started.
2297 */
2298 long mRunningSince;
2299
2300 /**
2301 * True if we are currently running.
2302 */
2303 boolean mRunning;
2304
2305 /**
2306 * Total number of times startService() has been called.
2307 */
2308 int mStarts;
2309
2310 /**
2311 * Total time (ms in battery uptime) the service has been left launched.
2312 */
2313 long mLaunchedTime;
2314
2315 /**
2316 * If service has been launched and not yet exited, this is
2317 * when it was launched (ms in battery uptime).
2318 */
2319 long mLaunchedSince;
2320
2321 /**
2322 * True if we are currently launched.
2323 */
2324 boolean mLaunched;
2325
2326 /**
2327 * Total number times the service has been launched.
2328 */
2329 int mLaunches;
2330
2331 /**
2332 * The amount of time spent started loaded from a previous save
2333 * (ms in battery uptime).
2334 */
2335 long mLoadedStartTime;
2336
2337 /**
2338 * The number of starts loaded from a previous save.
2339 */
2340 int mLoadedStarts;
2341
2342 /**
2343 * The number of launches loaded from a previous save.
2344 */
2345 int mLoadedLaunches;
2346
2347 /**
2348 * The amount of time spent started as of the last run (ms
2349 * in battery uptime).
2350 */
2351 long mLastStartTime;
2352
2353 /**
2354 * The number of starts as of the last run.
2355 */
2356 int mLastStarts;
2357
2358 /**
2359 * The number of launches as of the last run.
2360 */
2361 int mLastLaunches;
2362
2363 /**
2364 * The amount of time spent started when last unplugged (ms
2365 * in battery uptime).
2366 */
2367 long mUnpluggedStartTime;
2368
2369 /**
2370 * The number of starts when last unplugged.
2371 */
2372 int mUnpluggedStarts;
2373
2374 /**
2375 * The number of launches when last unplugged.
2376 */
2377 int mUnpluggedLaunches;
2378
2379 Serv() {
2380 mUnpluggables.add(this);
2381 }
2382
2383 public void unplug(long batteryUptime, long batteryRealtime) {
2384 mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime);
2385 mUnpluggedStarts = mStarts;
2386 mUnpluggedLaunches = mLaunches;
2387 }
2388
2389 public void plug(long batteryUptime, long batteryRealtime) {
2390 }
2391
2392 void readFromParcelLocked(Parcel in) {
2393 mStartTime = in.readLong();
2394 mRunningSince = in.readLong();
2395 mRunning = in.readInt() != 0;
2396 mStarts = in.readInt();
2397 mLaunchedTime = in.readLong();
2398 mLaunchedSince = in.readLong();
2399 mLaunched = in.readInt() != 0;
2400 mLaunches = in.readInt();
2401 mLoadedStartTime = in.readLong();
2402 mLoadedStarts = in.readInt();
2403 mLoadedLaunches = in.readInt();
2404 mLastStartTime = in.readLong();
2405 mLastStarts = in.readInt();
2406 mLastLaunches = in.readInt();
2407 mUnpluggedStartTime = in.readLong();
2408 mUnpluggedStarts = in.readInt();
2409 mUnpluggedLaunches = in.readInt();
2410 }
2411
2412 void writeToParcelLocked(Parcel out) {
2413 out.writeLong(mStartTime);
2414 out.writeLong(mRunningSince);
2415 out.writeInt(mRunning ? 1 : 0);
2416 out.writeInt(mStarts);
2417 out.writeLong(mLaunchedTime);
2418 out.writeLong(mLaunchedSince);
2419 out.writeInt(mLaunched ? 1 : 0);
2420 out.writeInt(mLaunches);
2421 out.writeLong(mLoadedStartTime);
2422 out.writeInt(mLoadedStarts);
2423 out.writeInt(mLoadedLaunches);
2424 out.writeLong(mLastStartTime);
2425 out.writeInt(mLastStarts);
2426 out.writeInt(mLastLaunches);
2427 out.writeLong(mUnpluggedStartTime);
2428 out.writeInt(mUnpluggedStarts);
2429 out.writeInt(mUnpluggedLaunches);
2430 }
2431
2432 long getLaunchTimeToNowLocked(long batteryUptime) {
2433 if (!mLaunched) return mLaunchedTime;
2434 return mLaunchedTime + batteryUptime - mLaunchedSince;
2435 }
2436
2437 long getStartTimeToNowLocked(long batteryUptime) {
2438 if (!mRunning) return mStartTime;
2439 return mStartTime + batteryUptime - mRunningSince;
2440 }
2441
2442 public void startLaunchedLocked() {
2443 if (!mLaunched) {
2444 mLaunches++;
2445 mLaunchedSince = getBatteryUptimeLocked();
2446 mLaunched = true;
2447 }
2448 }
2449
2450 public void stopLaunchedLocked() {
2451 if (mLaunched) {
2452 long time = getBatteryUptimeLocked() - mLaunchedSince;
2453 if (time > 0) {
2454 mLaunchedTime += time;
2455 } else {
2456 mLaunches--;
2457 }
2458 mLaunched = false;
2459 }
2460 }
2461
2462 public void startRunningLocked() {
2463 if (!mRunning) {
2464 mStarts++;
2465 mRunningSince = getBatteryUptimeLocked();
2466 mRunning = true;
2467 }
2468 }
2469
2470 public void stopRunningLocked() {
2471 if (mRunning) {
2472 long time = getBatteryUptimeLocked() - mRunningSince;
2473 if (time > 0) {
2474 mStartTime += time;
2475 } else {
2476 mStarts--;
2477 }
2478 mRunning = false;
2479 }
2480 }
2481
2482 public BatteryStatsImpl getBatteryStats() {
2483 return BatteryStatsImpl.this;
2484 }
2485
2486 @Override
2487 public int getLaunches(int which) {
2488 int val;
2489
2490 if (which == STATS_LAST) {
2491 val = mLastLaunches;
2492 } else {
2493 val = mLaunches;
2494 if (which == STATS_CURRENT) {
2495 val -= mLoadedLaunches;
2496 } else if (which == STATS_UNPLUGGED) {
2497 val -= mUnpluggedLaunches;
2498 }
2499 }
2500
2501 return val;
2502 }
2503
2504 @Override
2505 public long getStartTime(long now, int which) {
2506 long val;
2507 if (which == STATS_LAST) {
2508 val = mLastStartTime;
2509 } else {
2510 val = getStartTimeToNowLocked(now);
2511 if (which == STATS_CURRENT) {
2512 val -= mLoadedStartTime;
2513 } else if (which == STATS_UNPLUGGED) {
2514 val -= mUnpluggedStartTime;
2515 }
2516 }
2517
2518 return val;
2519 }
2520
2521 @Override
2522 public int getStarts(int which) {
2523 int val;
2524 if (which == STATS_LAST) {
2525 val = mLastStarts;
2526 } else {
2527 val = mStarts;
2528 if (which == STATS_CURRENT) {
2529 val -= mLoadedStarts;
2530 } else if (which == STATS_UNPLUGGED) {
2531 val -= mUnpluggedStarts;
2532 }
2533 }
2534
2535 return val;
2536 }
2537 }
2538
2539 public BatteryStatsImpl getBatteryStats() {
2540 return BatteryStatsImpl.this;
2541 }
2542
2543 public void incWakeupsLocked() {
2544 mWakeups++;
2545 }
2546
2547 final Serv newServiceStatsLocked() {
2548 return new Serv();
2549 }
2550 }
2551
2552 /**
2553 * Retrieve the statistics object for a particular process, creating
2554 * if needed.
2555 */
2556 public Proc getProcessStatsLocked(String name) {
2557 Proc ps = mProcessStats.get(name);
2558 if (ps == null) {
2559 ps = new Proc();
2560 mProcessStats.put(name, ps);
2561 }
2562
2563 return ps;
2564 }
2565
2566 /**
2567 * Retrieve the statistics object for a particular service, creating
2568 * if needed.
2569 */
2570 public Pkg getPackageStatsLocked(String name) {
2571 Pkg ps = mPackageStats.get(name);
2572 if (ps == null) {
2573 ps = new Pkg();
2574 mPackageStats.put(name, ps);
2575 }
2576
2577 return ps;
2578 }
2579
2580 /**
2581 * Retrieve the statistics object for a particular service, creating
2582 * if needed.
2583 */
2584 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
2585 Pkg ps = getPackageStatsLocked(pkg);
2586 Pkg.Serv ss = ps.mServiceStats.get(serv);
2587 if (ss == null) {
2588 ss = ps.newServiceStatsLocked();
2589 ps.mServiceStats.put(serv, ss);
2590 }
2591
2592 return ss;
2593 }
2594
Evan Millarc64edde2009-04-18 12:26:32 -07002595 public StopwatchTimer getWakeTimerLocked(String name, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002596 Wakelock wl = mWakelockStats.get(name);
2597 if (wl == null) {
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08002598 if (mWakelockStats.size() > MAX_WAKELOCKS_PER_UID) {
2599 name = BATCHED_WAKELOCK_NAME;
2600 wl = mWakelockStats.get(name);
2601 }
2602 if (wl == null) {
2603 wl = new Wakelock();
2604 mWakelockStats.put(name, wl);
2605 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002606 }
Evan Millarc64edde2009-04-18 12:26:32 -07002607 StopwatchTimer t = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002608 switch (type) {
2609 case WAKE_TYPE_PARTIAL:
2610 t = wl.mTimerPartial;
2611 if (t == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002612 t = new StopwatchTimer(WAKE_TYPE_PARTIAL, mPartialTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002613 wl.mTimerPartial = t;
2614 }
2615 return t;
2616 case WAKE_TYPE_FULL:
2617 t = wl.mTimerFull;
2618 if (t == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002619 t = new StopwatchTimer(WAKE_TYPE_FULL, mFullTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002620 wl.mTimerFull = t;
2621 }
2622 return t;
2623 case WAKE_TYPE_WINDOW:
2624 t = wl.mTimerWindow;
2625 if (t == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002626 t = new StopwatchTimer(WAKE_TYPE_WINDOW, mWindowTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002627 wl.mTimerWindow = t;
2628 }
2629 return t;
2630 default:
2631 throw new IllegalArgumentException("type=" + type);
2632 }
2633 }
2634
Evan Millarc64edde2009-04-18 12:26:32 -07002635 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002636 Sensor se = mSensorStats.get(sensor);
2637 if (se == null) {
2638 if (!create) {
2639 return null;
2640 }
2641 se = new Sensor(sensor);
2642 mSensorStats.put(sensor, se);
2643 }
Evan Millarc64edde2009-04-18 12:26:32 -07002644 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002645 if (t != null) {
2646 return t;
2647 }
Evan Millarc64edde2009-04-18 12:26:32 -07002648 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002649 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002650 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002651 mSensorTimers.put(sensor, timers);
2652 }
Evan Millarc64edde2009-04-18 12:26:32 -07002653 t = new StopwatchTimer(BatteryStats.SENSOR, timers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002654 se.mTimer = t;
2655 return t;
2656 }
2657
2658 public void noteStartWakeLocked(String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07002659 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002660 if (t != null) {
2661 t.startRunningLocked(BatteryStatsImpl.this);
2662 }
2663 }
2664
2665 public void noteStopWakeLocked(String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07002666 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002667 if (t != null) {
2668 t.stopRunningLocked(BatteryStatsImpl.this);
2669 }
2670 }
2671
2672 public void noteStartSensor(int sensor) {
Evan Millarc64edde2009-04-18 12:26:32 -07002673 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002674 if (t != null) {
2675 t.startRunningLocked(BatteryStatsImpl.this);
2676 }
2677 }
2678
2679 public void noteStopSensor(int sensor) {
2680 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07002681 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002682 if (t != null) {
2683 t.stopRunningLocked(BatteryStatsImpl.this);
2684 }
2685 }
2686
2687 public void noteStartGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07002688 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002689 if (t != null) {
2690 t.startRunningLocked(BatteryStatsImpl.this);
2691 }
2692 }
2693
2694 public void noteStopGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07002695 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002696 if (t != null) {
2697 t.stopRunningLocked(BatteryStatsImpl.this);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002698 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002699 }
2700
2701 public BatteryStatsImpl getBatteryStats() {
2702 return BatteryStatsImpl.this;
2703 }
2704 }
2705
2706 public BatteryStatsImpl(String filename) {
2707 mFile = new File(filename);
2708 mBackupFile = new File(filename + ".bak");
2709 mStartCount++;
Evan Millarc64edde2009-04-18 12:26:32 -07002710 mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002711 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07002712 mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002713 }
2714 mInputEventCounter = new Counter(mUnpluggables);
Evan Millarc64edde2009-04-18 12:26:32 -07002715 mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002716 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07002717 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002718 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07002719 mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002720 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07002721 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002722 }
Evan Millarc64edde2009-04-18 12:26:32 -07002723 mWifiOnTimer = new StopwatchTimer(-3, null, mUnpluggables);
2724 mWifiRunningTimer = new StopwatchTimer(-4, null, mUnpluggables);
2725 mBluetoothOnTimer = new StopwatchTimer(-5, null, mUnpluggables);
Mike Chan18d200f2010-02-02 10:33:45 -08002726 mAudioOnTimer = new StopwatchTimer(-6, null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002727 mOnBattery = mOnBatteryInternal = false;
2728 mTrackBatteryPastUptime = 0;
2729 mTrackBatteryPastRealtime = 0;
2730 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
2731 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
2732 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
2733 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
Evan Millar633a1742009-04-02 16:36:33 -07002734 mDischargeStartLevel = 0;
2735 mDischargeCurrentLevel = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002736 }
2737
2738 public BatteryStatsImpl(Parcel p) {
2739 mFile = mBackupFile = null;
2740 readFromParcel(p);
2741 }
2742
Amith Yamasanie43530a2009-08-21 13:11:37 -07002743 public void setNumSpeedSteps(int steps) {
2744 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
2745 }
2746
Amith Yamasanif37447b2009-10-08 18:28:01 -07002747 public void setRadioScanningTimeout(long timeout) {
2748 if (mPhoneSignalScanningTimer != null) {
2749 mPhoneSignalScanningTimer.setTimeout(timeout);
2750 }
2751 }
2752
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002753 @Override
2754 public int getStartCount() {
2755 return mStartCount;
2756 }
2757
2758 public boolean isOnBattery() {
2759 return mOnBattery;
2760 }
2761
The Android Open Source Project10592532009-03-18 17:39:46 -07002762 public void setOnBattery(boolean onBattery, int level) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002763 synchronized(this) {
Evan Millarc64edde2009-04-18 12:26:32 -07002764 updateKernelWakelocksLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002765 if (mOnBattery != onBattery) {
2766 mOnBattery = mOnBatteryInternal = onBattery;
2767
2768 long uptime = SystemClock.uptimeMillis() * 1000;
2769 long mSecRealtime = SystemClock.elapsedRealtime();
2770 long realtime = mSecRealtime * 1000;
2771 if (onBattery) {
2772 mTrackBatteryUptimeStart = uptime;
2773 mTrackBatteryRealtimeStart = realtime;
2774 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
2775 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
Evan Millar633a1742009-04-02 16:36:33 -07002776 mDischargeCurrentLevel = mDischargeStartLevel = level;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002777 doUnplug(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
2778 } else {
2779 mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
2780 mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
Evan Millar633a1742009-04-02 16:36:33 -07002781 mDischargeCurrentLevel = level;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002782 doPlug(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
2783 }
2784 if ((mLastWriteTime + (60 * 1000)) < mSecRealtime) {
2785 if (mFile != null) {
2786 writeLocked();
2787 }
2788 }
2789 }
2790 }
2791 }
Evan Millar633a1742009-04-02 16:36:33 -07002792
2793 public void recordCurrentLevel(int level) {
2794 mDischargeCurrentLevel = level;
2795 }
Evan Millarc64edde2009-04-18 12:26:32 -07002796
2797 public void updateKernelWakelocksLocked() {
2798 Map<String, KernelWakelockStats> m = readKernelWakelockStats();
2799
Marco Nelissend8593312009-04-30 14:45:06 -07002800 if (m == null) {
2801 // Not crashing might make board bringup easier.
2802 Log.w(TAG, "Couldn't get kernel wake lock stats");
2803 return;
2804 }
2805
Evan Millarc64edde2009-04-18 12:26:32 -07002806 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) {
2807 String name = ent.getKey();
2808 KernelWakelockStats kws = ent.getValue();
2809
2810 SamplingTimer kwlt = mKernelWakelockStats.get(name);
2811 if (kwlt == null) {
2812 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
2813 true /* track reported values */);
2814 mKernelWakelockStats.put(name, kwlt);
2815 }
2816 kwlt.updateCurrentReportedCount(kws.mCount);
2817 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
2818 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion);
2819 }
2820
2821 if (m.size() != mKernelWakelockStats.size()) {
2822 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
2823 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
2824 SamplingTimer st = ent.getValue();
2825 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) {
2826 st.setStale();
2827 }
2828 }
2829 }
2830 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002831
2832 public long getAwakeTimeBattery() {
2833 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
2834 }
2835
2836 public long getAwakeTimePlugged() {
2837 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
2838 }
2839
2840 @Override
2841 public long computeUptime(long curTime, int which) {
2842 switch (which) {
2843 case STATS_TOTAL: return mUptime + (curTime-mUptimeStart);
2844 case STATS_LAST: return mLastUptime;
2845 case STATS_CURRENT: return (curTime-mUptimeStart);
2846 case STATS_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart);
2847 }
2848 return 0;
2849 }
2850
2851 @Override
2852 public long computeRealtime(long curTime, int which) {
2853 switch (which) {
2854 case STATS_TOTAL: return mRealtime + (curTime-mRealtimeStart);
2855 case STATS_LAST: return mLastRealtime;
2856 case STATS_CURRENT: return (curTime-mRealtimeStart);
2857 case STATS_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart);
2858 }
2859 return 0;
2860 }
2861
2862 @Override
2863 public long computeBatteryUptime(long curTime, int which) {
2864 switch (which) {
2865 case STATS_TOTAL:
2866 return mBatteryUptime + getBatteryUptime(curTime);
2867 case STATS_LAST:
2868 return mBatteryLastUptime;
2869 case STATS_CURRENT:
2870 return getBatteryUptime(curTime);
2871 case STATS_UNPLUGGED:
2872 return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime;
2873 }
2874 return 0;
2875 }
2876
2877 @Override
2878 public long computeBatteryRealtime(long curTime, int which) {
2879 switch (which) {
2880 case STATS_TOTAL:
2881 return mBatteryRealtime + getBatteryRealtimeLocked(curTime);
2882 case STATS_LAST:
2883 return mBatteryLastRealtime;
2884 case STATS_CURRENT:
2885 return getBatteryRealtimeLocked(curTime);
2886 case STATS_UNPLUGGED:
2887 return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime;
2888 }
2889 return 0;
2890 }
2891
2892 long getBatteryUptimeLocked(long curTime) {
2893 long time = mTrackBatteryPastUptime;
2894 if (mOnBatteryInternal) {
2895 time += curTime - mTrackBatteryUptimeStart;
2896 }
2897 return time;
2898 }
2899
2900 long getBatteryUptimeLocked() {
2901 return getBatteryUptime(SystemClock.uptimeMillis() * 1000);
2902 }
2903
2904 @Override
2905 public long getBatteryUptime(long curTime) {
2906 return getBatteryUptimeLocked(curTime);
2907 }
2908
2909 long getBatteryRealtimeLocked(long curTime) {
2910 long time = mTrackBatteryPastRealtime;
2911 if (mOnBatteryInternal) {
2912 time += curTime - mTrackBatteryRealtimeStart;
2913 }
2914 return time;
2915 }
2916
2917 @Override
2918 public long getBatteryRealtime(long curTime) {
2919 return getBatteryRealtimeLocked(curTime);
2920 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002921
2922 private long getTcpBytes(long current, long[] dataBytes, int which) {
2923 if (which == STATS_LAST) {
2924 return dataBytes[STATS_LAST];
2925 } else {
2926 if (which == STATS_UNPLUGGED) {
2927 if (dataBytes[STATS_UNPLUGGED] < 0) {
2928 return dataBytes[STATS_LAST];
2929 } else {
2930 return current - dataBytes[STATS_UNPLUGGED];
2931 }
2932 } else if (which == STATS_TOTAL) {
2933 return (current - dataBytes[STATS_CURRENT]) + dataBytes[STATS_TOTAL];
2934 }
2935 return current - dataBytes[STATS_CURRENT];
2936 }
2937 }
2938
2939 /** Only STATS_UNPLUGGED works properly */
2940 public long getMobileTcpBytesSent(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08002941 return getTcpBytes(TrafficStats.getMobileTxBytes(), mMobileDataTx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002942 }
2943
2944 /** Only STATS_UNPLUGGED works properly */
2945 public long getMobileTcpBytesReceived(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08002946 return getTcpBytes(TrafficStats.getMobileRxBytes(), mMobileDataRx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002947 }
2948
2949 /** Only STATS_UNPLUGGED works properly */
2950 public long getTotalTcpBytesSent(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08002951 return getTcpBytes(TrafficStats.getTotalTxBytes(), mTotalDataTx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002952 }
2953
2954 /** Only STATS_UNPLUGGED works properly */
2955 public long getTotalTcpBytesReceived(int which) {
Ken Shirriff1719a392009-12-07 15:57:35 -08002956 return getTcpBytes(TrafficStats.getTotalRxBytes(), mTotalDataRx, which);
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002957 }
2958
The Android Open Source Project10592532009-03-18 17:39:46 -07002959 @Override
Evan Millar633a1742009-04-02 16:36:33 -07002960 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002961 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07002962 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002963 }
2964 }
2965
Evan Millar633a1742009-04-02 16:36:33 -07002966 public int getDischargeStartLevelLocked() {
2967 return mDischargeStartLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07002968 }
2969
2970 @Override
Evan Millar633a1742009-04-02 16:36:33 -07002971 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002972 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07002973 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002974 }
2975 }
2976
Evan Millar633a1742009-04-02 16:36:33 -07002977 public int getDischargeCurrentLevelLocked() {
2978 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07002979 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002980
Amith Yamasanie43530a2009-08-21 13:11:37 -07002981 @Override
2982 public int getCpuSpeedSteps() {
2983 return sNumSpeedSteps;
2984 }
2985
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002986 /**
2987 * Retrieve the statistics object for a particular uid, creating if needed.
2988 */
2989 public Uid getUidStatsLocked(int uid) {
2990 Uid u = mUidStats.get(uid);
2991 if (u == null) {
2992 u = new Uid(uid);
2993 mUidStats.put(uid, u);
2994 }
2995 return u;
2996 }
2997
2998 /**
2999 * Remove the statistics object for a particular uid.
3000 */
3001 public void removeUidStatsLocked(int uid) {
3002 mUidStats.remove(uid);
3003 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07003004
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003005 /**
3006 * Retrieve the statistics object for a particular process, creating
3007 * if needed.
3008 */
3009 public Uid.Proc getProcessStatsLocked(int uid, String name) {
3010 Uid u = getUidStatsLocked(uid);
3011 return u.getProcessStatsLocked(name);
3012 }
3013
3014 /**
Amith Yamasani32dbefd2009-06-19 09:21:17 -07003015 * Retrieve the statistics object for a particular process, given
3016 * the name of the process.
3017 * @param name process name
3018 * @return the statistics object for the process
3019 */
Amith Yamasani819f9282009-06-24 23:18:15 -07003020 public Uid.Proc getProcessStatsLocked(String name, int pid) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -07003021 int uid;
3022 if (mUidCache.containsKey(name)) {
3023 uid = mUidCache.get(name);
3024 } else {
Amith Yamasani819f9282009-06-24 23:18:15 -07003025 uid = Process.getUidForPid(pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07003026 mUidCache.put(name, uid);
3027 }
3028 Uid u = getUidStatsLocked(uid);
3029 return u.getProcessStatsLocked(name);
3030 }
3031
3032 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003033 * Retrieve the statistics object for a particular process, creating
3034 * if needed.
3035 */
3036 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
3037 Uid u = getUidStatsLocked(uid);
3038 return u.getPackageStatsLocked(pkg);
3039 }
3040
3041 /**
3042 * Retrieve the statistics object for a particular service, creating
3043 * if needed.
3044 */
3045 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
3046 Uid u = getUidStatsLocked(uid);
3047 return u.getServiceStatsLocked(pkg, name);
3048 }
3049
3050 public void writeLocked() {
3051 if ((mFile == null) || (mBackupFile == null)) {
3052 Log.w("BatteryStats", "writeLocked: no file associated with this instance");
3053 return;
3054 }
3055
3056 // Keep the old file around until we know the new one has
3057 // been successfully written.
3058 if (mFile.exists()) {
3059 if (mBackupFile.exists()) {
3060 mBackupFile.delete();
3061 }
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07003062 if (!mFile.renameTo(mBackupFile)) {
3063 Log.w("BatteryStats", "Failed to back up file before writing new stats");
3064 return;
3065 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003066 }
3067
3068 try {
3069 FileOutputStream stream = new FileOutputStream(mFile);
3070 Parcel out = Parcel.obtain();
3071 writeSummaryToParcel(out);
3072 stream.write(out.marshall());
3073 out.recycle();
3074
3075 stream.flush();
3076 stream.close();
3077 mBackupFile.delete();
3078
3079 mLastWriteTime = SystemClock.elapsedRealtime();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07003080 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003081 } catch (IOException e) {
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07003082 Log.w("BatteryStats", "Error writing battery statistics", e);
3083 }
3084 if (mFile.exists()) {
3085 if (!mFile.delete()) {
3086 Log.w(TAG, "Failed to delete mangled file " + mFile);
3087 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003088 }
3089 }
3090
3091 static byte[] readFully(FileInputStream stream) throws java.io.IOException {
3092 int pos = 0;
3093 int avail = stream.available();
3094 byte[] data = new byte[avail];
3095 while (true) {
3096 int amt = stream.read(data, pos, data.length-pos);
3097 //Log.i("foo", "Read " + amt + " bytes at " + pos
3098 // + " of avail " + data.length);
3099 if (amt <= 0) {
3100 //Log.i("foo", "**** FINISHED READING: pos=" + pos
3101 // + " len=" + data.length);
3102 return data;
3103 }
3104 pos += amt;
3105 avail = stream.available();
3106 if (avail > data.length-pos) {
3107 byte[] newData = new byte[pos+avail];
3108 System.arraycopy(data, 0, newData, 0, pos);
3109 data = newData;
3110 }
3111 }
3112 }
3113
3114 public void readLocked() {
3115 if ((mFile == null) || (mBackupFile == null)) {
3116 Log.w("BatteryStats", "readLocked: no file associated with this instance");
3117 return;
3118 }
3119
3120 mUidStats.clear();
3121
3122 FileInputStream stream = null;
3123 if (mBackupFile.exists()) {
3124 try {
3125 stream = new FileInputStream(mBackupFile);
3126 } catch (java.io.IOException e) {
3127 // We'll try for the normal settings file.
3128 }
3129 }
3130
3131 try {
3132 if (stream == null) {
3133 if (!mFile.exists()) {
3134 return;
3135 }
3136 stream = new FileInputStream(mFile);
3137 }
3138
3139 byte[] raw = readFully(stream);
3140 Parcel in = Parcel.obtain();
3141 in.unmarshall(raw, 0, raw.length);
3142 in.setDataPosition(0);
3143 stream.close();
3144
3145 readSummaryFromParcel(in);
3146 } catch(java.io.IOException e) {
3147 Log.e("BatteryStats", "Error reading battery statistics", e);
3148 }
3149 }
3150
3151 public int describeContents() {
3152 return 0;
3153 }
3154
3155 private void readSummaryFromParcel(Parcel in) {
3156 final int version = in.readInt();
3157 if (version != VERSION) {
3158 Log.w("BatteryStats", "readFromParcel: version got " + version
3159 + ", expected " + VERSION + "; erasing old stats");
3160 return;
3161 }
3162
3163 mStartCount = in.readInt();
3164 mBatteryUptime = in.readLong();
3165 mBatteryLastUptime = in.readLong();
3166 mBatteryRealtime = in.readLong();
3167 mBatteryLastRealtime = in.readLong();
3168 mUptime = in.readLong();
3169 mLastUptime = in.readLong();
3170 mRealtime = in.readLong();
3171 mLastRealtime = in.readLong();
Evan Millar633a1742009-04-02 16:36:33 -07003172 mDischargeStartLevel = in.readInt();
3173 mDischargeCurrentLevel = in.readInt();
The Android Open Source Project10592532009-03-18 17:39:46 -07003174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003175 mStartCount++;
3176
3177 mScreenOn = false;
3178 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003179 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
3180 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
3181 }
3182 mInputEventCounter.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003183 mPhoneOn = false;
3184 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003185 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
3186 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
3187 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07003188 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003189 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
3190 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
3191 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003192 mWifiOn = false;
3193 mWifiOnTimer.readSummaryFromParcelLocked(in);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003194 mWifiRunning = false;
3195 mWifiRunningTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07003196 mBluetoothOn = false;
3197 mBluetoothOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003198
Evan Millarc64edde2009-04-18 12:26:32 -07003199 int NKW = in.readInt();
3200 for (int ikw = 0; ikw < NKW; ikw++) {
3201 if (in.readInt() != 0) {
3202 String kwltName = in.readString();
3203 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
3204 }
3205 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003206
3207 sNumSpeedSteps = in.readInt();
3208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003209 final int NU = in.readInt();
3210 for (int iu = 0; iu < NU; iu++) {
3211 int uid = in.readInt();
3212 Uid u = new Uid(uid);
3213 mUidStats.put(uid, u);
3214
Dianne Hackborn617f8772009-03-31 15:04:46 -07003215 u.mWifiTurnedOn = false;
3216 u.mWifiTurnedOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07003217 u.mFullWifiLockOut = false;
3218 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003219 u.mAudioTurnedOn = false;
3220 u.mAudioTurnedOnTimer.readSummaryFromParcelLocked(in);
3221 u.mVideoTurnedOn = false;
3222 u.mVideoTurnedOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07003223 u.mScanWifiLockOut = false;
3224 u.mScanWifiLockTimer.readSummaryFromParcelLocked(in);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003225 u.mWifiMulticastEnabled = false;
3226 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
3227
Dianne Hackborn617f8772009-03-31 15:04:46 -07003228 if (in.readInt() != 0) {
3229 if (u.mUserActivityCounters == null) {
3230 u.initUserActivityLocked();
3231 }
3232 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
3233 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
3234 }
3235 }
3236
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003237 int NW = in.readInt();
3238 for (int iw = 0; iw < NW; iw++) {
3239 String wlName = in.readString();
3240 if (in.readInt() != 0) {
3241 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
3242 }
3243 if (in.readInt() != 0) {
3244 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
3245 }
3246 if (in.readInt() != 0) {
3247 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
3248 }
3249 }
3250
3251 int NP = in.readInt();
3252 for (int is = 0; is < NP; is++) {
3253 int seNumber = in.readInt();
3254 if (in.readInt() != 0) {
3255 u.getSensorTimerLocked(seNumber, true)
3256 .readSummaryFromParcelLocked(in);
3257 }
3258 }
3259
3260 NP = in.readInt();
3261 for (int ip = 0; ip < NP; ip++) {
3262 String procName = in.readString();
3263 Uid.Proc p = u.getProcessStatsLocked(procName);
3264 p.mUserTime = p.mLoadedUserTime = in.readLong();
3265 p.mLastUserTime = in.readLong();
3266 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
3267 p.mLastSystemTime = in.readLong();
3268 p.mStarts = p.mLoadedStarts = in.readInt();
3269 p.mLastStarts = in.readInt();
3270 }
3271
3272 NP = in.readInt();
3273 for (int ip = 0; ip < NP; ip++) {
3274 String pkgName = in.readString();
3275 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
3276 p.mWakeups = p.mLoadedWakeups = in.readInt();
3277 p.mLastWakeups = in.readInt();
3278 final int NS = in.readInt();
3279 for (int is = 0; is < NS; is++) {
3280 String servName = in.readString();
3281 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
3282 s.mStartTime = s.mLoadedStartTime = in.readLong();
3283 s.mLastStartTime = in.readLong();
3284 s.mStarts = s.mLoadedStarts = in.readInt();
3285 s.mLastStarts = in.readInt();
3286 s.mLaunches = s.mLoadedLaunches = in.readInt();
3287 s.mLastLaunches = in.readInt();
3288 }
3289 }
3290
3291 u.mLoadedTcpBytesReceived = in.readLong();
3292 u.mLoadedTcpBytesSent = in.readLong();
3293 }
3294 }
3295
3296 /**
3297 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
3298 * disk. This format does not allow a lossless round-trip.
3299 *
3300 * @param out the Parcel to be written to.
3301 */
3302 public void writeSummaryToParcel(Parcel out) {
3303 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
3304 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
3305 final long NOW = getBatteryUptimeLocked(NOW_SYS);
3306 final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS);
3307
3308 out.writeInt(VERSION);
3309
3310 out.writeInt(mStartCount);
3311 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_TOTAL));
3312 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_CURRENT));
3313 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_TOTAL));
3314 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_CURRENT));
3315 out.writeLong(computeUptime(NOW_SYS, STATS_TOTAL));
3316 out.writeLong(computeUptime(NOW_SYS, STATS_CURRENT));
3317 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_TOTAL));
3318 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_CURRENT));
Evan Millar633a1742009-04-02 16:36:33 -07003319 out.writeInt(mDischargeStartLevel);
3320 out.writeInt(mDischargeCurrentLevel);
The Android Open Source Project10592532009-03-18 17:39:46 -07003321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003322
3323 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003324 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
3325 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
3326 }
3327 mInputEventCounter.writeSummaryFromParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003328 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003329 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
3330 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
3331 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07003332 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003333 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
3334 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
3335 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003336 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003337 mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07003338 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003339
Evan Millarc64edde2009-04-18 12:26:32 -07003340 out.writeInt(mKernelWakelockStats.size());
3341 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
3342 Timer kwlt = ent.getValue();
3343 if (kwlt != null) {
3344 out.writeInt(1);
3345 out.writeString(ent.getKey());
3346 ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL);
3347 } else {
3348 out.writeInt(0);
3349 }
3350 }
3351
Amith Yamasanie43530a2009-08-21 13:11:37 -07003352 out.writeInt(sNumSpeedSteps);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003353 final int NU = mUidStats.size();
3354 out.writeInt(NU);
3355 for (int iu = 0; iu < NU; iu++) {
3356 out.writeInt(mUidStats.keyAt(iu));
3357 Uid u = mUidStats.valueAt(iu);
The Android Open Source Project10592532009-03-18 17:39:46 -07003358
Dianne Hackborn617f8772009-03-31 15:04:46 -07003359 u.mWifiTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07003360 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Amith Yamasanic33fe6c2009-05-27 15:29:04 -07003361 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
3362 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07003363 u.mScanWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003364 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003365
Dianne Hackborn617f8772009-03-31 15:04:46 -07003366 if (u.mUserActivityCounters == null) {
3367 out.writeInt(0);
3368 } else {
3369 out.writeInt(1);
3370 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
3371 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
3372 }
3373 }
3374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003375 int NW = u.mWakelockStats.size();
3376 out.writeInt(NW);
3377 if (NW > 0) {
3378 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent
3379 : u.mWakelockStats.entrySet()) {
3380 out.writeString(ent.getKey());
3381 Uid.Wakelock wl = ent.getValue();
3382 if (wl.mTimerFull != null) {
3383 out.writeInt(1);
3384 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL);
3385 } else {
3386 out.writeInt(0);
3387 }
3388 if (wl.mTimerPartial != null) {
3389 out.writeInt(1);
3390 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL);
3391 } else {
3392 out.writeInt(0);
3393 }
3394 if (wl.mTimerWindow != null) {
3395 out.writeInt(1);
3396 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL);
3397 } else {
3398 out.writeInt(0);
3399 }
3400 }
3401 }
3402
3403 int NSE = u.mSensorStats.size();
3404 out.writeInt(NSE);
3405 if (NSE > 0) {
3406 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent
3407 : u.mSensorStats.entrySet()) {
3408 out.writeInt(ent.getKey());
3409 Uid.Sensor se = ent.getValue();
3410 if (se.mTimer != null) {
3411 out.writeInt(1);
3412 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL);
3413 } else {
3414 out.writeInt(0);
3415 }
3416 }
3417 }
3418
3419 int NP = u.mProcessStats.size();
3420 out.writeInt(NP);
3421 if (NP > 0) {
3422 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent
3423 : u.mProcessStats.entrySet()) {
3424 out.writeString(ent.getKey());
3425 Uid.Proc ps = ent.getValue();
3426 out.writeLong(ps.mUserTime);
3427 out.writeLong(ps.mUserTime - ps.mLoadedUserTime);
3428 out.writeLong(ps.mSystemTime);
3429 out.writeLong(ps.mSystemTime - ps.mLoadedSystemTime);
3430 out.writeInt(ps.mStarts);
3431 out.writeInt(ps.mStarts - ps.mLoadedStarts);
3432 }
3433 }
3434
3435 NP = u.mPackageStats.size();
3436 out.writeInt(NP);
3437 if (NP > 0) {
3438 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
3439 : u.mPackageStats.entrySet()) {
3440 out.writeString(ent.getKey());
3441 Uid.Pkg ps = ent.getValue();
3442 out.writeInt(ps.mWakeups);
3443 out.writeInt(ps.mWakeups - ps.mLoadedWakeups);
3444 final int NS = ps.mServiceStats.size();
3445 out.writeInt(NS);
3446 if (NS > 0) {
3447 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
3448 : ps.mServiceStats.entrySet()) {
3449 out.writeString(sent.getKey());
3450 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
3451 long time = ss.getStartTimeToNowLocked(NOW);
3452 out.writeLong(time);
3453 out.writeLong(time - ss.mLoadedStartTime);
3454 out.writeInt(ss.mStarts);
3455 out.writeInt(ss.mStarts - ss.mLoadedStarts);
3456 out.writeInt(ss.mLaunches);
3457 out.writeInt(ss.mLaunches - ss.mLoadedLaunches);
3458 }
3459 }
3460 }
3461 }
3462
3463 out.writeLong(u.getTcpBytesReceived(STATS_TOTAL));
3464 out.writeLong(u.getTcpBytesSent(STATS_TOTAL));
3465 }
3466 }
3467
3468 public void readFromParcel(Parcel in) {
3469 readFromParcelLocked(in);
3470 }
3471
3472 void readFromParcelLocked(Parcel in) {
3473 int magic = in.readInt();
3474 if (magic != MAGIC) {
3475 throw new ParcelFormatException("Bad magic number");
3476 }
3477
3478 mStartCount = in.readInt();
3479 mBatteryUptime = in.readLong();
3480 mBatteryLastUptime = in.readLong();
3481 mBatteryRealtime = in.readLong();
3482 mBatteryLastRealtime = in.readLong();
3483 mScreenOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003484 mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003485 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07003486 mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003487 }
3488 mInputEventCounter = new Counter(mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003489 mPhoneOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003490 mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003491 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07003492 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003493 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07003494 mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003495 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07003496 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003497 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003498 mWifiOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003499 mWifiOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003500 mWifiRunning = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003501 mWifiRunningTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07003502 mBluetoothOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003503 mBluetoothOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003504 mUptime = in.readLong();
3505 mUptimeStart = in.readLong();
3506 mLastUptime = in.readLong();
3507 mRealtime = in.readLong();
3508 mRealtimeStart = in.readLong();
3509 mLastRealtime = in.readLong();
3510 mOnBattery = in.readInt() != 0;
3511 mOnBatteryInternal = false; // we are no longer really running.
3512 mTrackBatteryPastUptime = in.readLong();
3513 mTrackBatteryUptimeStart = in.readLong();
3514 mTrackBatteryPastRealtime = in.readLong();
3515 mTrackBatteryRealtimeStart = in.readLong();
3516 mUnpluggedBatteryUptime = in.readLong();
3517 mUnpluggedBatteryRealtime = in.readLong();
Evan Millar633a1742009-04-02 16:36:33 -07003518 mDischargeStartLevel = in.readInt();
3519 mDischargeCurrentLevel = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003520 mLastWriteTime = in.readLong();
3521
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003522 mMobileDataRx[STATS_LAST] = in.readLong();
3523 mMobileDataRx[STATS_UNPLUGGED] = -1;
3524 mMobileDataTx[STATS_LAST] = in.readLong();
3525 mMobileDataTx[STATS_UNPLUGGED] = -1;
3526 mTotalDataRx[STATS_LAST] = in.readLong();
3527 mTotalDataRx[STATS_UNPLUGGED] = -1;
3528 mTotalDataTx[STATS_LAST] = in.readLong();
3529 mTotalDataTx[STATS_UNPLUGGED] = -1;
3530
3531 mRadioDataUptime = in.readLong();
3532 mRadioDataStart = -1;
3533
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07003534 mBluetoothPingCount = in.readInt();
3535 mBluetoothPingStart = -1;
3536
Evan Millarc64edde2009-04-18 12:26:32 -07003537 mKernelWakelockStats.clear();
3538 int NKW = in.readInt();
3539 for (int ikw = 0; ikw < NKW; ikw++) {
3540 if (in.readInt() != 0) {
3541 String wakelockName = in.readString();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003542 in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel
Evan Millarc64edde2009-04-18 12:26:32 -07003543 SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in);
3544 mKernelWakelockStats.put(wakelockName, kwlt);
3545 }
3546 }
3547
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003548 mPartialTimers.clear();
3549 mFullTimers.clear();
3550 mWindowTimers.clear();
3551
Amith Yamasanie43530a2009-08-21 13:11:37 -07003552 sNumSpeedSteps = in.readInt();
3553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003554 int numUids = in.readInt();
3555 mUidStats.clear();
3556 for (int i = 0; i < numUids; i++) {
3557 int uid = in.readInt();
3558 Uid u = new Uid(uid);
3559 u.readFromParcelLocked(mUnpluggables, in);
3560 mUidStats.append(uid, u);
3561 }
3562 }
3563
3564 public void writeToParcel(Parcel out, int flags) {
3565 writeToParcelLocked(out, flags);
3566 }
3567
3568 @SuppressWarnings("unused")
3569 void writeToParcelLocked(Parcel out, int flags) {
3570 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
3571 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
3572 final long batteryUptime = getBatteryUptimeLocked(uSecUptime);
3573 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
3574
3575 out.writeInt(MAGIC);
3576 out.writeInt(mStartCount);
3577 out.writeLong(mBatteryUptime);
3578 out.writeLong(mBatteryLastUptime);
3579 out.writeLong(mBatteryRealtime);
3580 out.writeLong(mBatteryLastRealtime);
3581 mScreenOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003582 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
3583 mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime);
3584 }
3585 mInputEventCounter.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003586 mPhoneOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003587 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
3588 mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
3589 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07003590 mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003591 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
3592 mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime);
3593 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003594 mWifiOnTimer.writeToParcel(out, batteryRealtime);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003595 mWifiRunningTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003596 mBluetoothOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003597 out.writeLong(mUptime);
3598 out.writeLong(mUptimeStart);
3599 out.writeLong(mLastUptime);
3600 out.writeLong(mRealtime);
3601 out.writeLong(mRealtimeStart);
3602 out.writeLong(mLastRealtime);
3603 out.writeInt(mOnBattery ? 1 : 0);
3604 out.writeLong(batteryUptime);
3605 out.writeLong(mTrackBatteryUptimeStart);
3606 out.writeLong(batteryRealtime);
3607 out.writeLong(mTrackBatteryRealtimeStart);
3608 out.writeLong(mUnpluggedBatteryUptime);
3609 out.writeLong(mUnpluggedBatteryRealtime);
Evan Millar633a1742009-04-02 16:36:33 -07003610 out.writeInt(mDischargeStartLevel);
3611 out.writeInt(mDischargeCurrentLevel);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003612 out.writeLong(mLastWriteTime);
3613
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003614 out.writeLong(getMobileTcpBytesReceived(STATS_UNPLUGGED));
3615 out.writeLong(getMobileTcpBytesSent(STATS_UNPLUGGED));
3616 out.writeLong(getTotalTcpBytesReceived(STATS_UNPLUGGED));
3617 out.writeLong(getTotalTcpBytesSent(STATS_UNPLUGGED));
3618
3619 // Write radio uptime for data
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07003620 out.writeLong(getRadioDataUptime());
3621
3622 out.writeInt(getBluetoothPingCount());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003623
Evan Millarc64edde2009-04-18 12:26:32 -07003624 out.writeInt(mKernelWakelockStats.size());
3625 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
3626 SamplingTimer kwlt = ent.getValue();
3627 if (kwlt != null) {
3628 out.writeInt(1);
3629 out.writeString(ent.getKey());
3630 Timer.writeTimerToParcel(out, kwlt, batteryRealtime);
3631 } else {
3632 out.writeInt(0);
3633 }
3634 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003635
3636 out.writeInt(sNumSpeedSteps);
3637
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003638 int size = mUidStats.size();
3639 out.writeInt(size);
3640 for (int i = 0; i < size; i++) {
3641 out.writeInt(mUidStats.keyAt(i));
3642 Uid uid = mUidStats.valueAt(i);
3643
3644 uid.writeToParcelLocked(out, batteryRealtime);
3645 }
3646 }
3647
3648 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
3649 new Parcelable.Creator<BatteryStatsImpl>() {
3650 public BatteryStatsImpl createFromParcel(Parcel in) {
3651 return new BatteryStatsImpl(in);
3652 }
3653
3654 public BatteryStatsImpl[] newArray(int size) {
3655 return new BatteryStatsImpl[size];
3656 }
3657 };
3658
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003659 public void dumpLocked(PrintWriter pw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003660 if (DEBUG) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003661 Printer pr = new PrintWriterPrinter(pw);
3662 pr.println("*** Screen timer:");
3663 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07003664 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003665 pr.println("*** Screen brightness #" + i + ":");
3666 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07003667 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003668 pr.println("*** Input event counter:");
3669 mInputEventCounter.logState(pr, " ");
3670 pr.println("*** Phone timer:");
3671 mPhoneOnTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07003672 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003673 pr.println("*** Signal strength #" + i + ":");
3674 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07003675 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07003676 pr.println("*** Signal scanning :");
3677 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07003678 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003679 pr.println("*** Data connection type #" + i + ":");
3680 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07003681 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003682 pr.println("*** Wifi timer:");
3683 mWifiOnTimer.logState(pr, " ");
3684 pr.println("*** WifiRunning timer:");
3685 mWifiRunningTimer.logState(pr, " ");
3686 pr.println("*** Bluetooth timer:");
3687 mBluetoothOnTimer.logState(pr, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003688 }
3689 super.dumpLocked(pw);
3690 }
3691}