blob: fc4a9c4fe9994126156fd11f5df718828b5405eb [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
19import android.os.BatteryStats;
20import android.os.NetStat;
21import android.os.Parcel;
22import android.os.ParcelFormatException;
23import android.os.Parcelable;
Evan Millarc64edde2009-04-18 12:26:32 -070024import android.os.Process;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import android.os.SystemClock;
Wink Savillee9b06d72009-05-18 21:47:50 -070026import android.telephony.SignalStrength;
Dianne Hackborn627bba72009-03-24 22:32:56 -070027import android.telephony.TelephonyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import android.util.Log;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070029import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.util.Printer;
31import android.util.SparseArray;
32
Amith Yamasani3718aaa2009-06-09 06:32:35 -070033import java.io.BufferedReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import java.io.File;
35import java.io.FileInputStream;
36import java.io.FileOutputStream;
Amith Yamasani3718aaa2009-06-09 06:32:35 -070037import java.io.FileReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070039import java.io.PrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import java.util.ArrayList;
41import java.util.HashMap;
Evan Millarc64edde2009-04-18 12:26:32 -070042import java.util.Iterator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043import java.util.Map;
44
45/**
46 * All information we are collecting about things that can happen that impact
47 * battery life. All times are represented in microseconds except where indicated
48 * otherwise.
49 */
50public final class BatteryStatsImpl extends BatteryStats {
51 private static final String TAG = "BatteryStatsImpl";
52 private static final boolean DEBUG = false;
53
54 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
55 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
56
57 // Current on-disk Parcel version
Amith Yamasani3718aaa2009-06-09 06:32:35 -070058 private static final int VERSION = 39;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059
60 private final File mFile;
61 private final File mBackupFile;
62
63 /**
64 * The statistics we have collected organized by uids.
65 */
66 final SparseArray<BatteryStatsImpl.Uid> mUidStats =
67 new SparseArray<BatteryStatsImpl.Uid>();
68
69 // A set of pools of currently active timers. When a timer is queried, we will divide the
70 // elapsed time by the number of active timers to arrive at that timer's share of the time.
71 // In order to do this, we must refresh each timer whenever the number of active timers
72 // changes.
Evan Millarc64edde2009-04-18 12:26:32 -070073 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>();
74 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>();
75 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>();
76 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers
77 = new SparseArray<ArrayList<StopwatchTimer>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078
79 // These are the objects that will want to do something when the device
80 // is unplugged from power.
81 final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>();
82
83 int mStartCount;
84
85 long mBatteryUptime;
86 long mBatteryLastUptime;
87 long mBatteryRealtime;
88 long mBatteryLastRealtime;
89
90 long mUptime;
91 long mUptimeStart;
92 long mLastUptime;
93 long mRealtime;
94 long mRealtimeStart;
95 long mLastRealtime;
96
97 boolean mScreenOn;
Evan Millarc64edde2009-04-18 12:26:32 -070098 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -070099
Dianne Hackborn617f8772009-03-31 15:04:46 -0700100 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700101 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Dianne Hackborn617f8772009-03-31 15:04:46 -0700102
103 Counter mInputEventCounter;
104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700106 StopwatchTimer mPhoneOnTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700108 boolean mAudioOn;
109 StopwatchTimer mAudioOnTimer;
110
111 boolean mVideoOn;
112 StopwatchTimer mVideoOnTimer;
113
Dianne Hackborn627bba72009-03-24 22:32:56 -0700114 int mPhoneSignalStrengthBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700115 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
116 new StopwatchTimer[NUM_SIGNAL_STRENGTH_BINS];
Dianne Hackborn627bba72009-03-24 22:32:56 -0700117
118 int mPhoneDataConnectionType = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700119 final StopwatchTimer[] mPhoneDataConnectionsTimer =
120 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Dianne Hackborn627bba72009-03-24 22:32:56 -0700121
The Android Open Source Project10592532009-03-18 17:39:46 -0700122 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700123 StopwatchTimer mWifiOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700124 int mWifiOnUid = -1;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700125
126 boolean mWifiRunning;
Evan Millarc64edde2009-04-18 12:26:32 -0700127 StopwatchTimer mWifiRunningTimer;
The Android Open Source Project10592532009-03-18 17:39:46 -0700128
129 boolean mBluetoothOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700130 StopwatchTimer mBluetoothOnTimer;
The Android Open Source Project10592532009-03-18 17:39:46 -0700131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132 /**
133 * These provide time bases that discount the time the device is plugged
134 * in to power.
135 */
136 boolean mOnBattery;
137 boolean mOnBatteryInternal;
138 long mTrackBatteryPastUptime;
139 long mTrackBatteryUptimeStart;
140 long mTrackBatteryPastRealtime;
141 long mTrackBatteryRealtimeStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 long mUnpluggedBatteryUptime;
144 long mUnpluggedBatteryRealtime;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700145
The Android Open Source Project10592532009-03-18 17:39:46 -0700146 /*
147 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
148 */
Evan Millar633a1742009-04-02 16:36:33 -0700149 int mDischargeStartLevel;
150 int mDischargeCurrentLevel;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700153
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700154 // Mobile data transferred while on battery
155 private long[] mMobileDataTx = new long[4];
156 private long[] mMobileDataRx = new long[4];
157 private long[] mTotalDataTx = new long[4];
158 private long[] mTotalDataRx = new long[4];
159
160 private long mRadioDataUptime;
161 private long mRadioDataStart;
162
Evan Millarc64edde2009-04-18 12:26:32 -0700163 /*
164 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
165 */
166 private final HashMap<String, SamplingTimer> mKernelWakelockStats =
167 new HashMap<String, SamplingTimer>();
168
169 public Map<String, ? extends SamplingTimer> getKernelWakelockStats() {
170 return mKernelWakelockStats;
171 }
172
173 private static int sKernelWakelockUpdateVersion = 0;
174
175 private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
176 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name
177 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count
178 Process.PROC_TAB_TERM,
179 Process.PROC_TAB_TERM,
180 Process.PROC_TAB_TERM,
181 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime
182 };
183
184 private final String[] mProcWakelocksName = new String[3];
185 private final long[] mProcWakelocksData = new long[3];
186
187 /*
188 * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added
189 * to mKernelWakelockStats.
190 */
191 private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
192 new HashMap<String, KernelWakelockStats>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700194 private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>();
195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196 // For debugging
197 public BatteryStatsImpl() {
198 mFile = mBackupFile = null;
199 }
200
201 public static interface Unpluggable {
202 void unplug(long batteryUptime, long batteryRealtime);
203 void plug(long batteryUptime, long batteryRealtime);
204 }
205
206 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700207 * State for keeping track of counting information.
208 */
209 public static final class Counter extends BatteryStats.Counter implements Unpluggable {
210 int mCount;
211 int mLoadedCount;
212 int mLastCount;
213 int mUnpluggedCount;
214 int mPluggedCount;
215
216 Counter(ArrayList<Unpluggable> unpluggables, Parcel in) {
217 mPluggedCount = mCount = in.readInt();
218 mLoadedCount = in.readInt();
219 mLastCount = in.readInt();
220 mUnpluggedCount = in.readInt();
221 unpluggables.add(this);
222 }
223
224 Counter(ArrayList<Unpluggable> unpluggables) {
225 unpluggables.add(this);
226 }
227
228 public void writeToParcel(Parcel out) {
229 out.writeInt(mCount);
230 out.writeInt(mLoadedCount);
231 out.writeInt(mLastCount);
232 out.writeInt(mUnpluggedCount);
233 }
234
235 public void unplug(long batteryUptime, long batteryRealtime) {
236 mUnpluggedCount = mCount = mPluggedCount;
237 }
238
239 public void plug(long batteryUptime, long batteryRealtime) {
240 mPluggedCount = mCount;
241 }
242
243 /**
244 * Writes a possibly null Counter to a Parcel.
245 *
246 * @param out the Parcel to be written to.
247 * @param counter a Counter, or null.
248 */
249 public static void writeCounterToParcel(Parcel out, Counter counter) {
250 if (counter == null) {
251 out.writeInt(0); // indicates null
252 return;
253 }
254 out.writeInt(1); // indicates non-null
255
256 counter.writeToParcel(out);
257 }
258
259 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700260 public int getCountLocked(int which) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700261 int val;
262 if (which == STATS_LAST) {
263 val = mLastCount;
264 } else {
265 val = mCount;
266 if (which == STATS_UNPLUGGED) {
267 val -= mUnpluggedCount;
268 } else if (which != STATS_TOTAL) {
269 val -= mLoadedCount;
270 }
271 }
272
273 return val;
274 }
275
276 public void logState(Printer pw, String prefix) {
277 pw.println(prefix + "mCount=" + mCount
278 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
279 + " mUnpluggedCount=" + mUnpluggedCount
280 + " mPluggedCount=" + mPluggedCount);
281 }
282
283 void stepLocked() {
284 mCount++;
285 }
286
287 void writeSummaryFromParcelLocked(Parcel out) {
288 out.writeInt(mCount);
289 out.writeInt(mCount - mLoadedCount);
290 }
291
292 void readSummaryFromParcelLocked(Parcel in) {
293 mCount = mLoadedCount = in.readInt();
294 mLastCount = in.readInt();
295 mUnpluggedCount = mPluggedCount = mCount;
296 }
297 }
298
299 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800300 * State for keeping track of timing information.
301 */
Evan Millarc64edde2009-04-18 12:26:32 -0700302 public static abstract class Timer extends BatteryStats.Timer implements Unpluggable {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 final int mType;
Evan Millarc64edde2009-04-18 12:26:32 -0700304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305
306 int mCount;
307 int mLoadedCount;
308 int mLastCount;
309 int mUnpluggedCount;
310
311 // Times are in microseconds for better accuracy when dividing by the
312 // lock count, and are in "battery realtime" units.
313
314 /**
315 * The total time we have accumulated since the start of the original
316 * boot, to the last time something interesting happened in the
317 * current run.
318 */
319 long mTotalTime;
320
321 /**
322 * The total time we loaded for the previous runs. Subtract this from
323 * mTotalTime to find the time for the current run of the system.
324 */
325 long mLoadedTime;
326
327 /**
328 * The run time of the last run of the system, as loaded from the
329 * saved data.
330 */
331 long mLastTime;
332
333 /**
334 * The value of mTotalTime when unplug() was last called. Subtract
335 * this from mTotalTime to find the time since the last unplug from
336 * power.
337 */
338 long mUnpluggedTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700340 /**
341 * Constructs from a parcel.
342 * @param type
343 * @param unpluggables
344 * @param powerType
345 * @param in
346 */
Evan Millarc64edde2009-04-18 12:26:32 -0700347 Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800348 mType = type;
Evan Millarc64edde2009-04-18 12:26:32 -0700349
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800350 mCount = in.readInt();
351 mLoadedCount = in.readInt();
352 mLastCount = in.readInt();
353 mUnpluggedCount = in.readInt();
354 mTotalTime = in.readLong();
355 mLoadedTime = in.readLong();
356 mLastTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357 mUnpluggedTime = in.readLong();
358 unpluggables.add(this);
359 }
360
Evan Millarc64edde2009-04-18 12:26:32 -0700361 Timer(int type, ArrayList<Unpluggable> unpluggables) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800362 mType = type;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 unpluggables.add(this);
364 }
Evan Millarc64edde2009-04-18 12:26:32 -0700365
366 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
367
368 protected abstract int computeCurrentCountLocked();
369
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370
371 public void writeToParcel(Parcel out, long batteryRealtime) {
372 out.writeInt(mCount);
373 out.writeInt(mLoadedCount);
374 out.writeInt(mLastCount);
375 out.writeInt(mUnpluggedCount);
376 out.writeLong(computeRunTimeLocked(batteryRealtime));
377 out.writeLong(mLoadedTime);
378 out.writeLong(mLastTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800379 out.writeLong(mUnpluggedTime);
380 }
381
382 public void unplug(long batteryUptime, long batteryRealtime) {
383 if (DEBUG && mType < 0) {
384 Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime
385 + " old mUnpluggedTime=" + mUnpluggedTime
386 + " old mUnpluggedCount=" + mUnpluggedCount);
387 }
388 mUnpluggedTime = computeRunTimeLocked(batteryRealtime);
389 mUnpluggedCount = mCount;
390 if (DEBUG && mType < 0) {
391 Log.v(TAG, "unplug #" + mType
392 + ": new mUnpluggedTime=" + mUnpluggedTime
393 + " new mUnpluggedCount=" + mUnpluggedCount);
394 }
395 }
396
397 public void plug(long batteryUptime, long batteryRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -0700398 if (DEBUG && mType < 0) {
399 Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime
400 + " old mTotalTime=" + mTotalTime);
401 }
402 mTotalTime = computeRunTimeLocked(batteryRealtime);
403 mCount = computeCurrentCountLocked();
404 if (DEBUG && mType < 0) {
405 Log.v(TAG, "plug #" + mType
406 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407 }
408 }
409
410 /**
411 * Writes a possibly null Timer to a Parcel.
412 *
413 * @param out the Parcel to be written to.
414 * @param timer a Timer, or null.
415 */
416 public static void writeTimerToParcel(Parcel out, Timer timer,
417 long batteryRealtime) {
418 if (timer == null) {
419 out.writeInt(0); // indicates null
420 return;
421 }
422 out.writeInt(1); // indicates non-null
423
424 timer.writeToParcel(out, batteryRealtime);
425 }
426
427 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700428 public long getTotalTimeLocked(long batteryRealtime, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429 long val;
430 if (which == STATS_LAST) {
431 val = mLastTime;
432 } else {
433 val = computeRunTimeLocked(batteryRealtime);
434 if (which == STATS_UNPLUGGED) {
435 val -= mUnpluggedTime;
436 } else if (which != STATS_TOTAL) {
437 val -= mLoadedTime;
438 }
439 }
440
441 return val;
442 }
443
444 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700445 public int getCountLocked(int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446 int val;
447 if (which == STATS_LAST) {
448 val = mLastCount;
449 } else {
Evan Millarc64edde2009-04-18 12:26:32 -0700450 val = computeCurrentCountLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 if (which == STATS_UNPLUGGED) {
452 val -= mUnpluggedCount;
453 } else if (which != STATS_TOTAL) {
454 val -= mLoadedCount;
455 }
456 }
457
458 return val;
459 }
460
Dianne Hackborn627bba72009-03-24 22:32:56 -0700461 public void logState(Printer pw, String prefix) {
Evan Millarc64edde2009-04-18 12:26:32 -0700462 pw.println(prefix + " mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800463 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
464 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700465 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800466 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700467 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800468 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -0700469 }
470
471
472 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
473 long runTime = computeRunTimeLocked(batteryRealtime);
474 // Divide by 1000 for backwards compatibility
475 out.writeLong((runTime + 500) / 1000);
476 out.writeLong(((runTime - mLoadedTime) + 500) / 1000);
477 out.writeInt(mCount);
478 out.writeInt(mCount - mLoadedCount);
479 }
480
481 void readSummaryFromParcelLocked(Parcel in) {
482 // Multiply by 1000 for backwards compatibility
483 mTotalTime = mLoadedTime = in.readLong() * 1000;
484 mLastTime = in.readLong() * 1000;
485 mUnpluggedTime = mTotalTime;
486 mCount = mLoadedCount = in.readInt();
487 mLastCount = in.readInt();
488 mUnpluggedCount = mCount;
489 }
490 }
491
492 public static final class SamplingTimer extends Timer {
493
494 /**
495 * The most recent reported count from /proc/wakelocks.
496 */
497 int mCurrentReportedCount;
498
499 /**
500 * The reported count from /proc/wakelocks when unplug() was last
501 * called.
502 */
503 int mUnpluggedReportedCount;
504
505 /**
506 * The most recent reported total_time from /proc/wakelocks.
507 */
508 long mCurrentReportedTotalTime;
509
510
511 /**
512 * The reported total_time from /proc/wakelocks when unplug() was last
513 * called.
514 */
515 long mUnpluggedReportedTotalTime;
516
517 /**
518 * Whether we are currently in a discharge cycle.
519 */
520 boolean mInDischarge;
521
522 /**
523 * Whether we are currently recording reported values.
524 */
525 boolean mTrackingReportedValues;
526
527 /*
528 * A sequnce counter, incremented once for each update of the stats.
529 */
530 int mUpdateVersion;
531
532 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) {
533 super(0, unpluggables, in);
534 mCurrentReportedCount = in.readInt();
535 mUnpluggedReportedCount = in.readInt();
536 mCurrentReportedTotalTime = in.readLong();
537 mUnpluggedReportedTotalTime = in.readLong();
538 mTrackingReportedValues = in.readInt() == 1;
539 mInDischarge = inDischarge;
540 }
541
542 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge,
543 boolean trackReportedValues) {
544 super(0, unpluggables);
545 mTrackingReportedValues = trackReportedValues;
546 mInDischarge = inDischarge;
547 }
548
549 public void setStale() {
550 mTrackingReportedValues = false;
551 mUnpluggedReportedTotalTime = 0;
552 mUnpluggedReportedCount = 0;
553 }
554
555 public void setUpdateVersion(int version) {
556 mUpdateVersion = version;
557 }
558
559 public int getUpdateVersion() {
560 return mUpdateVersion;
561 }
562
563 public void updateCurrentReportedCount(int count) {
564 if (mInDischarge && mUnpluggedReportedCount == 0) {
565 // Updating the reported value for the first time.
566 mUnpluggedReportedCount = count;
567 // If we are receiving an update update mTrackingReportedValues;
568 mTrackingReportedValues = true;
569 }
570 mCurrentReportedCount = count;
571 }
572
573 public void updateCurrentReportedTotalTime(long totalTime) {
574 if (mInDischarge && mUnpluggedReportedTotalTime == 0) {
575 // Updating the reported value for the first time.
576 mUnpluggedReportedTotalTime = totalTime;
577 // If we are receiving an update update mTrackingReportedValues;
578 mTrackingReportedValues = true;
579 }
580 mCurrentReportedTotalTime = totalTime;
581 }
582
583 public void unplug(long batteryUptime, long batteryRealtime) {
584 super.unplug(batteryUptime, batteryRealtime);
585 if (mTrackingReportedValues) {
586 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
587 mUnpluggedReportedCount = mCurrentReportedCount;
588 }
589 mInDischarge = true;
590 }
591
592 public void plug(long batteryUptime, long batteryRealtime) {
593 super.plug(batteryUptime, batteryRealtime);
594 mInDischarge = false;
595 }
596
597 public void logState(Printer pw, String prefix) {
598 super.logState(pw, prefix);
599 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
600 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
601 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
602 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
603 }
604
605 protected long computeRunTimeLocked(long curBatteryRealtime) {
606 return mTotalTime + (mInDischarge && mTrackingReportedValues
607 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
608 }
609
610 protected int computeCurrentCountLocked() {
611 return mCount + (mInDischarge && mTrackingReportedValues
612 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
613 }
614
615 public void writeToParcel(Parcel out, long batteryRealtime) {
616 super.writeToParcel(out, batteryRealtime);
617 out.writeInt(mCurrentReportedCount);
618 out.writeInt(mUnpluggedReportedCount);
619 out.writeLong(mCurrentReportedTotalTime);
620 out.writeLong(mUnpluggedReportedTotalTime);
621 out.writeInt(mTrackingReportedValues ? 1 : 0);
622 }
623
624 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
625 super.writeSummaryFromParcelLocked(out, batteryRealtime);
626 out.writeLong(mCurrentReportedTotalTime);
627 out.writeInt(mCurrentReportedCount);
628 out.writeInt(mTrackingReportedValues ? 1 : 0);
629 }
630
631 void readSummaryFromParcelLocked(Parcel in) {
632 super.readSummaryFromParcelLocked(in);
633 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
634 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
635 mTrackingReportedValues = in.readInt() == 1;
636 }
637 }
638
639 /**
640 * State for keeping track of timing information.
641 */
642 public static final class StopwatchTimer extends Timer {
643 final ArrayList<StopwatchTimer> mTimerPool;
644 int mNesting;
645
646
647 /**
648 * The last time at which we updated the timer. If mNesting is > 0,
649 * subtract this from the current battery time to find the amount of
650 * time we have been running since we last computed an update.
651 */
652 long mUpdateTime;
653
654 /**
655 * The total time at which the timer was acquired, to determine if
656 * was actually held for an interesting duration.
657 */
658 long mAcquireTime;
Evan Millarc64edde2009-04-18 12:26:32 -0700659
660 StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool,
661 ArrayList<Unpluggable> unpluggables, Parcel in) {
662 super(type, unpluggables, in);
663 mTimerPool = timerPool;
664 mUpdateTime = in.readLong();
665 }
666
667 StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool,
668 ArrayList<Unpluggable> unpluggables) {
669 super(type, unpluggables);
670 mTimerPool = timerPool;
671 }
672
673 public void writeToParcel(Parcel out, long batteryRealtime) {
674 super.writeToParcel(out, batteryRealtime);
675 out.writeLong(mUpdateTime);
676 }
677
678 public void plug(long batteryUptime, long batteryRealtime) {
679 if (mNesting > 0) {
680 if (DEBUG && mType < 0) {
681 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
682 }
683 super.plug(batteryUptime, batteryRealtime);
684 mUpdateTime = batteryRealtime;
685 if (DEBUG && mType < 0) {
686 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
687 }
688 }
689 }
690
691 public void logState(Printer pw, String prefix) {
692 super.logState(pw, prefix);
693 pw.println(prefix + "mNesting=" + mNesting + "mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800694 + " mAcquireTime=" + mAcquireTime);
695 }
696
697 void startRunningLocked(BatteryStatsImpl stats) {
698 if (mNesting++ == 0) {
699 mUpdateTime = stats.getBatteryRealtimeLocked(
700 SystemClock.elapsedRealtime() * 1000);
701 if (mTimerPool != null) {
702 // Accumulate time to all currently active timers before adding
703 // this new one to the pool.
704 refreshTimersLocked(stats, mTimerPool);
705 // Add this timer to the active pool
706 mTimerPool.add(this);
707 }
708 // Increment the count
709 mCount++;
710 mAcquireTime = mTotalTime;
711 if (DEBUG && mType < 0) {
712 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
713 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
714 + " mAcquireTime=" + mAcquireTime);
715 }
716 }
717 }
718
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700719 boolean isRunningLocked() {
720 return mNesting > 0;
721 }
722
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 void stopRunningLocked(BatteryStatsImpl stats) {
724 // Ignore attempt to stop a timer that isn't running
725 if (mNesting == 0) {
726 return;
727 }
728 if (--mNesting == 0) {
729 if (mTimerPool != null) {
730 // Accumulate time to all active counters, scaled by the total
731 // active in the pool, before taking this one out of the pool.
732 refreshTimersLocked(stats, mTimerPool);
733 // Remove this timer from the active pool
734 mTimerPool.remove(this);
735 } else {
736 final long realtime = SystemClock.elapsedRealtime() * 1000;
737 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
738 mNesting = 1;
739 mTotalTime = computeRunTimeLocked(batteryRealtime);
740 mNesting = 0;
741 }
742
743 if (DEBUG && mType < 0) {
744 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
745 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
746 + " mAcquireTime=" + mAcquireTime);
747 }
748
749 if (mTotalTime == mAcquireTime) {
750 // If there was no change in the time, then discard this
751 // count. A somewhat cheezy strategy, but hey.
752 mCount--;
753 }
754 }
755 }
756
757 // Update the total time for all other running Timers with the same type as this Timer
758 // due to a change in timer count
759 private static void refreshTimersLocked(final BatteryStatsImpl stats,
Evan Millarc64edde2009-04-18 12:26:32 -0700760 final ArrayList<StopwatchTimer> pool) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800761 final long realtime = SystemClock.elapsedRealtime() * 1000;
762 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
763 final int N = pool.size();
764 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -0700765 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800766 long heldTime = batteryRealtime - t.mUpdateTime;
767 if (heldTime > 0) {
768 t.mTotalTime += heldTime / N;
769 }
770 t.mUpdateTime = batteryRealtime;
771 }
772 }
773
Evan Millarc64edde2009-04-18 12:26:32 -0700774 @Override
775 protected long computeRunTimeLocked(long curBatteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776 return mTotalTime + (mNesting > 0
777 ? (curBatteryRealtime - mUpdateTime)
778 / (mTimerPool != null ? mTimerPool.size() : 1)
779 : 0);
780 }
781
Evan Millarc64edde2009-04-18 12:26:32 -0700782 @Override
783 protected int computeCurrentCountLocked() {
784 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800785 }
786
787 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -0700788 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800789 mNesting = 0;
790 }
791 }
792
Evan Millarc64edde2009-04-18 12:26:32 -0700793 private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
794
795 byte[] buffer = new byte[4096];
796 int len;
797
798 try {
799 FileInputStream is = new FileInputStream("/proc/wakelocks");
800 len = is.read(buffer);
801 is.close();
802
803 if (len > 0) {
804 int i;
805 for (i=0; i<len; i++) {
806 if (buffer[i] == '\0') {
807 len = i;
808 break;
809 }
810 }
811 }
812 } catch (java.io.FileNotFoundException e) {
813 return null;
814 } catch (java.io.IOException e) {
815 return null;
816 }
817
818 return parseProcWakelocks(buffer, len);
819 }
820
821 private final Map<String, KernelWakelockStats> parseProcWakelocks(
822 byte[] wlBuffer, int len) {
823 String name;
824 int count;
825 long totalTime;
826 int startIndex, endIndex;
827 int numUpdatedWlNames = 0;
828
829 // Advance past the first line.
830 int i;
831 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++);
832 startIndex = endIndex = i + 1;
833
834 synchronized(this) {
835 Map<String, KernelWakelockStats> m = mProcWakelockFileStats;
836
837 sKernelWakelockUpdateVersion++;
838 while (endIndex < len) {
839 for (endIndex=startIndex;
840 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
841 endIndex++);
842 endIndex++; // endIndex is an exclusive upper bound.
843
844 String[] nameStringArray = mProcWakelocksName;
845 long[] wlData = mProcWakelocksData;
846 Process.parseProcLine(wlBuffer, startIndex, endIndex, PROC_WAKELOCKS_FORMAT,
847 nameStringArray, wlData, null);
848
849 name = nameStringArray[0];
850 count = (int) wlData[1];
851 // convert nanoseconds to microseconds with rounding.
852 totalTime = (wlData[2] + 500) / 1000;
853
854 if (name.length() > 0) {
855 if (!m.containsKey(name)) {
856 m.put(name, new KernelWakelockStats(count, totalTime,
857 sKernelWakelockUpdateVersion));
858 numUpdatedWlNames++;
859 } else {
860 KernelWakelockStats kwlStats = m.get(name);
861 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) {
862 kwlStats.mCount += count;
863 kwlStats.mTotalTime += totalTime;
864 } else {
865 kwlStats.mCount = count;
866 kwlStats.mTotalTime = totalTime;
867 kwlStats.mVersion = sKernelWakelockUpdateVersion;
868 numUpdatedWlNames++;
869 }
870 }
871 }
872 startIndex = endIndex;
873 }
874
875 if (m.size() != numUpdatedWlNames) {
876 // Don't report old data.
877 Iterator<KernelWakelockStats> itr = m.values().iterator();
878 while (itr.hasNext()) {
879 if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
880 itr.remove();
881 }
882 }
883 }
884 return m;
885 }
886 }
887
888 private class KernelWakelockStats {
889 public int mCount;
890 public long mTotalTime;
891 public int mVersion;
892
893 KernelWakelockStats(int count, long totalTime, int version) {
894 mCount = count;
895 mTotalTime = totalTime;
896 mVersion = version;
897 }
898 }
899
900 /*
901 * Get the KernelWakelockTimer associated with name, and create a new one if one
902 * doesn't already exist.
903 */
904 public SamplingTimer getKernelWakelockTimerLocked(String name) {
905 SamplingTimer kwlt = mKernelWakelockStats.get(name);
906 if (kwlt == null) {
907 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
908 true /* track reported values */);
909 mKernelWakelockStats.put(name, kwlt);
910 }
911 return kwlt;
912 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700913
914 private void doDataPlug(long[] dataTransfer, long currentBytes) {
915 dataTransfer[STATS_LAST] = dataTransfer[STATS_UNPLUGGED];
916 dataTransfer[STATS_UNPLUGGED] = -1;
917 }
918
919 private void doDataUnplug(long[] dataTransfer, long currentBytes) {
920 dataTransfer[STATS_UNPLUGGED] = currentBytes;
921 }
922
923 private long getCurrentRadioDataUptimeMs() {
924 try {
925 File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms");
926 if (!awakeTimeFile.exists()) return 0;
927 BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile));
928 String line = br.readLine();
929 br.close();
930 return Long.parseLong(line);
931 } catch (NumberFormatException nfe) {
932 // Nothing
933 } catch (IOException ioe) {
934 // Nothing
935 }
936 return 0;
937 }
938
939 public long getRadioDataUptimeMs() {
940 if (mRadioDataStart == -1) {
941 return mRadioDataUptime;
942 } else {
943 return getCurrentRadioDataUptimeMs() - mRadioDataStart;
944 }
945 }
946
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800947 public void doUnplug(long batteryUptime, long batteryRealtime) {
948 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
949 Uid u = mUidStats.valueAt(iu);
950 u.mStartedTcpBytesReceived = NetStat.getUidRxBytes(u.mUid);
951 u.mStartedTcpBytesSent = NetStat.getUidTxBytes(u.mUid);
952 u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived;
953 u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent;
954 }
955 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
956 mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime);
957 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700958 // Track total mobile data
959 doDataUnplug(mMobileDataRx, NetStat.getMobileRxBytes());
960 doDataUnplug(mMobileDataTx, NetStat.getMobileTxBytes());
961 doDataUnplug(mTotalDataRx, NetStat.getTotalRxBytes());
962 doDataUnplug(mTotalDataTx, NetStat.getTotalTxBytes());
963 // Track radio awake time
964 mRadioDataStart = getCurrentRadioDataUptimeMs();
965 mRadioDataUptime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800966 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700967
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968 public void doPlug(long batteryUptime, long batteryRealtime) {
969 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
970 Uid u = mUidStats.valueAt(iu);
971 if (u.mStartedTcpBytesReceived >= 0) {
972 u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived();
973 u.mStartedTcpBytesReceived = -1;
974 }
975 if (u.mStartedTcpBytesSent >= 0) {
976 u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent();
977 u.mStartedTcpBytesSent = -1;
978 }
979 }
980 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
981 mUnpluggables.get(i).plug(batteryUptime, batteryRealtime);
982 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700983 doDataPlug(mMobileDataRx, NetStat.getMobileRxBytes());
984 doDataPlug(mMobileDataTx, NetStat.getMobileTxBytes());
985 doDataPlug(mTotalDataRx, NetStat.getTotalRxBytes());
986 doDataPlug(mTotalDataTx, NetStat.getTotalTxBytes());
987 // Track radio awake time
988 mRadioDataUptime = getRadioDataUptimeMs();
989 mRadioDataStart = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800990 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700991
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992 public void noteStartGps(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -0700993 getUidStatsLocked(uid).noteStartGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994 }
995
996 public void noteStopGps(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -0700997 getUidStatsLocked(uid).noteStopGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800998 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700999
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000 public void noteScreenOnLocked() {
1001 if (!mScreenOn) {
1002 mScreenOn = true;
1003 mScreenOnTimer.startRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001004 if (mScreenBrightnessBin >= 0) {
1005 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this);
1006 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 }
1008 }
1009
1010 public void noteScreenOffLocked() {
1011 if (mScreenOn) {
1012 mScreenOn = false;
1013 mScreenOnTimer.stopRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001014 if (mScreenBrightnessBin >= 0) {
1015 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1016 }
1017 }
1018 }
1019
1020 public void noteScreenBrightnessLocked(int brightness) {
1021 // Bin the brightness.
1022 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
1023 if (bin < 0) bin = 0;
1024 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
1025 if (mScreenBrightnessBin != bin) {
1026 if (mScreenOn) {
1027 if (mScreenBrightnessBin >= 0) {
1028 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1029 }
1030 mScreenBrightnessTimer[bin].startRunningLocked(this);
1031 }
1032 mScreenBrightnessBin = bin;
1033 }
1034 }
1035
1036 public void noteInputEventLocked() {
1037 mInputEventCounter.stepLocked();
1038 }
1039
1040 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001041 getUidStatsLocked(uid).noteUserActivityLocked(event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001042 }
1043
1044 public void notePhoneOnLocked() {
1045 if (!mPhoneOn) {
1046 mPhoneOn = true;
1047 mPhoneOnTimer.startRunningLocked(this);
1048 }
1049 }
1050
1051 public void notePhoneOffLocked() {
1052 if (mPhoneOn) {
1053 mPhoneOn = false;
1054 mPhoneOnTimer.stopRunningLocked(this);
1055 }
1056 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001057
1058 public void noteAirplaneModeLocked(boolean isAirplaneMode) {
1059 final int bin = mPhoneSignalStrengthBin;
1060 if (bin >= 0) {
1061 if (!isAirplaneMode) {
1062 if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
1063 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
1064 }
1065 } else {
1066 for (int i = 0; i < NUM_SIGNAL_STRENGTH_BINS; i++) {
1067 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
1068 mPhoneSignalStrengthsTimer[i].stopRunningLocked(this);
1069 }
1070 }
1071 }
1072 }
1073 }
1074
Wink Savillee9b06d72009-05-18 21:47:50 -07001075 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07001076 // Bin the strength.
1077 int bin;
Wink Savillee9b06d72009-05-18 21:47:50 -07001078
1079 if (!signalStrength.isGsm()) {
1080 int dBm = signalStrength.getCdmaDbm();
1081 if (dBm >= -75) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
1082 else if (dBm >= -85) bin = SIGNAL_STRENGTH_GREAT;
1083 else if (dBm >= -95) bin = SIGNAL_STRENGTH_GOOD;
1084 else if (dBm >= -100) bin = SIGNAL_STRENGTH_MODERATE;
1085 else bin = SIGNAL_STRENGTH_POOR;
1086 } else {
1087 int asu = signalStrength.getGsmSignalStrength();
1088 if (asu < 0 || asu >= 99) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
1089 else if (asu >= 16) bin = SIGNAL_STRENGTH_GREAT;
1090 else if (asu >= 8) bin = SIGNAL_STRENGTH_GOOD;
1091 else if (asu >= 4) bin = SIGNAL_STRENGTH_MODERATE;
1092 else bin = SIGNAL_STRENGTH_POOR;
1093 }
Dianne Hackborn627bba72009-03-24 22:32:56 -07001094 if (mPhoneSignalStrengthBin != bin) {
1095 if (mPhoneSignalStrengthBin >= 0) {
1096 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
1097 }
1098 mPhoneSignalStrengthBin = bin;
1099 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
1100 }
1101 }
1102
1103 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
1104 int bin = DATA_CONNECTION_NONE;
1105 if (hasData) {
1106 switch (dataType) {
1107 case TelephonyManager.NETWORK_TYPE_EDGE:
1108 bin = DATA_CONNECTION_EDGE;
1109 break;
1110 case TelephonyManager.NETWORK_TYPE_GPRS:
1111 bin = DATA_CONNECTION_GPRS;
1112 break;
1113 case TelephonyManager.NETWORK_TYPE_UMTS:
1114 bin = DATA_CONNECTION_UMTS;
1115 break;
1116 default:
1117 bin = DATA_CONNECTION_OTHER;
1118 break;
1119 }
1120 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001121 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001122 if (mPhoneDataConnectionType != bin) {
1123 if (mPhoneDataConnectionType >= 0) {
1124 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this);
1125 }
1126 mPhoneDataConnectionType = bin;
1127 mPhoneDataConnectionsTimer[bin].startRunningLocked(this);
1128 }
1129 }
1130
Dianne Hackborn617f8772009-03-31 15:04:46 -07001131 public void noteWifiOnLocked(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001132 if (!mWifiOn) {
1133 mWifiOn = true;
1134 mWifiOnTimer.startRunningLocked(this);
1135 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001136 if (mWifiOnUid != uid) {
1137 if (mWifiOnUid >= 0) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001138 getUidStatsLocked(mWifiOnUid).noteWifiTurnedOffLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001139 }
1140 mWifiOnUid = uid;
Dianne Hackborn2e418422009-06-22 20:00:17 -07001141 getUidStatsLocked(uid).noteWifiTurnedOnLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001142 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001143 }
1144
Dianne Hackborn617f8772009-03-31 15:04:46 -07001145 public void noteWifiOffLocked(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001146 if (mWifiOn) {
1147 mWifiOn = false;
1148 mWifiOnTimer.stopRunningLocked(this);
1149 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001150 if (mWifiOnUid >= 0) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001151 getUidStatsLocked(mWifiOnUid).noteWifiTurnedOffLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001152 mWifiOnUid = -1;
1153 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001154 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001155
1156 public void noteAudioOnLocked(int uid) {
1157 if (!mAudioOn) {
1158 mAudioOn = true;
1159 mAudioOnTimer.startRunningLocked(this);
1160 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001161 getUidStatsLocked(uid).noteAudioTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001162 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001163
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001164 public void noteAudioOffLocked(int uid) {
1165 if (mAudioOn) {
1166 mAudioOn = false;
1167 mAudioOnTimer.stopRunningLocked(this);
1168 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001169 getUidStatsLocked(uid).noteAudioTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001170 }
1171
1172 public void noteVideoOnLocked(int uid) {
1173 if (!mVideoOn) {
1174 mVideoOn = true;
1175 mVideoOnTimer.startRunningLocked(this);
1176 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001177 getUidStatsLocked(uid).noteVideoTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001178 }
1179
1180 public void noteVideoOffLocked(int uid) {
1181 if (mVideoOn) {
1182 mVideoOn = false;
1183 mVideoOnTimer.stopRunningLocked(this);
1184 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001185 getUidStatsLocked(uid).noteVideoTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001186 }
1187
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001188 public void noteWifiRunningLocked() {
1189 if (!mWifiRunning) {
1190 mWifiRunning = true;
1191 mWifiRunningTimer.startRunningLocked(this);
1192 }
1193 }
1194
1195 public void noteWifiStoppedLocked() {
1196 if (mWifiRunning) {
1197 mWifiRunning = false;
1198 mWifiRunningTimer.stopRunningLocked(this);
1199 }
1200 }
1201
The Android Open Source Project10592532009-03-18 17:39:46 -07001202 public void noteBluetoothOnLocked() {
1203 if (!mBluetoothOn) {
1204 mBluetoothOn = true;
1205 mBluetoothOnTimer.startRunningLocked(this);
1206 }
1207 }
1208
1209 public void noteBluetoothOffLocked() {
1210 if (mBluetoothOn) {
1211 mBluetoothOn = false;
1212 mBluetoothOnTimer.stopRunningLocked(this);
1213 }
1214 }
1215
1216 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001217 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001218 }
1219
1220 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001221 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001222 }
1223
1224 public void noteScanWifiLockAcquiredLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001225 getUidStatsLocked(uid).noteScanWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001226 }
1227
1228 public void noteScanWifiLockReleasedLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001229 getUidStatsLocked(uid).noteScanWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001230 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001231
1232 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001233 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001234 }
1235
1236 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001237 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001238 }
1239
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001240 @Override public long getScreenOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001241 return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001242 }
1243
Dianne Hackborn617f8772009-03-31 15:04:46 -07001244 @Override public long getScreenBrightnessTime(int brightnessBin,
1245 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001246 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn617f8772009-03-31 15:04:46 -07001247 batteryRealtime, which);
1248 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001249
Dianne Hackborn617f8772009-03-31 15:04:46 -07001250 @Override public int getInputEventCount(int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001251 return mInputEventCounter.getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001252 }
1253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001254 @Override public long getPhoneOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001255 return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001256 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001257
Dianne Hackborn627bba72009-03-24 22:32:56 -07001258 @Override public long getPhoneSignalStrengthTime(int strengthBin,
1259 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001260 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07001261 batteryRealtime, which);
1262 }
1263
Dianne Hackborn617f8772009-03-31 15:04:46 -07001264 @Override public int getPhoneSignalStrengthCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001265 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001266 }
1267
Dianne Hackborn627bba72009-03-24 22:32:56 -07001268 @Override public long getPhoneDataConnectionTime(int dataType,
1269 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001270 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07001271 batteryRealtime, which);
1272 }
1273
Dianne Hackborn617f8772009-03-31 15:04:46 -07001274 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001275 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001276 }
1277
The Android Open Source Project10592532009-03-18 17:39:46 -07001278 @Override public long getWifiOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001279 return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001280 }
1281
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001282 @Override public long getWifiRunningTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001283 return mWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001284 }
1285
The Android Open Source Project10592532009-03-18 17:39:46 -07001286 @Override public long getBluetoothOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001287 return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001288 }
1289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001290 @Override public boolean getIsOnBattery() {
1291 return mOnBattery;
1292 }
1293
1294 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
1295 return mUidStats;
1296 }
1297
1298 /**
1299 * The statistics associated with a particular uid.
1300 */
1301 public final class Uid extends BatteryStats.Uid {
1302
1303 final int mUid;
1304 long mLoadedTcpBytesReceived;
1305 long mLoadedTcpBytesSent;
1306 long mCurrentTcpBytesReceived;
1307 long mCurrentTcpBytesSent;
1308 long mTcpBytesReceivedAtLastUnplug;
1309 long mTcpBytesSentAtLastUnplug;
1310
1311 // These are not saved/restored when parcelling, since we want
1312 // to return from the parcel with a snapshot of the state.
1313 long mStartedTcpBytesReceived = -1;
1314 long mStartedTcpBytesSent = -1;
1315
Dianne Hackborn617f8772009-03-31 15:04:46 -07001316 boolean mWifiTurnedOn;
Evan Millarc64edde2009-04-18 12:26:32 -07001317 StopwatchTimer mWifiTurnedOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -07001318
The Android Open Source Project10592532009-03-18 17:39:46 -07001319 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07001320 StopwatchTimer mFullWifiLockTimer;
The Android Open Source Project10592532009-03-18 17:39:46 -07001321
1322 boolean mScanWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07001323 StopwatchTimer mScanWifiLockTimer;
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001324
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001325 boolean mWifiMulticastEnabled;
1326 StopwatchTimer mWifiMulticastTimer;
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001327
1328 boolean mAudioTurnedOn;
1329 StopwatchTimer mAudioTurnedOnTimer;
1330
1331 boolean mVideoTurnedOn;
1332 StopwatchTimer mVideoTurnedOnTimer;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001333
Dianne Hackborn617f8772009-03-31 15:04:46 -07001334 Counter[] mUserActivityCounters;
1335
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001336 /**
1337 * The statistics we have collected for this uid's wake locks.
1338 */
1339 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>();
1340
1341 /**
1342 * The statistics we have collected for this uid's sensor activations.
1343 */
1344 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>();
1345
1346 /**
1347 * The statistics we have collected for this uid's processes.
1348 */
1349 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>();
1350
1351 /**
1352 * The statistics we have collected for this uid's processes.
1353 */
1354 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>();
1355
1356 public Uid(int uid) {
1357 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001358 mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, null, mUnpluggables);
1359 mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables);
1360 mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001361 mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED,
1362 null, mUnpluggables);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001363 mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, null, mUnpluggables);
1364 mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001365 }
1366
1367 @Override
1368 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
1369 return mWakelockStats;
1370 }
1371
1372 @Override
1373 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() {
1374 return mSensorStats;
1375 }
1376
1377 @Override
1378 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
1379 return mProcessStats;
1380 }
1381
1382 @Override
1383 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
1384 return mPackageStats;
1385 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001386
1387 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001388 public int getUid() {
1389 return mUid;
1390 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001391
1392 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001393 public long getTcpBytesReceived(int which) {
1394 if (which == STATS_LAST) {
1395 return mLoadedTcpBytesReceived;
1396 } else {
1397 long current = computeCurrentTcpBytesReceived();
1398 if (which == STATS_UNPLUGGED) {
1399 current -= mTcpBytesReceivedAtLastUnplug;
1400 } else if (which == STATS_TOTAL) {
1401 current += mLoadedTcpBytesReceived;
1402 }
1403 return current;
1404 }
1405 }
1406
1407 public long computeCurrentTcpBytesReceived() {
1408 return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0
1409 ? (NetStat.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0);
1410 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001411
1412 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001413 public long getTcpBytesSent(int which) {
1414 if (which == STATS_LAST) {
1415 return mLoadedTcpBytesSent;
1416 } else {
1417 long current = computeCurrentTcpBytesSent();
1418 if (which == STATS_UNPLUGGED) {
1419 current -= mTcpBytesSentAtLastUnplug;
1420 } else if (which == STATS_TOTAL) {
1421 current += mLoadedTcpBytesSent;
1422 }
1423 return current;
1424 }
1425 }
1426
The Android Open Source Project10592532009-03-18 17:39:46 -07001427 @Override
Dianne Hackborn617f8772009-03-31 15:04:46 -07001428 public void noteWifiTurnedOnLocked() {
1429 if (!mWifiTurnedOn) {
1430 mWifiTurnedOn = true;
1431 mWifiTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
1432 }
1433 }
1434
1435 @Override
1436 public void noteWifiTurnedOffLocked() {
1437 if (mWifiTurnedOn) {
1438 mWifiTurnedOn = false;
1439 mWifiTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
1440 }
1441 }
1442
1443 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07001444 public void noteFullWifiLockAcquiredLocked() {
1445 if (!mFullWifiLockOut) {
1446 mFullWifiLockOut = true;
1447 mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
1448 }
1449 }
1450
1451 @Override
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001452 public void noteVideoTurnedOnLocked() {
1453 if (!mVideoTurnedOn) {
1454 mVideoTurnedOn = true;
1455 mVideoTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
1456 }
1457 }
1458
1459 @Override
1460 public void noteVideoTurnedOffLocked() {
1461 if (mVideoTurnedOn) {
1462 mVideoTurnedOn = false;
1463 mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
1464 }
1465 }
1466
1467 @Override
1468 public void noteAudioTurnedOnLocked() {
1469 if (!mAudioTurnedOn) {
1470 mAudioTurnedOn = true;
1471 mAudioTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
1472 }
1473 }
1474
1475 @Override
1476 public void noteAudioTurnedOffLocked() {
1477 if (mAudioTurnedOn) {
1478 mAudioTurnedOn = false;
1479 mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
1480 }
1481 }
1482
1483 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07001484 public void noteFullWifiLockReleasedLocked() {
1485 if (mFullWifiLockOut) {
1486 mFullWifiLockOut = false;
1487 mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
1488 }
1489 }
1490
1491 @Override
1492 public void noteScanWifiLockAcquiredLocked() {
1493 if (!mScanWifiLockOut) {
1494 mScanWifiLockOut = true;
1495 mScanWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
1496 }
1497 }
1498
1499 @Override
1500 public void noteScanWifiLockReleasedLocked() {
1501 if (mScanWifiLockOut) {
1502 mScanWifiLockOut = false;
1503 mScanWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
1504 }
1505 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001506
1507 @Override
1508 public void noteWifiMulticastEnabledLocked() {
1509 if (!mWifiMulticastEnabled) {
1510 mWifiMulticastEnabled = true;
1511 mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this);
1512 }
1513 }
1514
1515 @Override
1516 public void noteWifiMulticastDisabledLocked() {
1517 if (mWifiMulticastEnabled) {
1518 mWifiMulticastEnabled = false;
1519 mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this);
1520 }
1521 }
1522
Dianne Hackborn617f8772009-03-31 15:04:46 -07001523 @Override
1524 public long getWifiTurnedOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001525 return mWifiTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001526 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001527
1528 @Override
1529 public long getAudioTurnedOnTime(long batteryRealtime, int which) {
1530 return mAudioTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
1531 }
1532
1533 @Override
1534 public long getVideoTurnedOnTime(long batteryRealtime, int which) {
1535 return mVideoTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
1536 }
1537
The Android Open Source Project10592532009-03-18 17:39:46 -07001538 @Override
1539 public long getFullWifiLockTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001540 return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001541 }
1542
1543 @Override
1544 public long getScanWifiLockTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001545 return mScanWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001546 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001547
1548 @Override
1549 public long getWifiMulticastTime(long batteryRealtime, int which) {
1550 return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime,
1551 which);
1552 }
1553
Dianne Hackborn617f8772009-03-31 15:04:46 -07001554 @Override
1555 public void noteUserActivityLocked(int type) {
1556 if (mUserActivityCounters == null) {
1557 initUserActivityLocked();
1558 }
1559 if (type < 0) type = 0;
1560 else if (type >= NUM_USER_ACTIVITY_TYPES) type = NUM_USER_ACTIVITY_TYPES-1;
1561 mUserActivityCounters[type].stepLocked();
1562 }
1563
1564 @Override
1565 public boolean hasUserActivity() {
1566 return mUserActivityCounters != null;
1567 }
1568
1569 @Override
1570 public int getUserActivityCount(int type, int which) {
1571 if (mUserActivityCounters == null) {
1572 return 0;
1573 }
Evan Millarc64edde2009-04-18 12:26:32 -07001574 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001575 }
1576
1577 void initUserActivityLocked() {
1578 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
1579 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
1580 mUserActivityCounters[i] = new Counter(mUnpluggables);
1581 }
1582 }
1583
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001584 public long computeCurrentTcpBytesSent() {
1585 return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0
1586 ? (NetStat.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0);
1587 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001589 void writeToParcelLocked(Parcel out, long batteryRealtime) {
1590 out.writeInt(mWakelockStats.size());
1591 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
1592 out.writeString(wakelockEntry.getKey());
1593 Uid.Wakelock wakelock = wakelockEntry.getValue();
1594 wakelock.writeToParcelLocked(out, batteryRealtime);
1595 }
1596
1597 out.writeInt(mSensorStats.size());
1598 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) {
1599 out.writeInt(sensorEntry.getKey());
1600 Uid.Sensor sensor = sensorEntry.getValue();
1601 sensor.writeToParcelLocked(out, batteryRealtime);
1602 }
1603
1604 out.writeInt(mProcessStats.size());
1605 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) {
1606 out.writeString(procEntry.getKey());
1607 Uid.Proc proc = procEntry.getValue();
1608 proc.writeToParcelLocked(out);
1609 }
1610
1611 out.writeInt(mPackageStats.size());
1612 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
1613 out.writeString(pkgEntry.getKey());
1614 Uid.Pkg pkg = pkgEntry.getValue();
1615 pkg.writeToParcelLocked(out);
1616 }
1617
1618 out.writeLong(mLoadedTcpBytesReceived);
1619 out.writeLong(mLoadedTcpBytesSent);
1620 out.writeLong(computeCurrentTcpBytesReceived());
1621 out.writeLong(computeCurrentTcpBytesSent());
1622 out.writeLong(mTcpBytesReceivedAtLastUnplug);
1623 out.writeLong(mTcpBytesSentAtLastUnplug);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001624 mWifiTurnedOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07001625 mFullWifiLockTimer.writeToParcel(out, batteryRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001626 mAudioTurnedOnTimer.writeToParcel(out, batteryRealtime);
1627 mVideoTurnedOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07001628 mScanWifiLockTimer.writeToParcel(out, batteryRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001629 mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001630 if (mUserActivityCounters == null) {
1631 out.writeInt(0);
1632 } else {
1633 out.writeInt(1);
1634 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
1635 mUserActivityCounters[i].writeToParcel(out);
1636 }
1637 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001638 }
1639
1640 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
1641 int numWakelocks = in.readInt();
1642 mWakelockStats.clear();
1643 for (int j = 0; j < numWakelocks; j++) {
1644 String wakelockName = in.readString();
1645 Uid.Wakelock wakelock = new Wakelock();
1646 wakelock.readFromParcelLocked(unpluggables, in);
1647 mWakelockStats.put(wakelockName, wakelock);
1648 }
1649
1650 int numSensors = in.readInt();
1651 mSensorStats.clear();
1652 for (int k = 0; k < numSensors; k++) {
1653 int sensorNumber = in.readInt();
1654 Uid.Sensor sensor = new Sensor(sensorNumber);
1655 sensor.readFromParcelLocked(mUnpluggables, in);
1656 mSensorStats.put(sensorNumber, sensor);
1657 }
1658
1659 int numProcs = in.readInt();
1660 mProcessStats.clear();
1661 for (int k = 0; k < numProcs; k++) {
1662 String processName = in.readString();
1663 Uid.Proc proc = new Proc();
1664 proc.readFromParcelLocked(in);
1665 mProcessStats.put(processName, proc);
1666 }
1667
1668 int numPkgs = in.readInt();
1669 mPackageStats.clear();
1670 for (int l = 0; l < numPkgs; l++) {
1671 String packageName = in.readString();
1672 Uid.Pkg pkg = new Pkg();
1673 pkg.readFromParcelLocked(in);
1674 mPackageStats.put(packageName, pkg);
1675 }
1676
1677 mLoadedTcpBytesReceived = in.readLong();
1678 mLoadedTcpBytesSent = in.readLong();
1679 mCurrentTcpBytesReceived = in.readLong();
1680 mCurrentTcpBytesSent = in.readLong();
1681 mTcpBytesReceivedAtLastUnplug = in.readLong();
1682 mTcpBytesSentAtLastUnplug = in.readLong();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001683 mWifiTurnedOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001684 mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07001685 mFullWifiLockOut = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001686 mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables, in);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001687 mAudioTurnedOn = false;
1688 mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, null, mUnpluggables, in);
1689 mVideoTurnedOn = false;
1690 mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07001691 mScanWifiLockOut = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001692 mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables, in);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001693 mWifiMulticastEnabled = false;
1694 mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED,
1695 null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001696 if (in.readInt() == 0) {
1697 mUserActivityCounters = null;
1698 } else {
1699 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
1700 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
1701 mUserActivityCounters[i] = new Counter(mUnpluggables, in);
1702 }
1703 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001704 }
1705
1706 /**
1707 * The statistics associated with a particular wake lock.
1708 */
1709 public final class Wakelock extends BatteryStats.Uid.Wakelock {
1710 /**
1711 * How long (in ms) this uid has been keeping the device partially awake.
1712 */
Evan Millarc64edde2009-04-18 12:26:32 -07001713 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001714
1715 /**
1716 * How long (in ms) this uid has been keeping the device fully awake.
1717 */
Evan Millarc64edde2009-04-18 12:26:32 -07001718 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001719
1720 /**
1721 * How long (in ms) this uid has had a window keeping the device awake.
1722 */
Evan Millarc64edde2009-04-18 12:26:32 -07001723 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001724
1725 /**
1726 * Reads a possibly null Timer from a Parcel. The timer is associated with the
1727 * proper timer pool from the given BatteryStatsImpl object.
1728 *
1729 * @param in the Parcel to be read from.
1730 * return a new Timer, or null.
1731 */
Evan Millarc64edde2009-04-18 12:26:32 -07001732 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001733 ArrayList<Unpluggable> unpluggables, Parcel in) {
1734 if (in.readInt() == 0) {
1735 return null;
1736 }
1737
Evan Millarc64edde2009-04-18 12:26:32 -07001738 return new StopwatchTimer(type, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001739 }
1740
1741 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
1742 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
1743 mPartialTimers, unpluggables, in);
1744 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
1745 mFullTimers, unpluggables, in);
1746 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
1747 mWindowTimers, unpluggables, in);
1748 }
1749
1750 void writeToParcelLocked(Parcel out, long batteryRealtime) {
1751 Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime);
1752 Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime);
1753 Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime);
1754 }
1755
1756 @Override
1757 public Timer getWakeTime(int type) {
1758 switch (type) {
1759 case WAKE_TYPE_FULL: return mTimerFull;
1760 case WAKE_TYPE_PARTIAL: return mTimerPartial;
1761 case WAKE_TYPE_WINDOW: return mTimerWindow;
1762 default: throw new IllegalArgumentException("type = " + type);
1763 }
1764 }
1765 }
1766
1767 public final class Sensor extends BatteryStats.Uid.Sensor {
1768 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07001769 StopwatchTimer mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001770
1771 public Sensor(int handle) {
1772 mHandle = handle;
1773 }
1774
Evan Millarc64edde2009-04-18 12:26:32 -07001775 private StopwatchTimer readTimerFromParcel(ArrayList<Unpluggable> unpluggables,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001776 Parcel in) {
1777 if (in.readInt() == 0) {
1778 return null;
1779 }
1780
Evan Millarc64edde2009-04-18 12:26:32 -07001781 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001782 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001783 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001784 mSensorTimers.put(mHandle, pool);
1785 }
Evan Millarc64edde2009-04-18 12:26:32 -07001786 return new StopwatchTimer(0, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001787 }
1788
1789 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
1790 mTimer = readTimerFromParcel(unpluggables, in);
1791 }
1792
1793 void writeToParcelLocked(Parcel out, long batteryRealtime) {
1794 Timer.writeTimerToParcel(out, mTimer, batteryRealtime);
1795 }
1796
1797 @Override
1798 public Timer getSensorTime() {
1799 return mTimer;
1800 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001801
1802 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001803 public int getHandle() {
1804 return mHandle;
1805 }
1806 }
1807
1808 /**
1809 * The statistics associated with a particular process.
1810 */
1811 public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable {
1812 /**
1813 * Total time (in 1/100 sec) spent executing in user code.
1814 */
1815 long mUserTime;
1816
1817 /**
1818 * Total time (in 1/100 sec) spent executing in kernel code.
1819 */
1820 long mSystemTime;
1821
1822 /**
1823 * Number of times the process has been started.
1824 */
1825 int mStarts;
1826
1827 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001828 * Amount of time the process was running in the foreground.
1829 */
1830 long mForegroundTime;
1831
1832 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001833 * The amount of user time loaded from a previous save.
1834 */
1835 long mLoadedUserTime;
1836
1837 /**
1838 * The amount of system time loaded from a previous save.
1839 */
1840 long mLoadedSystemTime;
1841
1842 /**
1843 * The number of times the process has started from a previous save.
1844 */
1845 int mLoadedStarts;
1846
1847 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001848 * The amount of foreground time loaded from a previous save.
1849 */
1850 long mLoadedForegroundTime;
1851
1852 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001853 * The amount of user time loaded from the previous run.
1854 */
1855 long mLastUserTime;
1856
1857 /**
1858 * The amount of system time loaded from the previous run.
1859 */
1860 long mLastSystemTime;
1861
1862 /**
1863 * The number of times the process has started from the previous run.
1864 */
1865 int mLastStarts;
1866
1867 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001868 * The amount of foreground time loaded from the previous run
1869 */
1870 long mLastForegroundTime;
1871
1872 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001873 * The amount of user time when last unplugged.
1874 */
1875 long mUnpluggedUserTime;
1876
1877 /**
1878 * The amount of system time when last unplugged.
1879 */
1880 long mUnpluggedSystemTime;
1881
1882 /**
1883 * The number of times the process has started before unplugged.
1884 */
1885 int mUnpluggedStarts;
1886
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001887 /**
1888 * The amount of foreground time since unplugged.
1889 */
1890 long mUnpluggedForegroundTime;
1891
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001892 Proc() {
1893 mUnpluggables.add(this);
1894 }
1895
1896 public void unplug(long batteryUptime, long batteryRealtime) {
1897 mUnpluggedUserTime = mUserTime;
1898 mUnpluggedSystemTime = mSystemTime;
1899 mUnpluggedStarts = mStarts;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001900 mUnpluggedForegroundTime = mForegroundTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001901 }
1902
1903 public void plug(long batteryUptime, long batteryRealtime) {
1904 }
1905
1906 void writeToParcelLocked(Parcel out) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001907 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
1908 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
1909
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001910 out.writeLong(mUserTime);
1911 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001912 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001913 out.writeInt(mStarts);
1914 out.writeLong(mLoadedUserTime);
1915 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001916 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001917 out.writeInt(mLoadedStarts);
1918 out.writeLong(mLastUserTime);
1919 out.writeLong(mLastSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001920 out.writeLong(mLastForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001921 out.writeInt(mLastStarts);
1922 out.writeLong(mUnpluggedUserTime);
1923 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001924 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001925 out.writeInt(mUnpluggedStarts);
1926 }
1927
1928 void readFromParcelLocked(Parcel in) {
1929 mUserTime = in.readLong();
1930 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001931 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001932 mStarts = in.readInt();
1933 mLoadedUserTime = in.readLong();
1934 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001935 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001936 mLoadedStarts = in.readInt();
1937 mLastUserTime = in.readLong();
1938 mLastSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001939 mLastForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001940 mLastStarts = in.readInt();
1941 mUnpluggedUserTime = in.readLong();
1942 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001943 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001944 mUnpluggedStarts = in.readInt();
1945 }
1946
1947 public BatteryStatsImpl getBatteryStats() {
1948 return BatteryStatsImpl.this;
1949 }
1950
1951 public void addCpuTimeLocked(int utime, int stime) {
1952 mUserTime += utime;
1953 mSystemTime += stime;
1954 }
1955
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001956 public void addForegroundTimeLocked(long ttime) {
1957 mForegroundTime += ttime;
1958 }
1959
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001960 public void incStartsLocked() {
1961 mStarts++;
1962 }
1963
1964 @Override
1965 public long getUserTime(int which) {
1966 long val;
1967 if (which == STATS_LAST) {
1968 val = mLastUserTime;
1969 } else {
1970 val = mUserTime;
1971 if (which == STATS_CURRENT) {
1972 val -= mLoadedUserTime;
1973 } else if (which == STATS_UNPLUGGED) {
1974 val -= mUnpluggedUserTime;
1975 }
1976 }
1977 return val;
1978 }
1979
1980 @Override
1981 public long getSystemTime(int which) {
1982 long val;
1983 if (which == STATS_LAST) {
1984 val = mLastSystemTime;
1985 } else {
1986 val = mSystemTime;
1987 if (which == STATS_CURRENT) {
1988 val -= mLoadedSystemTime;
1989 } else if (which == STATS_UNPLUGGED) {
1990 val -= mUnpluggedSystemTime;
1991 }
1992 }
1993 return val;
1994 }
1995
1996 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001997 public long getForegroundTime(int which) {
1998 long val;
1999 if (which == STATS_LAST) {
2000 val = mLastForegroundTime;
2001 } else {
2002 val = mForegroundTime;
2003 if (which == STATS_CURRENT) {
2004 val -= mLoadedForegroundTime;
2005 } else if (which == STATS_UNPLUGGED) {
2006 val -= mUnpluggedForegroundTime;
2007 }
2008 }
2009 return val;
2010 }
2011
2012 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002013 public int getStarts(int which) {
2014 int val;
2015 if (which == STATS_LAST) {
2016 val = mLastStarts;
2017 } else {
2018 val = mStarts;
2019 if (which == STATS_CURRENT) {
2020 val -= mLoadedStarts;
2021 } else if (which == STATS_UNPLUGGED) {
2022 val -= mUnpluggedStarts;
2023 }
2024 }
2025 return val;
2026 }
2027 }
2028
2029 /**
2030 * The statistics associated with a particular package.
2031 */
2032 public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable {
2033 /**
2034 * Number of times this package has done something that could wake up the
2035 * device from sleep.
2036 */
2037 int mWakeups;
2038
2039 /**
2040 * Number of things that could wake up the device loaded from a
2041 * previous save.
2042 */
2043 int mLoadedWakeups;
2044
2045 /**
2046 * Number of things that could wake up the device as of the
2047 * last run.
2048 */
2049 int mLastWakeups;
2050
2051 /**
2052 * Number of things that could wake up the device as of the
2053 * last run.
2054 */
2055 int mUnpluggedWakeups;
2056
2057 /**
2058 * The statics we have collected for this package's services.
2059 */
2060 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
2061
2062 Pkg() {
2063 mUnpluggables.add(this);
2064 }
2065
2066 public void unplug(long batteryUptime, long batteryRealtime) {
2067 mUnpluggedWakeups = mWakeups;
2068 }
2069
2070 public void plug(long batteryUptime, long batteryRealtime) {
2071 }
2072
2073 void readFromParcelLocked(Parcel in) {
2074 mWakeups = in.readInt();
2075 mLoadedWakeups = in.readInt();
2076 mLastWakeups = in.readInt();
2077 mUnpluggedWakeups = in.readInt();
2078
2079 int numServs = in.readInt();
2080 mServiceStats.clear();
2081 for (int m = 0; m < numServs; m++) {
2082 String serviceName = in.readString();
2083 Uid.Pkg.Serv serv = new Serv();
2084 mServiceStats.put(serviceName, serv);
2085
2086 serv.readFromParcelLocked(in);
2087 }
2088 }
2089
2090 void writeToParcelLocked(Parcel out) {
2091 out.writeInt(mWakeups);
2092 out.writeInt(mLoadedWakeups);
2093 out.writeInt(mLastWakeups);
2094 out.writeInt(mUnpluggedWakeups);
2095
2096 out.writeInt(mServiceStats.size());
2097 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
2098 out.writeString(servEntry.getKey());
2099 Uid.Pkg.Serv serv = servEntry.getValue();
2100
2101 serv.writeToParcelLocked(out);
2102 }
2103 }
2104
2105 @Override
2106 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
2107 return mServiceStats;
2108 }
2109
2110 @Override
2111 public int getWakeups(int which) {
2112 int val;
2113 if (which == STATS_LAST) {
2114 val = mLastWakeups;
2115 } else {
2116 val = mWakeups;
2117 if (which == STATS_CURRENT) {
2118 val -= mLoadedWakeups;
2119 } else if (which == STATS_UNPLUGGED) {
2120 val -= mUnpluggedWakeups;
2121 }
2122 }
2123
2124 return val;
2125 }
2126
2127 /**
2128 * The statistics associated with a particular service.
2129 */
2130 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable {
2131 /**
2132 * Total time (ms in battery uptime) the service has been left started.
2133 */
2134 long mStartTime;
2135
2136 /**
2137 * If service has been started and not yet stopped, this is
2138 * when it was started.
2139 */
2140 long mRunningSince;
2141
2142 /**
2143 * True if we are currently running.
2144 */
2145 boolean mRunning;
2146
2147 /**
2148 * Total number of times startService() has been called.
2149 */
2150 int mStarts;
2151
2152 /**
2153 * Total time (ms in battery uptime) the service has been left launched.
2154 */
2155 long mLaunchedTime;
2156
2157 /**
2158 * If service has been launched and not yet exited, this is
2159 * when it was launched (ms in battery uptime).
2160 */
2161 long mLaunchedSince;
2162
2163 /**
2164 * True if we are currently launched.
2165 */
2166 boolean mLaunched;
2167
2168 /**
2169 * Total number times the service has been launched.
2170 */
2171 int mLaunches;
2172
2173 /**
2174 * The amount of time spent started loaded from a previous save
2175 * (ms in battery uptime).
2176 */
2177 long mLoadedStartTime;
2178
2179 /**
2180 * The number of starts loaded from a previous save.
2181 */
2182 int mLoadedStarts;
2183
2184 /**
2185 * The number of launches loaded from a previous save.
2186 */
2187 int mLoadedLaunches;
2188
2189 /**
2190 * The amount of time spent started as of the last run (ms
2191 * in battery uptime).
2192 */
2193 long mLastStartTime;
2194
2195 /**
2196 * The number of starts as of the last run.
2197 */
2198 int mLastStarts;
2199
2200 /**
2201 * The number of launches as of the last run.
2202 */
2203 int mLastLaunches;
2204
2205 /**
2206 * The amount of time spent started when last unplugged (ms
2207 * in battery uptime).
2208 */
2209 long mUnpluggedStartTime;
2210
2211 /**
2212 * The number of starts when last unplugged.
2213 */
2214 int mUnpluggedStarts;
2215
2216 /**
2217 * The number of launches when last unplugged.
2218 */
2219 int mUnpluggedLaunches;
2220
2221 Serv() {
2222 mUnpluggables.add(this);
2223 }
2224
2225 public void unplug(long batteryUptime, long batteryRealtime) {
2226 mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime);
2227 mUnpluggedStarts = mStarts;
2228 mUnpluggedLaunches = mLaunches;
2229 }
2230
2231 public void plug(long batteryUptime, long batteryRealtime) {
2232 }
2233
2234 void readFromParcelLocked(Parcel in) {
2235 mStartTime = in.readLong();
2236 mRunningSince = in.readLong();
2237 mRunning = in.readInt() != 0;
2238 mStarts = in.readInt();
2239 mLaunchedTime = in.readLong();
2240 mLaunchedSince = in.readLong();
2241 mLaunched = in.readInt() != 0;
2242 mLaunches = in.readInt();
2243 mLoadedStartTime = in.readLong();
2244 mLoadedStarts = in.readInt();
2245 mLoadedLaunches = in.readInt();
2246 mLastStartTime = in.readLong();
2247 mLastStarts = in.readInt();
2248 mLastLaunches = in.readInt();
2249 mUnpluggedStartTime = in.readLong();
2250 mUnpluggedStarts = in.readInt();
2251 mUnpluggedLaunches = in.readInt();
2252 }
2253
2254 void writeToParcelLocked(Parcel out) {
2255 out.writeLong(mStartTime);
2256 out.writeLong(mRunningSince);
2257 out.writeInt(mRunning ? 1 : 0);
2258 out.writeInt(mStarts);
2259 out.writeLong(mLaunchedTime);
2260 out.writeLong(mLaunchedSince);
2261 out.writeInt(mLaunched ? 1 : 0);
2262 out.writeInt(mLaunches);
2263 out.writeLong(mLoadedStartTime);
2264 out.writeInt(mLoadedStarts);
2265 out.writeInt(mLoadedLaunches);
2266 out.writeLong(mLastStartTime);
2267 out.writeInt(mLastStarts);
2268 out.writeInt(mLastLaunches);
2269 out.writeLong(mUnpluggedStartTime);
2270 out.writeInt(mUnpluggedStarts);
2271 out.writeInt(mUnpluggedLaunches);
2272 }
2273
2274 long getLaunchTimeToNowLocked(long batteryUptime) {
2275 if (!mLaunched) return mLaunchedTime;
2276 return mLaunchedTime + batteryUptime - mLaunchedSince;
2277 }
2278
2279 long getStartTimeToNowLocked(long batteryUptime) {
2280 if (!mRunning) return mStartTime;
2281 return mStartTime + batteryUptime - mRunningSince;
2282 }
2283
2284 public void startLaunchedLocked() {
2285 if (!mLaunched) {
2286 mLaunches++;
2287 mLaunchedSince = getBatteryUptimeLocked();
2288 mLaunched = true;
2289 }
2290 }
2291
2292 public void stopLaunchedLocked() {
2293 if (mLaunched) {
2294 long time = getBatteryUptimeLocked() - mLaunchedSince;
2295 if (time > 0) {
2296 mLaunchedTime += time;
2297 } else {
2298 mLaunches--;
2299 }
2300 mLaunched = false;
2301 }
2302 }
2303
2304 public void startRunningLocked() {
2305 if (!mRunning) {
2306 mStarts++;
2307 mRunningSince = getBatteryUptimeLocked();
2308 mRunning = true;
2309 }
2310 }
2311
2312 public void stopRunningLocked() {
2313 if (mRunning) {
2314 long time = getBatteryUptimeLocked() - mRunningSince;
2315 if (time > 0) {
2316 mStartTime += time;
2317 } else {
2318 mStarts--;
2319 }
2320 mRunning = false;
2321 }
2322 }
2323
2324 public BatteryStatsImpl getBatteryStats() {
2325 return BatteryStatsImpl.this;
2326 }
2327
2328 @Override
2329 public int getLaunches(int which) {
2330 int val;
2331
2332 if (which == STATS_LAST) {
2333 val = mLastLaunches;
2334 } else {
2335 val = mLaunches;
2336 if (which == STATS_CURRENT) {
2337 val -= mLoadedLaunches;
2338 } else if (which == STATS_UNPLUGGED) {
2339 val -= mUnpluggedLaunches;
2340 }
2341 }
2342
2343 return val;
2344 }
2345
2346 @Override
2347 public long getStartTime(long now, int which) {
2348 long val;
2349 if (which == STATS_LAST) {
2350 val = mLastStartTime;
2351 } else {
2352 val = getStartTimeToNowLocked(now);
2353 if (which == STATS_CURRENT) {
2354 val -= mLoadedStartTime;
2355 } else if (which == STATS_UNPLUGGED) {
2356 val -= mUnpluggedStartTime;
2357 }
2358 }
2359
2360 return val;
2361 }
2362
2363 @Override
2364 public int getStarts(int which) {
2365 int val;
2366 if (which == STATS_LAST) {
2367 val = mLastStarts;
2368 } else {
2369 val = mStarts;
2370 if (which == STATS_CURRENT) {
2371 val -= mLoadedStarts;
2372 } else if (which == STATS_UNPLUGGED) {
2373 val -= mUnpluggedStarts;
2374 }
2375 }
2376
2377 return val;
2378 }
2379 }
2380
2381 public BatteryStatsImpl getBatteryStats() {
2382 return BatteryStatsImpl.this;
2383 }
2384
2385 public void incWakeupsLocked() {
2386 mWakeups++;
2387 }
2388
2389 final Serv newServiceStatsLocked() {
2390 return new Serv();
2391 }
2392 }
2393
2394 /**
2395 * Retrieve the statistics object for a particular process, creating
2396 * if needed.
2397 */
2398 public Proc getProcessStatsLocked(String name) {
2399 Proc ps = mProcessStats.get(name);
2400 if (ps == null) {
2401 ps = new Proc();
2402 mProcessStats.put(name, ps);
2403 }
2404
2405 return ps;
2406 }
2407
2408 /**
2409 * Retrieve the statistics object for a particular service, creating
2410 * if needed.
2411 */
2412 public Pkg getPackageStatsLocked(String name) {
2413 Pkg ps = mPackageStats.get(name);
2414 if (ps == null) {
2415 ps = new Pkg();
2416 mPackageStats.put(name, ps);
2417 }
2418
2419 return ps;
2420 }
2421
2422 /**
2423 * Retrieve the statistics object for a particular service, creating
2424 * if needed.
2425 */
2426 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
2427 Pkg ps = getPackageStatsLocked(pkg);
2428 Pkg.Serv ss = ps.mServiceStats.get(serv);
2429 if (ss == null) {
2430 ss = ps.newServiceStatsLocked();
2431 ps.mServiceStats.put(serv, ss);
2432 }
2433
2434 return ss;
2435 }
2436
Evan Millarc64edde2009-04-18 12:26:32 -07002437 public StopwatchTimer getWakeTimerLocked(String name, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002438 Wakelock wl = mWakelockStats.get(name);
2439 if (wl == null) {
2440 wl = new Wakelock();
2441 mWakelockStats.put(name, wl);
2442 }
Evan Millarc64edde2009-04-18 12:26:32 -07002443 StopwatchTimer t = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002444 switch (type) {
2445 case WAKE_TYPE_PARTIAL:
2446 t = wl.mTimerPartial;
2447 if (t == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002448 t = new StopwatchTimer(WAKE_TYPE_PARTIAL, mPartialTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002449 wl.mTimerPartial = t;
2450 }
2451 return t;
2452 case WAKE_TYPE_FULL:
2453 t = wl.mTimerFull;
2454 if (t == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002455 t = new StopwatchTimer(WAKE_TYPE_FULL, mFullTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002456 wl.mTimerFull = t;
2457 }
2458 return t;
2459 case WAKE_TYPE_WINDOW:
2460 t = wl.mTimerWindow;
2461 if (t == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002462 t = new StopwatchTimer(WAKE_TYPE_WINDOW, mWindowTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002463 wl.mTimerWindow = t;
2464 }
2465 return t;
2466 default:
2467 throw new IllegalArgumentException("type=" + type);
2468 }
2469 }
2470
Evan Millarc64edde2009-04-18 12:26:32 -07002471 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002472 Sensor se = mSensorStats.get(sensor);
2473 if (se == null) {
2474 if (!create) {
2475 return null;
2476 }
2477 se = new Sensor(sensor);
2478 mSensorStats.put(sensor, se);
2479 }
Evan Millarc64edde2009-04-18 12:26:32 -07002480 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002481 if (t != null) {
2482 return t;
2483 }
Evan Millarc64edde2009-04-18 12:26:32 -07002484 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002485 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002486 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002487 mSensorTimers.put(sensor, timers);
2488 }
Evan Millarc64edde2009-04-18 12:26:32 -07002489 t = new StopwatchTimer(BatteryStats.SENSOR, timers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002490 se.mTimer = t;
2491 return t;
2492 }
2493
2494 public void noteStartWakeLocked(String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07002495 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002496 if (t != null) {
2497 t.startRunningLocked(BatteryStatsImpl.this);
2498 }
2499 }
2500
2501 public void noteStopWakeLocked(String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07002502 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002503 if (t != null) {
2504 t.stopRunningLocked(BatteryStatsImpl.this);
2505 }
2506 }
2507
2508 public void noteStartSensor(int sensor) {
Evan Millarc64edde2009-04-18 12:26:32 -07002509 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002510 if (t != null) {
2511 t.startRunningLocked(BatteryStatsImpl.this);
2512 }
2513 }
2514
2515 public void noteStopSensor(int sensor) {
2516 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07002517 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002518 if (t != null) {
2519 t.stopRunningLocked(BatteryStatsImpl.this);
2520 }
2521 }
2522
2523 public void noteStartGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07002524 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002525 if (t != null) {
2526 t.startRunningLocked(BatteryStatsImpl.this);
2527 }
2528 }
2529
2530 public void noteStopGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07002531 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002532 if (t != null) {
2533 t.stopRunningLocked(BatteryStatsImpl.this);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002534 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002535 }
2536
2537 public BatteryStatsImpl getBatteryStats() {
2538 return BatteryStatsImpl.this;
2539 }
2540 }
2541
2542 public BatteryStatsImpl(String filename) {
2543 mFile = new File(filename);
2544 mBackupFile = new File(filename + ".bak");
2545 mStartCount++;
Evan Millarc64edde2009-04-18 12:26:32 -07002546 mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002547 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07002548 mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002549 }
2550 mInputEventCounter = new Counter(mUnpluggables);
Evan Millarc64edde2009-04-18 12:26:32 -07002551 mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002552 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07002553 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002554 }
2555 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07002556 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002557 }
Evan Millarc64edde2009-04-18 12:26:32 -07002558 mWifiOnTimer = new StopwatchTimer(-3, null, mUnpluggables);
2559 mWifiRunningTimer = new StopwatchTimer(-4, null, mUnpluggables);
2560 mBluetoothOnTimer = new StopwatchTimer(-5, null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002561 mOnBattery = mOnBatteryInternal = false;
2562 mTrackBatteryPastUptime = 0;
2563 mTrackBatteryPastRealtime = 0;
2564 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
2565 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
2566 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
2567 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
Evan Millar633a1742009-04-02 16:36:33 -07002568 mDischargeStartLevel = 0;
2569 mDischargeCurrentLevel = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002570 }
2571
2572 public BatteryStatsImpl(Parcel p) {
2573 mFile = mBackupFile = null;
2574 readFromParcel(p);
2575 }
2576
2577 @Override
2578 public int getStartCount() {
2579 return mStartCount;
2580 }
2581
2582 public boolean isOnBattery() {
2583 return mOnBattery;
2584 }
2585
The Android Open Source Project10592532009-03-18 17:39:46 -07002586 public void setOnBattery(boolean onBattery, int level) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002587 synchronized(this) {
Evan Millarc64edde2009-04-18 12:26:32 -07002588 updateKernelWakelocksLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002589 if (mOnBattery != onBattery) {
2590 mOnBattery = mOnBatteryInternal = onBattery;
2591
2592 long uptime = SystemClock.uptimeMillis() * 1000;
2593 long mSecRealtime = SystemClock.elapsedRealtime();
2594 long realtime = mSecRealtime * 1000;
2595 if (onBattery) {
2596 mTrackBatteryUptimeStart = uptime;
2597 mTrackBatteryRealtimeStart = realtime;
2598 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
2599 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
Evan Millar633a1742009-04-02 16:36:33 -07002600 mDischargeCurrentLevel = mDischargeStartLevel = level;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002601 doUnplug(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
2602 } else {
2603 mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
2604 mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
Evan Millar633a1742009-04-02 16:36:33 -07002605 mDischargeCurrentLevel = level;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002606 doPlug(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
2607 }
2608 if ((mLastWriteTime + (60 * 1000)) < mSecRealtime) {
2609 if (mFile != null) {
2610 writeLocked();
2611 }
2612 }
2613 }
2614 }
2615 }
Evan Millar633a1742009-04-02 16:36:33 -07002616
2617 public void recordCurrentLevel(int level) {
2618 mDischargeCurrentLevel = level;
2619 }
Evan Millarc64edde2009-04-18 12:26:32 -07002620
2621 public void updateKernelWakelocksLocked() {
2622 Map<String, KernelWakelockStats> m = readKernelWakelockStats();
2623
Marco Nelissend8593312009-04-30 14:45:06 -07002624 if (m == null) {
2625 // Not crashing might make board bringup easier.
2626 Log.w(TAG, "Couldn't get kernel wake lock stats");
2627 return;
2628 }
2629
Evan Millarc64edde2009-04-18 12:26:32 -07002630 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) {
2631 String name = ent.getKey();
2632 KernelWakelockStats kws = ent.getValue();
2633
2634 SamplingTimer kwlt = mKernelWakelockStats.get(name);
2635 if (kwlt == null) {
2636 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
2637 true /* track reported values */);
2638 mKernelWakelockStats.put(name, kwlt);
2639 }
2640 kwlt.updateCurrentReportedCount(kws.mCount);
2641 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
2642 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion);
2643 }
2644
2645 if (m.size() != mKernelWakelockStats.size()) {
2646 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
2647 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
2648 SamplingTimer st = ent.getValue();
2649 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) {
2650 st.setStale();
2651 }
2652 }
2653 }
2654 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002655
2656 public long getAwakeTimeBattery() {
2657 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
2658 }
2659
2660 public long getAwakeTimePlugged() {
2661 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
2662 }
2663
2664 @Override
2665 public long computeUptime(long curTime, int which) {
2666 switch (which) {
2667 case STATS_TOTAL: return mUptime + (curTime-mUptimeStart);
2668 case STATS_LAST: return mLastUptime;
2669 case STATS_CURRENT: return (curTime-mUptimeStart);
2670 case STATS_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart);
2671 }
2672 return 0;
2673 }
2674
2675 @Override
2676 public long computeRealtime(long curTime, int which) {
2677 switch (which) {
2678 case STATS_TOTAL: return mRealtime + (curTime-mRealtimeStart);
2679 case STATS_LAST: return mLastRealtime;
2680 case STATS_CURRENT: return (curTime-mRealtimeStart);
2681 case STATS_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart);
2682 }
2683 return 0;
2684 }
2685
2686 @Override
2687 public long computeBatteryUptime(long curTime, int which) {
2688 switch (which) {
2689 case STATS_TOTAL:
2690 return mBatteryUptime + getBatteryUptime(curTime);
2691 case STATS_LAST:
2692 return mBatteryLastUptime;
2693 case STATS_CURRENT:
2694 return getBatteryUptime(curTime);
2695 case STATS_UNPLUGGED:
2696 return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime;
2697 }
2698 return 0;
2699 }
2700
2701 @Override
2702 public long computeBatteryRealtime(long curTime, int which) {
2703 switch (which) {
2704 case STATS_TOTAL:
2705 return mBatteryRealtime + getBatteryRealtimeLocked(curTime);
2706 case STATS_LAST:
2707 return mBatteryLastRealtime;
2708 case STATS_CURRENT:
2709 return getBatteryRealtimeLocked(curTime);
2710 case STATS_UNPLUGGED:
2711 return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime;
2712 }
2713 return 0;
2714 }
2715
2716 long getBatteryUptimeLocked(long curTime) {
2717 long time = mTrackBatteryPastUptime;
2718 if (mOnBatteryInternal) {
2719 time += curTime - mTrackBatteryUptimeStart;
2720 }
2721 return time;
2722 }
2723
2724 long getBatteryUptimeLocked() {
2725 return getBatteryUptime(SystemClock.uptimeMillis() * 1000);
2726 }
2727
2728 @Override
2729 public long getBatteryUptime(long curTime) {
2730 return getBatteryUptimeLocked(curTime);
2731 }
2732
2733 long getBatteryRealtimeLocked(long curTime) {
2734 long time = mTrackBatteryPastRealtime;
2735 if (mOnBatteryInternal) {
2736 time += curTime - mTrackBatteryRealtimeStart;
2737 }
2738 return time;
2739 }
2740
2741 @Override
2742 public long getBatteryRealtime(long curTime) {
2743 return getBatteryRealtimeLocked(curTime);
2744 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002745
2746 private long getTcpBytes(long current, long[] dataBytes, int which) {
2747 if (which == STATS_LAST) {
2748 return dataBytes[STATS_LAST];
2749 } else {
2750 if (which == STATS_UNPLUGGED) {
2751 if (dataBytes[STATS_UNPLUGGED] < 0) {
2752 return dataBytes[STATS_LAST];
2753 } else {
2754 return current - dataBytes[STATS_UNPLUGGED];
2755 }
2756 } else if (which == STATS_TOTAL) {
2757 return (current - dataBytes[STATS_CURRENT]) + dataBytes[STATS_TOTAL];
2758 }
2759 return current - dataBytes[STATS_CURRENT];
2760 }
2761 }
2762
2763 /** Only STATS_UNPLUGGED works properly */
2764 public long getMobileTcpBytesSent(int which) {
2765 return getTcpBytes(NetStat.getMobileTxBytes(), mMobileDataTx, which);
2766 }
2767
2768 /** Only STATS_UNPLUGGED works properly */
2769 public long getMobileTcpBytesReceived(int which) {
2770 return getTcpBytes(NetStat.getMobileRxBytes(), mMobileDataRx, which);
2771 }
2772
2773 /** Only STATS_UNPLUGGED works properly */
2774 public long getTotalTcpBytesSent(int which) {
2775 return getTcpBytes(NetStat.getTotalTxBytes(), mTotalDataTx, which);
2776 }
2777
2778 /** Only STATS_UNPLUGGED works properly */
2779 public long getTotalTcpBytesReceived(int which) {
2780 return getTcpBytes(NetStat.getTotalRxBytes(), mTotalDataRx, which);
2781 }
2782
The Android Open Source Project10592532009-03-18 17:39:46 -07002783 @Override
Evan Millar633a1742009-04-02 16:36:33 -07002784 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002785 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07002786 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002787 }
2788 }
2789
Evan Millar633a1742009-04-02 16:36:33 -07002790 public int getDischargeStartLevelLocked() {
2791 return mDischargeStartLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07002792 }
2793
2794 @Override
Evan Millar633a1742009-04-02 16:36:33 -07002795 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002796 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07002797 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002798 }
2799 }
2800
Evan Millar633a1742009-04-02 16:36:33 -07002801 public int getDischargeCurrentLevelLocked() {
2802 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07002803 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002804
2805 /**
2806 * Retrieve the statistics object for a particular uid, creating if needed.
2807 */
2808 public Uid getUidStatsLocked(int uid) {
2809 Uid u = mUidStats.get(uid);
2810 if (u == null) {
2811 u = new Uid(uid);
2812 mUidStats.put(uid, u);
2813 }
2814 return u;
2815 }
2816
2817 /**
2818 * Remove the statistics object for a particular uid.
2819 */
2820 public void removeUidStatsLocked(int uid) {
2821 mUidStats.remove(uid);
2822 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002823
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002824 /**
2825 * Retrieve the statistics object for a particular process, creating
2826 * if needed.
2827 */
2828 public Uid.Proc getProcessStatsLocked(int uid, String name) {
2829 Uid u = getUidStatsLocked(uid);
2830 return u.getProcessStatsLocked(name);
2831 }
2832
2833 /**
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002834 * Retrieve the statistics object for a particular process, given
2835 * the name of the process.
2836 * @param name process name
2837 * @return the statistics object for the process
2838 */
2839 public Uid.Proc getProcessStatsLocked(String name) {
2840 int uid;
2841 if (mUidCache.containsKey(name)) {
2842 uid = mUidCache.get(name);
2843 } else {
2844 // TODO: Find the actual uid from /proc/pid/status. For now use the hashcode of the
2845 // process name
2846 uid = name.hashCode();
2847 mUidCache.put(name, uid);
2848 }
2849 Uid u = getUidStatsLocked(uid);
2850 return u.getProcessStatsLocked(name);
2851 }
2852
2853 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002854 * Retrieve the statistics object for a particular process, creating
2855 * if needed.
2856 */
2857 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
2858 Uid u = getUidStatsLocked(uid);
2859 return u.getPackageStatsLocked(pkg);
2860 }
2861
2862 /**
2863 * Retrieve the statistics object for a particular service, creating
2864 * if needed.
2865 */
2866 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
2867 Uid u = getUidStatsLocked(uid);
2868 return u.getServiceStatsLocked(pkg, name);
2869 }
2870
2871 public void writeLocked() {
2872 if ((mFile == null) || (mBackupFile == null)) {
2873 Log.w("BatteryStats", "writeLocked: no file associated with this instance");
2874 return;
2875 }
2876
2877 // Keep the old file around until we know the new one has
2878 // been successfully written.
2879 if (mFile.exists()) {
2880 if (mBackupFile.exists()) {
2881 mBackupFile.delete();
2882 }
2883 mFile.renameTo(mBackupFile);
2884 }
2885
2886 try {
2887 FileOutputStream stream = new FileOutputStream(mFile);
2888 Parcel out = Parcel.obtain();
2889 writeSummaryToParcel(out);
2890 stream.write(out.marshall());
2891 out.recycle();
2892
2893 stream.flush();
2894 stream.close();
2895 mBackupFile.delete();
2896
2897 mLastWriteTime = SystemClock.elapsedRealtime();
2898 } catch (IOException e) {
2899 Log.e("BatteryStats", "Error writing battery statistics", e);
2900 }
2901 }
2902
2903 static byte[] readFully(FileInputStream stream) throws java.io.IOException {
2904 int pos = 0;
2905 int avail = stream.available();
2906 byte[] data = new byte[avail];
2907 while (true) {
2908 int amt = stream.read(data, pos, data.length-pos);
2909 //Log.i("foo", "Read " + amt + " bytes at " + pos
2910 // + " of avail " + data.length);
2911 if (amt <= 0) {
2912 //Log.i("foo", "**** FINISHED READING: pos=" + pos
2913 // + " len=" + data.length);
2914 return data;
2915 }
2916 pos += amt;
2917 avail = stream.available();
2918 if (avail > data.length-pos) {
2919 byte[] newData = new byte[pos+avail];
2920 System.arraycopy(data, 0, newData, 0, pos);
2921 data = newData;
2922 }
2923 }
2924 }
2925
2926 public void readLocked() {
2927 if ((mFile == null) || (mBackupFile == null)) {
2928 Log.w("BatteryStats", "readLocked: no file associated with this instance");
2929 return;
2930 }
2931
2932 mUidStats.clear();
2933
2934 FileInputStream stream = null;
2935 if (mBackupFile.exists()) {
2936 try {
2937 stream = new FileInputStream(mBackupFile);
2938 } catch (java.io.IOException e) {
2939 // We'll try for the normal settings file.
2940 }
2941 }
2942
2943 try {
2944 if (stream == null) {
2945 if (!mFile.exists()) {
2946 return;
2947 }
2948 stream = new FileInputStream(mFile);
2949 }
2950
2951 byte[] raw = readFully(stream);
2952 Parcel in = Parcel.obtain();
2953 in.unmarshall(raw, 0, raw.length);
2954 in.setDataPosition(0);
2955 stream.close();
2956
2957 readSummaryFromParcel(in);
2958 } catch(java.io.IOException e) {
2959 Log.e("BatteryStats", "Error reading battery statistics", e);
2960 }
2961 }
2962
2963 public int describeContents() {
2964 return 0;
2965 }
2966
2967 private void readSummaryFromParcel(Parcel in) {
2968 final int version = in.readInt();
2969 if (version != VERSION) {
2970 Log.w("BatteryStats", "readFromParcel: version got " + version
2971 + ", expected " + VERSION + "; erasing old stats");
2972 return;
2973 }
2974
2975 mStartCount = in.readInt();
2976 mBatteryUptime = in.readLong();
2977 mBatteryLastUptime = in.readLong();
2978 mBatteryRealtime = in.readLong();
2979 mBatteryLastRealtime = in.readLong();
2980 mUptime = in.readLong();
2981 mLastUptime = in.readLong();
2982 mRealtime = in.readLong();
2983 mLastRealtime = in.readLong();
Evan Millar633a1742009-04-02 16:36:33 -07002984 mDischargeStartLevel = in.readInt();
2985 mDischargeCurrentLevel = in.readInt();
The Android Open Source Project10592532009-03-18 17:39:46 -07002986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002987 mStartCount++;
2988
2989 mScreenOn = false;
2990 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002991 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
2992 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
2993 }
2994 mInputEventCounter.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002995 mPhoneOn = false;
2996 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002997 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
2998 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
2999 }
3000 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
3001 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
3002 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003003 mWifiOn = false;
3004 mWifiOnTimer.readSummaryFromParcelLocked(in);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003005 mWifiRunning = false;
3006 mWifiRunningTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07003007 mBluetoothOn = false;
3008 mBluetoothOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003009
Evan Millarc64edde2009-04-18 12:26:32 -07003010 int NKW = in.readInt();
3011 for (int ikw = 0; ikw < NKW; ikw++) {
3012 if (in.readInt() != 0) {
3013 String kwltName = in.readString();
3014 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
3015 }
3016 }
3017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003018 final int NU = in.readInt();
3019 for (int iu = 0; iu < NU; iu++) {
3020 int uid = in.readInt();
3021 Uid u = new Uid(uid);
3022 mUidStats.put(uid, u);
3023
Dianne Hackborn617f8772009-03-31 15:04:46 -07003024 u.mWifiTurnedOn = false;
3025 u.mWifiTurnedOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07003026 u.mFullWifiLockOut = false;
3027 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003028 u.mAudioTurnedOn = false;
3029 u.mAudioTurnedOnTimer.readSummaryFromParcelLocked(in);
3030 u.mVideoTurnedOn = false;
3031 u.mVideoTurnedOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07003032 u.mScanWifiLockOut = false;
3033 u.mScanWifiLockTimer.readSummaryFromParcelLocked(in);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003034 u.mWifiMulticastEnabled = false;
3035 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
3036
Dianne Hackborn617f8772009-03-31 15:04:46 -07003037 if (in.readInt() != 0) {
3038 if (u.mUserActivityCounters == null) {
3039 u.initUserActivityLocked();
3040 }
3041 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
3042 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
3043 }
3044 }
3045
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003046 int NW = in.readInt();
3047 for (int iw = 0; iw < NW; iw++) {
3048 String wlName = in.readString();
3049 if (in.readInt() != 0) {
3050 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
3051 }
3052 if (in.readInt() != 0) {
3053 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
3054 }
3055 if (in.readInt() != 0) {
3056 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
3057 }
3058 }
3059
3060 int NP = in.readInt();
3061 for (int is = 0; is < NP; is++) {
3062 int seNumber = in.readInt();
3063 if (in.readInt() != 0) {
3064 u.getSensorTimerLocked(seNumber, true)
3065 .readSummaryFromParcelLocked(in);
3066 }
3067 }
3068
3069 NP = in.readInt();
3070 for (int ip = 0; ip < NP; ip++) {
3071 String procName = in.readString();
3072 Uid.Proc p = u.getProcessStatsLocked(procName);
3073 p.mUserTime = p.mLoadedUserTime = in.readLong();
3074 p.mLastUserTime = in.readLong();
3075 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
3076 p.mLastSystemTime = in.readLong();
3077 p.mStarts = p.mLoadedStarts = in.readInt();
3078 p.mLastStarts = in.readInt();
3079 }
3080
3081 NP = in.readInt();
3082 for (int ip = 0; ip < NP; ip++) {
3083 String pkgName = in.readString();
3084 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
3085 p.mWakeups = p.mLoadedWakeups = in.readInt();
3086 p.mLastWakeups = in.readInt();
3087 final int NS = in.readInt();
3088 for (int is = 0; is < NS; is++) {
3089 String servName = in.readString();
3090 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
3091 s.mStartTime = s.mLoadedStartTime = in.readLong();
3092 s.mLastStartTime = in.readLong();
3093 s.mStarts = s.mLoadedStarts = in.readInt();
3094 s.mLastStarts = in.readInt();
3095 s.mLaunches = s.mLoadedLaunches = in.readInt();
3096 s.mLastLaunches = in.readInt();
3097 }
3098 }
3099
3100 u.mLoadedTcpBytesReceived = in.readLong();
3101 u.mLoadedTcpBytesSent = in.readLong();
3102 }
3103 }
3104
3105 /**
3106 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
3107 * disk. This format does not allow a lossless round-trip.
3108 *
3109 * @param out the Parcel to be written to.
3110 */
3111 public void writeSummaryToParcel(Parcel out) {
3112 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
3113 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
3114 final long NOW = getBatteryUptimeLocked(NOW_SYS);
3115 final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS);
3116
3117 out.writeInt(VERSION);
3118
3119 out.writeInt(mStartCount);
3120 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_TOTAL));
3121 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_CURRENT));
3122 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_TOTAL));
3123 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_CURRENT));
3124 out.writeLong(computeUptime(NOW_SYS, STATS_TOTAL));
3125 out.writeLong(computeUptime(NOW_SYS, STATS_CURRENT));
3126 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_TOTAL));
3127 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_CURRENT));
Evan Millar633a1742009-04-02 16:36:33 -07003128 out.writeInt(mDischargeStartLevel);
3129 out.writeInt(mDischargeCurrentLevel);
The Android Open Source Project10592532009-03-18 17:39:46 -07003130
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003131
3132 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003133 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
3134 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
3135 }
3136 mInputEventCounter.writeSummaryFromParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003137 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003138 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
3139 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
3140 }
3141 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
3142 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
3143 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003144 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003145 mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07003146 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003147
Evan Millarc64edde2009-04-18 12:26:32 -07003148 out.writeInt(mKernelWakelockStats.size());
3149 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
3150 Timer kwlt = ent.getValue();
3151 if (kwlt != null) {
3152 out.writeInt(1);
3153 out.writeString(ent.getKey());
3154 ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL);
3155 } else {
3156 out.writeInt(0);
3157 }
3158 }
3159
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003160 final int NU = mUidStats.size();
3161 out.writeInt(NU);
3162 for (int iu = 0; iu < NU; iu++) {
3163 out.writeInt(mUidStats.keyAt(iu));
3164 Uid u = mUidStats.valueAt(iu);
The Android Open Source Project10592532009-03-18 17:39:46 -07003165
Dianne Hackborn617f8772009-03-31 15:04:46 -07003166 u.mWifiTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07003167 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Amith Yamasanic33fe6c2009-05-27 15:29:04 -07003168 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
3169 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07003170 u.mScanWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003171 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003172
Dianne Hackborn617f8772009-03-31 15:04:46 -07003173 if (u.mUserActivityCounters == null) {
3174 out.writeInt(0);
3175 } else {
3176 out.writeInt(1);
3177 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
3178 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
3179 }
3180 }
3181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003182 int NW = u.mWakelockStats.size();
3183 out.writeInt(NW);
3184 if (NW > 0) {
3185 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent
3186 : u.mWakelockStats.entrySet()) {
3187 out.writeString(ent.getKey());
3188 Uid.Wakelock wl = ent.getValue();
3189 if (wl.mTimerFull != null) {
3190 out.writeInt(1);
3191 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL);
3192 } else {
3193 out.writeInt(0);
3194 }
3195 if (wl.mTimerPartial != null) {
3196 out.writeInt(1);
3197 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL);
3198 } else {
3199 out.writeInt(0);
3200 }
3201 if (wl.mTimerWindow != null) {
3202 out.writeInt(1);
3203 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL);
3204 } else {
3205 out.writeInt(0);
3206 }
3207 }
3208 }
3209
3210 int NSE = u.mSensorStats.size();
3211 out.writeInt(NSE);
3212 if (NSE > 0) {
3213 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent
3214 : u.mSensorStats.entrySet()) {
3215 out.writeInt(ent.getKey());
3216 Uid.Sensor se = ent.getValue();
3217 if (se.mTimer != null) {
3218 out.writeInt(1);
3219 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL);
3220 } else {
3221 out.writeInt(0);
3222 }
3223 }
3224 }
3225
3226 int NP = u.mProcessStats.size();
3227 out.writeInt(NP);
3228 if (NP > 0) {
3229 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent
3230 : u.mProcessStats.entrySet()) {
3231 out.writeString(ent.getKey());
3232 Uid.Proc ps = ent.getValue();
3233 out.writeLong(ps.mUserTime);
3234 out.writeLong(ps.mUserTime - ps.mLoadedUserTime);
3235 out.writeLong(ps.mSystemTime);
3236 out.writeLong(ps.mSystemTime - ps.mLoadedSystemTime);
3237 out.writeInt(ps.mStarts);
3238 out.writeInt(ps.mStarts - ps.mLoadedStarts);
3239 }
3240 }
3241
3242 NP = u.mPackageStats.size();
3243 out.writeInt(NP);
3244 if (NP > 0) {
3245 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
3246 : u.mPackageStats.entrySet()) {
3247 out.writeString(ent.getKey());
3248 Uid.Pkg ps = ent.getValue();
3249 out.writeInt(ps.mWakeups);
3250 out.writeInt(ps.mWakeups - ps.mLoadedWakeups);
3251 final int NS = ps.mServiceStats.size();
3252 out.writeInt(NS);
3253 if (NS > 0) {
3254 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
3255 : ps.mServiceStats.entrySet()) {
3256 out.writeString(sent.getKey());
3257 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
3258 long time = ss.getStartTimeToNowLocked(NOW);
3259 out.writeLong(time);
3260 out.writeLong(time - ss.mLoadedStartTime);
3261 out.writeInt(ss.mStarts);
3262 out.writeInt(ss.mStarts - ss.mLoadedStarts);
3263 out.writeInt(ss.mLaunches);
3264 out.writeInt(ss.mLaunches - ss.mLoadedLaunches);
3265 }
3266 }
3267 }
3268 }
3269
3270 out.writeLong(u.getTcpBytesReceived(STATS_TOTAL));
3271 out.writeLong(u.getTcpBytesSent(STATS_TOTAL));
3272 }
3273 }
3274
3275 public void readFromParcel(Parcel in) {
3276 readFromParcelLocked(in);
3277 }
3278
3279 void readFromParcelLocked(Parcel in) {
3280 int magic = in.readInt();
3281 if (magic != MAGIC) {
3282 throw new ParcelFormatException("Bad magic number");
3283 }
3284
3285 mStartCount = in.readInt();
3286 mBatteryUptime = in.readLong();
3287 mBatteryLastUptime = in.readLong();
3288 mBatteryRealtime = in.readLong();
3289 mBatteryLastRealtime = in.readLong();
3290 mScreenOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003291 mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003292 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07003293 mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003294 }
3295 mInputEventCounter = new Counter(mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003296 mPhoneOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003297 mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003298 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07003299 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003300 }
3301 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07003302 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003303 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003304 mWifiOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003305 mWifiOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003306 mWifiRunning = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003307 mWifiRunningTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07003308 mBluetoothOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003309 mBluetoothOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003310 mUptime = in.readLong();
3311 mUptimeStart = in.readLong();
3312 mLastUptime = in.readLong();
3313 mRealtime = in.readLong();
3314 mRealtimeStart = in.readLong();
3315 mLastRealtime = in.readLong();
3316 mOnBattery = in.readInt() != 0;
3317 mOnBatteryInternal = false; // we are no longer really running.
3318 mTrackBatteryPastUptime = in.readLong();
3319 mTrackBatteryUptimeStart = in.readLong();
3320 mTrackBatteryPastRealtime = in.readLong();
3321 mTrackBatteryRealtimeStart = in.readLong();
3322 mUnpluggedBatteryUptime = in.readLong();
3323 mUnpluggedBatteryRealtime = in.readLong();
Evan Millar633a1742009-04-02 16:36:33 -07003324 mDischargeStartLevel = in.readInt();
3325 mDischargeCurrentLevel = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003326 mLastWriteTime = in.readLong();
3327
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003328 mMobileDataRx[STATS_LAST] = in.readLong();
3329 mMobileDataRx[STATS_UNPLUGGED] = -1;
3330 mMobileDataTx[STATS_LAST] = in.readLong();
3331 mMobileDataTx[STATS_UNPLUGGED] = -1;
3332 mTotalDataRx[STATS_LAST] = in.readLong();
3333 mTotalDataRx[STATS_UNPLUGGED] = -1;
3334 mTotalDataTx[STATS_LAST] = in.readLong();
3335 mTotalDataTx[STATS_UNPLUGGED] = -1;
3336
3337 mRadioDataUptime = in.readLong();
3338 mRadioDataStart = -1;
3339
Evan Millarc64edde2009-04-18 12:26:32 -07003340 mKernelWakelockStats.clear();
3341 int NKW = in.readInt();
3342 for (int ikw = 0; ikw < NKW; ikw++) {
3343 if (in.readInt() != 0) {
3344 String wakelockName = in.readString();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003345 in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel
Evan Millarc64edde2009-04-18 12:26:32 -07003346 SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in);
3347 mKernelWakelockStats.put(wakelockName, kwlt);
3348 }
3349 }
3350
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003351 mPartialTimers.clear();
3352 mFullTimers.clear();
3353 mWindowTimers.clear();
3354
3355 int numUids = in.readInt();
3356 mUidStats.clear();
3357 for (int i = 0; i < numUids; i++) {
3358 int uid = in.readInt();
3359 Uid u = new Uid(uid);
3360 u.readFromParcelLocked(mUnpluggables, in);
3361 mUidStats.append(uid, u);
3362 }
3363 }
3364
3365 public void writeToParcel(Parcel out, int flags) {
3366 writeToParcelLocked(out, flags);
3367 }
3368
3369 @SuppressWarnings("unused")
3370 void writeToParcelLocked(Parcel out, int flags) {
3371 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
3372 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
3373 final long batteryUptime = getBatteryUptimeLocked(uSecUptime);
3374 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
3375
3376 out.writeInt(MAGIC);
3377 out.writeInt(mStartCount);
3378 out.writeLong(mBatteryUptime);
3379 out.writeLong(mBatteryLastUptime);
3380 out.writeLong(mBatteryRealtime);
3381 out.writeLong(mBatteryLastRealtime);
3382 mScreenOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003383 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
3384 mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime);
3385 }
3386 mInputEventCounter.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003387 mPhoneOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003388 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
3389 mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
3390 }
3391 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
3392 mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime);
3393 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003394 mWifiOnTimer.writeToParcel(out, batteryRealtime);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003395 mWifiRunningTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003396 mBluetoothOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003397 out.writeLong(mUptime);
3398 out.writeLong(mUptimeStart);
3399 out.writeLong(mLastUptime);
3400 out.writeLong(mRealtime);
3401 out.writeLong(mRealtimeStart);
3402 out.writeLong(mLastRealtime);
3403 out.writeInt(mOnBattery ? 1 : 0);
3404 out.writeLong(batteryUptime);
3405 out.writeLong(mTrackBatteryUptimeStart);
3406 out.writeLong(batteryRealtime);
3407 out.writeLong(mTrackBatteryRealtimeStart);
3408 out.writeLong(mUnpluggedBatteryUptime);
3409 out.writeLong(mUnpluggedBatteryRealtime);
Evan Millar633a1742009-04-02 16:36:33 -07003410 out.writeInt(mDischargeStartLevel);
3411 out.writeInt(mDischargeCurrentLevel);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003412 out.writeLong(mLastWriteTime);
3413
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003414 out.writeLong(getMobileTcpBytesReceived(STATS_UNPLUGGED));
3415 out.writeLong(getMobileTcpBytesSent(STATS_UNPLUGGED));
3416 out.writeLong(getTotalTcpBytesReceived(STATS_UNPLUGGED));
3417 out.writeLong(getTotalTcpBytesSent(STATS_UNPLUGGED));
3418
3419 // Write radio uptime for data
3420 out.writeLong(getRadioDataUptimeMs());
3421
Evan Millarc64edde2009-04-18 12:26:32 -07003422 out.writeInt(mKernelWakelockStats.size());
3423 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
3424 SamplingTimer kwlt = ent.getValue();
3425 if (kwlt != null) {
3426 out.writeInt(1);
3427 out.writeString(ent.getKey());
3428 Timer.writeTimerToParcel(out, kwlt, batteryRealtime);
3429 } else {
3430 out.writeInt(0);
3431 }
3432 }
3433
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003434 int size = mUidStats.size();
3435 out.writeInt(size);
3436 for (int i = 0; i < size; i++) {
3437 out.writeInt(mUidStats.keyAt(i));
3438 Uid uid = mUidStats.valueAt(i);
3439
3440 uid.writeToParcelLocked(out, batteryRealtime);
3441 }
3442 }
3443
3444 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
3445 new Parcelable.Creator<BatteryStatsImpl>() {
3446 public BatteryStatsImpl createFromParcel(Parcel in) {
3447 return new BatteryStatsImpl(in);
3448 }
3449
3450 public BatteryStatsImpl[] newArray(int size) {
3451 return new BatteryStatsImpl[size];
3452 }
3453 };
3454
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003455 public void dumpLocked(PrintWriter pw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003456 if (DEBUG) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003457 Printer pr = new PrintWriterPrinter(pw);
3458 pr.println("*** Screen timer:");
3459 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07003460 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003461 pr.println("*** Screen brightness #" + i + ":");
3462 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07003463 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003464 pr.println("*** Input event counter:");
3465 mInputEventCounter.logState(pr, " ");
3466 pr.println("*** Phone timer:");
3467 mPhoneOnTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07003468 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003469 pr.println("*** Signal strength #" + i + ":");
3470 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07003471 }
3472 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003473 pr.println("*** Data connection type #" + i + ":");
3474 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07003475 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003476 pr.println("*** Wifi timer:");
3477 mWifiOnTimer.logState(pr, " ");
3478 pr.println("*** WifiRunning timer:");
3479 mWifiRunningTimer.logState(pr, " ");
3480 pr.println("*** Bluetooth timer:");
3481 mBluetoothOnTimer.logState(pr, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003482 }
3483 super.dumpLocked(pw);
3484 }
3485}