blob: 8698cb7c818b8e453b5010ccb817ab7660a2281a [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.os;
18
Amith Yamasani3f7e35c2009-07-13 16:02:45 -070019import android.bluetooth.BluetoothHeadset;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import android.os.BatteryStats;
21import android.os.NetStat;
22import android.os.Parcel;
23import android.os.ParcelFormatException;
24import android.os.Parcelable;
Evan Millarc64edde2009-04-18 12:26:32 -070025import android.os.Process;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import android.os.SystemClock;
Amith Yamasanif37447b2009-10-08 18:28:01 -070027import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070028import android.telephony.SignalStrength;
Dianne Hackborn627bba72009-03-24 22:32:56 -070029import android.telephony.TelephonyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.util.Log;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070031import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.util.Printer;
33import android.util.SparseArray;
34
Amith Yamasani3718aaa2009-06-09 06:32:35 -070035import java.io.BufferedReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import java.io.File;
37import java.io.FileInputStream;
38import java.io.FileOutputStream;
Amith Yamasani3718aaa2009-06-09 06:32:35 -070039import java.io.FileReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070041import java.io.PrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import java.util.ArrayList;
43import java.util.HashMap;
Evan Millarc64edde2009-04-18 12:26:32 -070044import java.util.Iterator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import java.util.Map;
46
47/**
48 * All information we are collecting about things that can happen that impact
49 * battery life. All times are represented in microseconds except where indicated
50 * otherwise.
51 */
52public final class BatteryStatsImpl extends BatteryStats {
53 private static final String TAG = "BatteryStatsImpl";
54 private static final boolean DEBUG = false;
55
56 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
57 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
58
59 // Current on-disk Parcel version
Amith Yamasanif37447b2009-10-08 18:28:01 -070060 private static final int VERSION = 41;
Amith Yamasanie43530a2009-08-21 13:11:37 -070061
62 private static int sNumSpeedSteps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063
64 private final File mFile;
65 private final File mBackupFile;
66
67 /**
68 * The statistics we have collected organized by uids.
69 */
70 final SparseArray<BatteryStatsImpl.Uid> mUidStats =
71 new SparseArray<BatteryStatsImpl.Uid>();
72
73 // A set of pools of currently active timers. When a timer is queried, we will divide the
74 // elapsed time by the number of active timers to arrive at that timer's share of the time.
75 // In order to do this, we must refresh each timer whenever the number of active timers
76 // changes.
Evan Millarc64edde2009-04-18 12:26:32 -070077 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>();
78 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>();
79 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>();
80 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers
81 = new SparseArray<ArrayList<StopwatchTimer>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082
83 // These are the objects that will want to do something when the device
84 // is unplugged from power.
85 final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>();
86
87 int mStartCount;
88
89 long mBatteryUptime;
90 long mBatteryLastUptime;
91 long mBatteryRealtime;
92 long mBatteryLastRealtime;
93
94 long mUptime;
95 long mUptimeStart;
96 long mLastUptime;
97 long mRealtime;
98 long mRealtimeStart;
99 long mLastRealtime;
100
101 boolean mScreenOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700102 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700103
Dianne Hackborn617f8772009-03-31 15:04:46 -0700104 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700105 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Dianne Hackborn617f8772009-03-31 15:04:46 -0700106
107 Counter mInputEventCounter;
108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700110 StopwatchTimer mPhoneOnTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700112 boolean mAudioOn;
113 StopwatchTimer mAudioOnTimer;
114
115 boolean mVideoOn;
116 StopwatchTimer mVideoOnTimer;
117
Dianne Hackborn627bba72009-03-24 22:32:56 -0700118 int mPhoneSignalStrengthBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700119 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
120 new StopwatchTimer[NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700121
122 StopwatchTimer mPhoneSignalScanningTimer;
123
Dianne Hackborn627bba72009-03-24 22:32:56 -0700124 int mPhoneDataConnectionType = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700125 final StopwatchTimer[] mPhoneDataConnectionsTimer =
126 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Dianne Hackborn627bba72009-03-24 22:32:56 -0700127
The Android Open Source Project10592532009-03-18 17:39:46 -0700128 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700129 StopwatchTimer mWifiOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700130 int mWifiOnUid = -1;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700131
132 boolean mWifiRunning;
Evan Millarc64edde2009-04-18 12:26:32 -0700133 StopwatchTimer mWifiRunningTimer;
The Android Open Source Project10592532009-03-18 17:39:46 -0700134
135 boolean mBluetoothOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700136 StopwatchTimer mBluetoothOnTimer;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700137
138 /** Bluetooth headset object */
139 BluetoothHeadset mBtHeadset;
140
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141 /**
142 * These provide time bases that discount the time the device is plugged
143 * in to power.
144 */
145 boolean mOnBattery;
146 boolean mOnBatteryInternal;
147 long mTrackBatteryPastUptime;
148 long mTrackBatteryUptimeStart;
149 long mTrackBatteryPastRealtime;
150 long mTrackBatteryRealtimeStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 long mUnpluggedBatteryUptime;
153 long mUnpluggedBatteryRealtime;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700154
The Android Open Source Project10592532009-03-18 17:39:46 -0700155 /*
156 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
157 */
Evan Millar633a1742009-04-02 16:36:33 -0700158 int mDischargeStartLevel;
159 int mDischargeCurrentLevel;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700162
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700163 // Mobile data transferred while on battery
164 private long[] mMobileDataTx = new long[4];
165 private long[] mMobileDataRx = new long[4];
166 private long[] mTotalDataTx = new long[4];
167 private long[] mTotalDataRx = new long[4];
168
169 private long mRadioDataUptime;
170 private long mRadioDataStart;
171
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700172 private int mBluetoothPingCount;
173 private int mBluetoothPingStart = -1;
174
Amith Yamasanif37447b2009-10-08 18:28:01 -0700175 private int mPhoneServiceState = -1;
176
Evan Millarc64edde2009-04-18 12:26:32 -0700177 /*
178 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
179 */
180 private final HashMap<String, SamplingTimer> mKernelWakelockStats =
181 new HashMap<String, SamplingTimer>();
182
183 public Map<String, ? extends SamplingTimer> getKernelWakelockStats() {
184 return mKernelWakelockStats;
185 }
186
187 private static int sKernelWakelockUpdateVersion = 0;
188
189 private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
190 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name
191 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count
192 Process.PROC_TAB_TERM,
193 Process.PROC_TAB_TERM,
194 Process.PROC_TAB_TERM,
195 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime
196 };
197
198 private final String[] mProcWakelocksName = new String[3];
199 private final long[] mProcWakelocksData = new long[3];
200
201 /*
202 * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added
203 * to mKernelWakelockStats.
204 */
205 private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
206 new HashMap<String, KernelWakelockStats>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700208 private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>();
209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210 // For debugging
211 public BatteryStatsImpl() {
212 mFile = mBackupFile = null;
213 }
214
215 public static interface Unpluggable {
216 void unplug(long batteryUptime, long batteryRealtime);
217 void plug(long batteryUptime, long batteryRealtime);
218 }
219
220 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700221 * State for keeping track of counting information.
222 */
Amith Yamasanie43530a2009-08-21 13:11:37 -0700223 public static class Counter extends BatteryStats.Counter implements Unpluggable {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700224 int mCount;
225 int mLoadedCount;
226 int mLastCount;
227 int mUnpluggedCount;
228 int mPluggedCount;
229
230 Counter(ArrayList<Unpluggable> unpluggables, Parcel in) {
231 mPluggedCount = mCount = in.readInt();
232 mLoadedCount = in.readInt();
233 mLastCount = in.readInt();
234 mUnpluggedCount = in.readInt();
235 unpluggables.add(this);
236 }
237
238 Counter(ArrayList<Unpluggable> unpluggables) {
239 unpluggables.add(this);
240 }
241
242 public void writeToParcel(Parcel out) {
243 out.writeInt(mCount);
244 out.writeInt(mLoadedCount);
245 out.writeInt(mLastCount);
246 out.writeInt(mUnpluggedCount);
247 }
248
249 public void unplug(long batteryUptime, long batteryRealtime) {
250 mUnpluggedCount = mCount = mPluggedCount;
251 }
252
253 public void plug(long batteryUptime, long batteryRealtime) {
254 mPluggedCount = mCount;
255 }
256
257 /**
258 * Writes a possibly null Counter to a Parcel.
259 *
260 * @param out the Parcel to be written to.
261 * @param counter a Counter, or null.
262 */
263 public static void writeCounterToParcel(Parcel out, Counter counter) {
264 if (counter == null) {
265 out.writeInt(0); // indicates null
266 return;
267 }
268 out.writeInt(1); // indicates non-null
269
270 counter.writeToParcel(out);
271 }
272
273 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700274 public int getCountLocked(int which) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700275 int val;
276 if (which == STATS_LAST) {
277 val = mLastCount;
278 } else {
279 val = mCount;
280 if (which == STATS_UNPLUGGED) {
281 val -= mUnpluggedCount;
282 } else if (which != STATS_TOTAL) {
283 val -= mLoadedCount;
284 }
285 }
286
287 return val;
288 }
289
290 public void logState(Printer pw, String prefix) {
291 pw.println(prefix + "mCount=" + mCount
292 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
293 + " mUnpluggedCount=" + mUnpluggedCount
294 + " mPluggedCount=" + mPluggedCount);
295 }
296
297 void stepLocked() {
298 mCount++;
299 }
300
301 void writeSummaryFromParcelLocked(Parcel out) {
302 out.writeInt(mCount);
303 out.writeInt(mCount - mLoadedCount);
304 }
305
306 void readSummaryFromParcelLocked(Parcel in) {
307 mCount = mLoadedCount = in.readInt();
308 mLastCount = in.readInt();
309 mUnpluggedCount = mPluggedCount = mCount;
310 }
311 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700312
313 public static class SamplingCounter extends Counter {
314
315 SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
316 super(unpluggables, in);
317 }
318
319 SamplingCounter(ArrayList<Unpluggable> unpluggables) {
320 super(unpluggables);
321 }
322
323 public void addCountLocked(long count) {
324 mCount += count;
325 }
326 }
327
Dianne Hackborn617f8772009-03-31 15:04:46 -0700328 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 * State for keeping track of timing information.
330 */
Evan Millarc64edde2009-04-18 12:26:32 -0700331 public static abstract class Timer extends BatteryStats.Timer implements Unpluggable {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332 final int mType;
Evan Millarc64edde2009-04-18 12:26:32 -0700333
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334
335 int mCount;
336 int mLoadedCount;
337 int mLastCount;
338 int mUnpluggedCount;
339
340 // Times are in microseconds for better accuracy when dividing by the
341 // lock count, and are in "battery realtime" units.
342
343 /**
344 * The total time we have accumulated since the start of the original
345 * boot, to the last time something interesting happened in the
346 * current run.
347 */
348 long mTotalTime;
349
350 /**
351 * The total time we loaded for the previous runs. Subtract this from
352 * mTotalTime to find the time for the current run of the system.
353 */
354 long mLoadedTime;
355
356 /**
357 * The run time of the last run of the system, as loaded from the
358 * saved data.
359 */
360 long mLastTime;
361
362 /**
363 * The value of mTotalTime when unplug() was last called. Subtract
364 * this from mTotalTime to find the time since the last unplug from
365 * power.
366 */
367 long mUnpluggedTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700369 /**
370 * Constructs from a parcel.
371 * @param type
372 * @param unpluggables
373 * @param powerType
374 * @param in
375 */
Evan Millarc64edde2009-04-18 12:26:32 -0700376 Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 mType = type;
Evan Millarc64edde2009-04-18 12:26:32 -0700378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800379 mCount = in.readInt();
380 mLoadedCount = in.readInt();
381 mLastCount = in.readInt();
382 mUnpluggedCount = in.readInt();
383 mTotalTime = in.readLong();
384 mLoadedTime = in.readLong();
385 mLastTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 mUnpluggedTime = in.readLong();
387 unpluggables.add(this);
388 }
389
Evan Millarc64edde2009-04-18 12:26:32 -0700390 Timer(int type, ArrayList<Unpluggable> unpluggables) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391 mType = type;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 unpluggables.add(this);
393 }
Evan Millarc64edde2009-04-18 12:26:32 -0700394
395 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
396
397 protected abstract int computeCurrentCountLocked();
398
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399
400 public void writeToParcel(Parcel out, long batteryRealtime) {
401 out.writeInt(mCount);
402 out.writeInt(mLoadedCount);
403 out.writeInt(mLastCount);
404 out.writeInt(mUnpluggedCount);
405 out.writeLong(computeRunTimeLocked(batteryRealtime));
406 out.writeLong(mLoadedTime);
407 out.writeLong(mLastTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 out.writeLong(mUnpluggedTime);
409 }
410
411 public void unplug(long batteryUptime, long batteryRealtime) {
412 if (DEBUG && mType < 0) {
413 Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime
414 + " old mUnpluggedTime=" + mUnpluggedTime
415 + " old mUnpluggedCount=" + mUnpluggedCount);
416 }
417 mUnpluggedTime = computeRunTimeLocked(batteryRealtime);
418 mUnpluggedCount = mCount;
419 if (DEBUG && mType < 0) {
420 Log.v(TAG, "unplug #" + mType
421 + ": new mUnpluggedTime=" + mUnpluggedTime
422 + " new mUnpluggedCount=" + mUnpluggedCount);
423 }
424 }
425
426 public void plug(long batteryUptime, long batteryRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -0700427 if (DEBUG && mType < 0) {
428 Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime
429 + " old mTotalTime=" + mTotalTime);
430 }
431 mTotalTime = computeRunTimeLocked(batteryRealtime);
432 mCount = computeCurrentCountLocked();
433 if (DEBUG && mType < 0) {
434 Log.v(TAG, "plug #" + mType
435 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800436 }
437 }
438
439 /**
440 * Writes a possibly null Timer to a Parcel.
441 *
442 * @param out the Parcel to be written to.
443 * @param timer a Timer, or null.
444 */
445 public static void writeTimerToParcel(Parcel out, Timer timer,
446 long batteryRealtime) {
447 if (timer == null) {
448 out.writeInt(0); // indicates null
449 return;
450 }
451 out.writeInt(1); // indicates non-null
452
453 timer.writeToParcel(out, batteryRealtime);
454 }
455
456 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700457 public long getTotalTimeLocked(long batteryRealtime, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458 long val;
459 if (which == STATS_LAST) {
460 val = mLastTime;
461 } else {
462 val = computeRunTimeLocked(batteryRealtime);
463 if (which == STATS_UNPLUGGED) {
464 val -= mUnpluggedTime;
465 } else if (which != STATS_TOTAL) {
466 val -= mLoadedTime;
467 }
468 }
469
470 return val;
471 }
472
473 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700474 public int getCountLocked(int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800475 int val;
476 if (which == STATS_LAST) {
477 val = mLastCount;
478 } else {
Evan Millarc64edde2009-04-18 12:26:32 -0700479 val = computeCurrentCountLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 if (which == STATS_UNPLUGGED) {
481 val -= mUnpluggedCount;
482 } else if (which != STATS_TOTAL) {
483 val -= mLoadedCount;
484 }
485 }
486
487 return val;
488 }
489
Dianne Hackborn627bba72009-03-24 22:32:56 -0700490 public void logState(Printer pw, String prefix) {
Evan Millarc64edde2009-04-18 12:26:32 -0700491 pw.println(prefix + " mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800492 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
493 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700494 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700496 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800497 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -0700498 }
499
500
501 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
502 long runTime = computeRunTimeLocked(batteryRealtime);
503 // Divide by 1000 for backwards compatibility
504 out.writeLong((runTime + 500) / 1000);
505 out.writeLong(((runTime - mLoadedTime) + 500) / 1000);
506 out.writeInt(mCount);
507 out.writeInt(mCount - mLoadedCount);
508 }
509
510 void readSummaryFromParcelLocked(Parcel in) {
511 // Multiply by 1000 for backwards compatibility
512 mTotalTime = mLoadedTime = in.readLong() * 1000;
513 mLastTime = in.readLong() * 1000;
514 mUnpluggedTime = mTotalTime;
515 mCount = mLoadedCount = in.readInt();
516 mLastCount = in.readInt();
517 mUnpluggedCount = mCount;
518 }
519 }
520
521 public static final class SamplingTimer extends Timer {
522
523 /**
524 * The most recent reported count from /proc/wakelocks.
525 */
526 int mCurrentReportedCount;
527
528 /**
529 * The reported count from /proc/wakelocks when unplug() was last
530 * called.
531 */
532 int mUnpluggedReportedCount;
533
534 /**
535 * The most recent reported total_time from /proc/wakelocks.
536 */
537 long mCurrentReportedTotalTime;
538
539
540 /**
541 * The reported total_time from /proc/wakelocks when unplug() was last
542 * called.
543 */
544 long mUnpluggedReportedTotalTime;
545
546 /**
547 * Whether we are currently in a discharge cycle.
548 */
549 boolean mInDischarge;
550
551 /**
552 * Whether we are currently recording reported values.
553 */
554 boolean mTrackingReportedValues;
555
556 /*
557 * A sequnce counter, incremented once for each update of the stats.
558 */
559 int mUpdateVersion;
560
561 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) {
562 super(0, unpluggables, in);
563 mCurrentReportedCount = in.readInt();
564 mUnpluggedReportedCount = in.readInt();
565 mCurrentReportedTotalTime = in.readLong();
566 mUnpluggedReportedTotalTime = in.readLong();
567 mTrackingReportedValues = in.readInt() == 1;
568 mInDischarge = inDischarge;
569 }
570
571 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge,
572 boolean trackReportedValues) {
573 super(0, unpluggables);
574 mTrackingReportedValues = trackReportedValues;
575 mInDischarge = inDischarge;
576 }
577
578 public void setStale() {
579 mTrackingReportedValues = false;
580 mUnpluggedReportedTotalTime = 0;
581 mUnpluggedReportedCount = 0;
582 }
583
584 public void setUpdateVersion(int version) {
585 mUpdateVersion = version;
586 }
587
588 public int getUpdateVersion() {
589 return mUpdateVersion;
590 }
591
592 public void updateCurrentReportedCount(int count) {
593 if (mInDischarge && mUnpluggedReportedCount == 0) {
594 // Updating the reported value for the first time.
595 mUnpluggedReportedCount = count;
596 // If we are receiving an update update mTrackingReportedValues;
597 mTrackingReportedValues = true;
598 }
599 mCurrentReportedCount = count;
600 }
601
602 public void updateCurrentReportedTotalTime(long totalTime) {
603 if (mInDischarge && mUnpluggedReportedTotalTime == 0) {
604 // Updating the reported value for the first time.
605 mUnpluggedReportedTotalTime = totalTime;
606 // If we are receiving an update update mTrackingReportedValues;
607 mTrackingReportedValues = true;
608 }
609 mCurrentReportedTotalTime = totalTime;
610 }
611
612 public void unplug(long batteryUptime, long batteryRealtime) {
613 super.unplug(batteryUptime, batteryRealtime);
614 if (mTrackingReportedValues) {
615 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
616 mUnpluggedReportedCount = mCurrentReportedCount;
617 }
618 mInDischarge = true;
619 }
620
621 public void plug(long batteryUptime, long batteryRealtime) {
622 super.plug(batteryUptime, batteryRealtime);
623 mInDischarge = false;
624 }
625
626 public void logState(Printer pw, String prefix) {
627 super.logState(pw, prefix);
628 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
629 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
630 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
631 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
632 }
633
634 protected long computeRunTimeLocked(long curBatteryRealtime) {
635 return mTotalTime + (mInDischarge && mTrackingReportedValues
636 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
637 }
638
639 protected int computeCurrentCountLocked() {
640 return mCount + (mInDischarge && mTrackingReportedValues
641 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
642 }
643
644 public void writeToParcel(Parcel out, long batteryRealtime) {
645 super.writeToParcel(out, batteryRealtime);
646 out.writeInt(mCurrentReportedCount);
647 out.writeInt(mUnpluggedReportedCount);
648 out.writeLong(mCurrentReportedTotalTime);
649 out.writeLong(mUnpluggedReportedTotalTime);
650 out.writeInt(mTrackingReportedValues ? 1 : 0);
651 }
652
653 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
654 super.writeSummaryFromParcelLocked(out, batteryRealtime);
655 out.writeLong(mCurrentReportedTotalTime);
656 out.writeInt(mCurrentReportedCount);
657 out.writeInt(mTrackingReportedValues ? 1 : 0);
658 }
659
660 void readSummaryFromParcelLocked(Parcel in) {
661 super.readSummaryFromParcelLocked(in);
662 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
663 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
664 mTrackingReportedValues = in.readInt() == 1;
665 }
666 }
667
668 /**
669 * State for keeping track of timing information.
670 */
671 public static final class StopwatchTimer extends Timer {
672 final ArrayList<StopwatchTimer> mTimerPool;
673 int mNesting;
674
675
676 /**
677 * The last time at which we updated the timer. If mNesting is > 0,
678 * subtract this from the current battery time to find the amount of
679 * time we have been running since we last computed an update.
680 */
681 long mUpdateTime;
682
683 /**
684 * The total time at which the timer was acquired, to determine if
685 * was actually held for an interesting duration.
686 */
687 long mAcquireTime;
Evan Millarc64edde2009-04-18 12:26:32 -0700688
Amith Yamasanif37447b2009-10-08 18:28:01 -0700689 long mTimeout;
690
Evan Millarc64edde2009-04-18 12:26:32 -0700691 StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool,
692 ArrayList<Unpluggable> unpluggables, Parcel in) {
693 super(type, unpluggables, in);
694 mTimerPool = timerPool;
695 mUpdateTime = in.readLong();
696 }
697
698 StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool,
699 ArrayList<Unpluggable> unpluggables) {
700 super(type, unpluggables);
701 mTimerPool = timerPool;
702 }
703
Amith Yamasanif37447b2009-10-08 18:28:01 -0700704 void setTimeout(long timeout) {
705 mTimeout = timeout;
706 }
707
Evan Millarc64edde2009-04-18 12:26:32 -0700708 public void writeToParcel(Parcel out, long batteryRealtime) {
709 super.writeToParcel(out, batteryRealtime);
710 out.writeLong(mUpdateTime);
711 }
712
713 public void plug(long batteryUptime, long batteryRealtime) {
714 if (mNesting > 0) {
715 if (DEBUG && mType < 0) {
716 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
717 }
718 super.plug(batteryUptime, batteryRealtime);
719 mUpdateTime = batteryRealtime;
720 if (DEBUG && mType < 0) {
721 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
722 }
723 }
724 }
725
726 public void logState(Printer pw, String prefix) {
727 super.logState(pw, prefix);
728 pw.println(prefix + "mNesting=" + mNesting + "mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800729 + " mAcquireTime=" + mAcquireTime);
730 }
731
732 void startRunningLocked(BatteryStatsImpl stats) {
733 if (mNesting++ == 0) {
734 mUpdateTime = stats.getBatteryRealtimeLocked(
735 SystemClock.elapsedRealtime() * 1000);
736 if (mTimerPool != null) {
737 // Accumulate time to all currently active timers before adding
738 // this new one to the pool.
739 refreshTimersLocked(stats, mTimerPool);
740 // Add this timer to the active pool
741 mTimerPool.add(this);
742 }
743 // Increment the count
744 mCount++;
745 mAcquireTime = mTotalTime;
746 if (DEBUG && mType < 0) {
747 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
748 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
749 + " mAcquireTime=" + mAcquireTime);
750 }
751 }
752 }
753
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700754 boolean isRunningLocked() {
755 return mNesting > 0;
756 }
757
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800758 void stopRunningLocked(BatteryStatsImpl stats) {
759 // Ignore attempt to stop a timer that isn't running
760 if (mNesting == 0) {
761 return;
762 }
763 if (--mNesting == 0) {
764 if (mTimerPool != null) {
765 // Accumulate time to all active counters, scaled by the total
766 // active in the pool, before taking this one out of the pool.
767 refreshTimersLocked(stats, mTimerPool);
768 // Remove this timer from the active pool
769 mTimerPool.remove(this);
770 } else {
771 final long realtime = SystemClock.elapsedRealtime() * 1000;
772 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
773 mNesting = 1;
774 mTotalTime = computeRunTimeLocked(batteryRealtime);
775 mNesting = 0;
776 }
777
778 if (DEBUG && mType < 0) {
779 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
780 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
781 + " mAcquireTime=" + mAcquireTime);
782 }
783
784 if (mTotalTime == mAcquireTime) {
785 // If there was no change in the time, then discard this
786 // count. A somewhat cheezy strategy, but hey.
787 mCount--;
788 }
789 }
790 }
791
792 // Update the total time for all other running Timers with the same type as this Timer
793 // due to a change in timer count
794 private static void refreshTimersLocked(final BatteryStatsImpl stats,
Evan Millarc64edde2009-04-18 12:26:32 -0700795 final ArrayList<StopwatchTimer> pool) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800796 final long realtime = SystemClock.elapsedRealtime() * 1000;
797 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
798 final int N = pool.size();
799 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -0700800 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801 long heldTime = batteryRealtime - t.mUpdateTime;
802 if (heldTime > 0) {
803 t.mTotalTime += heldTime / N;
804 }
805 t.mUpdateTime = batteryRealtime;
806 }
807 }
808
Evan Millarc64edde2009-04-18 12:26:32 -0700809 @Override
810 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -0700811 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
812 curBatteryRealtime = mUpdateTime + mTimeout;
813 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800814 return mTotalTime + (mNesting > 0
815 ? (curBatteryRealtime - mUpdateTime)
816 / (mTimerPool != null ? mTimerPool.size() : 1)
817 : 0);
818 }
819
Evan Millarc64edde2009-04-18 12:26:32 -0700820 @Override
821 protected int computeCurrentCountLocked() {
822 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800823 }
824
825 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -0700826 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800827 mNesting = 0;
828 }
829 }
830
Evan Millarc64edde2009-04-18 12:26:32 -0700831 private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
832
833 byte[] buffer = new byte[4096];
834 int len;
835
836 try {
837 FileInputStream is = new FileInputStream("/proc/wakelocks");
838 len = is.read(buffer);
839 is.close();
840
841 if (len > 0) {
842 int i;
843 for (i=0; i<len; i++) {
844 if (buffer[i] == '\0') {
845 len = i;
846 break;
847 }
848 }
849 }
850 } catch (java.io.FileNotFoundException e) {
851 return null;
852 } catch (java.io.IOException e) {
853 return null;
854 }
855
856 return parseProcWakelocks(buffer, len);
857 }
858
859 private final Map<String, KernelWakelockStats> parseProcWakelocks(
860 byte[] wlBuffer, int len) {
861 String name;
862 int count;
863 long totalTime;
864 int startIndex, endIndex;
865 int numUpdatedWlNames = 0;
866
867 // Advance past the first line.
868 int i;
869 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++);
870 startIndex = endIndex = i + 1;
871
872 synchronized(this) {
873 Map<String, KernelWakelockStats> m = mProcWakelockFileStats;
874
875 sKernelWakelockUpdateVersion++;
876 while (endIndex < len) {
877 for (endIndex=startIndex;
878 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
879 endIndex++);
880 endIndex++; // endIndex is an exclusive upper bound.
881
882 String[] nameStringArray = mProcWakelocksName;
883 long[] wlData = mProcWakelocksData;
Amith Yamasani53b707b2009-09-30 11:05:30 -0700884 boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex,
885 PROC_WAKELOCKS_FORMAT, nameStringArray, wlData, null);
Evan Millarc64edde2009-04-18 12:26:32 -0700886
887 name = nameStringArray[0];
888 count = (int) wlData[1];
889 // convert nanoseconds to microseconds with rounding.
890 totalTime = (wlData[2] + 500) / 1000;
891
Amith Yamasani53b707b2009-09-30 11:05:30 -0700892 if (parsed && name.length() > 0) {
Evan Millarc64edde2009-04-18 12:26:32 -0700893 if (!m.containsKey(name)) {
894 m.put(name, new KernelWakelockStats(count, totalTime,
895 sKernelWakelockUpdateVersion));
896 numUpdatedWlNames++;
897 } else {
898 KernelWakelockStats kwlStats = m.get(name);
899 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) {
900 kwlStats.mCount += count;
901 kwlStats.mTotalTime += totalTime;
902 } else {
903 kwlStats.mCount = count;
904 kwlStats.mTotalTime = totalTime;
905 kwlStats.mVersion = sKernelWakelockUpdateVersion;
906 numUpdatedWlNames++;
907 }
908 }
Amith Yamasani53b707b2009-09-30 11:05:30 -0700909 }
Evan Millarc64edde2009-04-18 12:26:32 -0700910 startIndex = endIndex;
911 }
912
913 if (m.size() != numUpdatedWlNames) {
914 // Don't report old data.
915 Iterator<KernelWakelockStats> itr = m.values().iterator();
916 while (itr.hasNext()) {
917 if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
918 itr.remove();
919 }
920 }
921 }
922 return m;
923 }
924 }
925
926 private class KernelWakelockStats {
927 public int mCount;
928 public long mTotalTime;
929 public int mVersion;
930
931 KernelWakelockStats(int count, long totalTime, int version) {
932 mCount = count;
933 mTotalTime = totalTime;
934 mVersion = version;
935 }
936 }
937
938 /*
939 * Get the KernelWakelockTimer associated with name, and create a new one if one
940 * doesn't already exist.
941 */
942 public SamplingTimer getKernelWakelockTimerLocked(String name) {
943 SamplingTimer kwlt = mKernelWakelockStats.get(name);
944 if (kwlt == null) {
945 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
946 true /* track reported values */);
947 mKernelWakelockStats.put(name, kwlt);
948 }
949 return kwlt;
950 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700951
952 private void doDataPlug(long[] dataTransfer, long currentBytes) {
953 dataTransfer[STATS_LAST] = dataTransfer[STATS_UNPLUGGED];
954 dataTransfer[STATS_UNPLUGGED] = -1;
955 }
956
957 private void doDataUnplug(long[] dataTransfer, long currentBytes) {
958 dataTransfer[STATS_UNPLUGGED] = currentBytes;
959 }
960
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700961 /**
962 * Radio uptime in microseconds when transferring data. This value is very approximate.
963 * @return
964 */
965 private long getCurrentRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700966 try {
967 File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms");
968 if (!awakeTimeFile.exists()) return 0;
969 BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile));
970 String line = br.readLine();
971 br.close();
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700972 return Long.parseLong(line) * 1000;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700973 } catch (NumberFormatException nfe) {
974 // Nothing
975 } catch (IOException ioe) {
976 // Nothing
977 }
978 return 0;
979 }
980
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700981 /**
982 * @deprecated use getRadioDataUptime
983 */
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700984 public long getRadioDataUptimeMs() {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700985 return getRadioDataUptime() / 1000;
986 }
987
988 /**
989 * Returns the duration that the cell radio was up for data transfers.
990 */
991 public long getRadioDataUptime() {
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700992 if (mRadioDataStart == -1) {
993 return mRadioDataUptime;
994 } else {
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700995 return getCurrentRadioDataUptime() - mRadioDataStart;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700996 }
997 }
998
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700999 private int getCurrentBluetoothPingCount() {
1000 if (mBtHeadset != null) {
1001 return mBtHeadset.getBatteryUsageHint();
1002 }
1003 return -1;
1004 }
1005
1006 public int getBluetoothPingCount() {
1007 if (mBluetoothPingStart == -1) {
1008 return mBluetoothPingCount;
1009 } else if (mBtHeadset != null) {
1010 return getCurrentBluetoothPingCount() - mBluetoothPingStart;
1011 }
Amith Yamasani82cb0292009-08-18 11:29:28 -07001012 return 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001013 }
1014
1015 public void setBtHeadset(BluetoothHeadset headset) {
Amith Yamasani82cb0292009-08-18 11:29:28 -07001016 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) {
1017 mBluetoothPingStart = getCurrentBluetoothPingCount();
1018 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001019 mBtHeadset = headset;
1020 }
1021
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001022 public void doUnplug(long batteryUptime, long batteryRealtime) {
1023 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
1024 Uid u = mUidStats.valueAt(iu);
1025 u.mStartedTcpBytesReceived = NetStat.getUidRxBytes(u.mUid);
1026 u.mStartedTcpBytesSent = NetStat.getUidTxBytes(u.mUid);
1027 u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived;
1028 u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent;
1029 }
1030 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
1031 mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime);
1032 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001033 // Track total mobile data
1034 doDataUnplug(mMobileDataRx, NetStat.getMobileRxBytes());
1035 doDataUnplug(mMobileDataTx, NetStat.getMobileTxBytes());
1036 doDataUnplug(mTotalDataRx, NetStat.getTotalRxBytes());
1037 doDataUnplug(mTotalDataTx, NetStat.getTotalTxBytes());
1038 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001039 mRadioDataStart = getCurrentRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001040 mRadioDataUptime = 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001041 // Track bt headset ping count
1042 mBluetoothPingStart = getCurrentBluetoothPingCount();
1043 mBluetoothPingCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001044 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001045
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001046 public void doPlug(long batteryUptime, long batteryRealtime) {
1047 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
1048 Uid u = mUidStats.valueAt(iu);
1049 if (u.mStartedTcpBytesReceived >= 0) {
1050 u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived();
1051 u.mStartedTcpBytesReceived = -1;
1052 }
1053 if (u.mStartedTcpBytesSent >= 0) {
1054 u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent();
1055 u.mStartedTcpBytesSent = -1;
1056 }
1057 }
1058 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
1059 mUnpluggables.get(i).plug(batteryUptime, batteryRealtime);
1060 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001061 doDataPlug(mMobileDataRx, NetStat.getMobileRxBytes());
1062 doDataPlug(mMobileDataTx, NetStat.getMobileTxBytes());
1063 doDataPlug(mTotalDataRx, NetStat.getTotalRxBytes());
1064 doDataPlug(mTotalDataTx, NetStat.getTotalTxBytes());
1065 // Track radio awake time
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001066 mRadioDataUptime = getRadioDataUptime();
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001067 mRadioDataStart = -1;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001068
1069 // Track bt headset ping count
1070 mBluetoothPingCount = getBluetoothPingCount();
1071 mBluetoothPingStart = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001072 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001074 public void noteStartGps(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001075 getUidStatsLocked(uid).noteStartGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001076 }
1077
1078 public void noteStopGps(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001079 getUidStatsLocked(uid).noteStopGps();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001080 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001081
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001082 public void noteScreenOnLocked() {
1083 if (!mScreenOn) {
1084 mScreenOn = true;
1085 mScreenOnTimer.startRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001086 if (mScreenBrightnessBin >= 0) {
1087 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this);
1088 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001089 }
1090 }
1091
1092 public void noteScreenOffLocked() {
1093 if (mScreenOn) {
1094 mScreenOn = false;
1095 mScreenOnTimer.stopRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001096 if (mScreenBrightnessBin >= 0) {
1097 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1098 }
1099 }
1100 }
1101
1102 public void noteScreenBrightnessLocked(int brightness) {
1103 // Bin the brightness.
1104 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
1105 if (bin < 0) bin = 0;
1106 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
1107 if (mScreenBrightnessBin != bin) {
1108 if (mScreenOn) {
1109 if (mScreenBrightnessBin >= 0) {
1110 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
1111 }
1112 mScreenBrightnessTimer[bin].startRunningLocked(this);
1113 }
1114 mScreenBrightnessBin = bin;
1115 }
1116 }
1117
1118 public void noteInputEventLocked() {
1119 mInputEventCounter.stepLocked();
1120 }
1121
1122 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001123 getUidStatsLocked(uid).noteUserActivityLocked(event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001124 }
1125
1126 public void notePhoneOnLocked() {
1127 if (!mPhoneOn) {
1128 mPhoneOn = true;
1129 mPhoneOnTimer.startRunningLocked(this);
1130 }
1131 }
1132
1133 public void notePhoneOffLocked() {
1134 if (mPhoneOn) {
1135 mPhoneOn = false;
1136 mPhoneOnTimer.stopRunningLocked(this);
1137 }
1138 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001139
Amith Yamasanif37447b2009-10-08 18:28:01 -07001140 /**
1141 * Telephony stack updates the phone state.
1142 * @param state phone state from ServiceState.getState()
1143 */
1144 public void notePhoneStateLocked(int state) {
1145 int bin = mPhoneSignalStrengthBin;
1146 boolean isAirplaneMode = state == ServiceState.STATE_POWER_OFF;
1147 // Stop all timers
1148 if (isAirplaneMode || state == ServiceState.STATE_OUT_OF_SERVICE) {
1149 for (int i = 0; i < NUM_SIGNAL_STRENGTH_BINS; i++) {
1150 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
1151 mPhoneSignalStrengthsTimer[i].stopRunningLocked(this);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001152 }
1153 }
1154 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07001155 // Stop Signal Scanning timer, in case we're going into service
1156 while (mPhoneSignalScanningTimer.isRunningLocked()) {
1157 mPhoneSignalScanningTimer.stopRunningLocked(this);
1158 }
1159
1160 // If we're back in service or continuing in service, restart the old timer.
1161 if (state == ServiceState.STATE_IN_SERVICE) {
1162 if (bin == -1) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
1163 if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
1164 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
1165 }
1166 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
1167 mPhoneSignalStrengthBin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
1168 if (!mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].isRunningLocked()) {
1169 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].startRunningLocked(this);
1170 }
1171 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
1172 mPhoneSignalScanningTimer.startRunningLocked(this);
1173 }
1174 }
1175 mPhoneServiceState = state;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001176 }
1177
Wink Savillee9b06d72009-05-18 21:47:50 -07001178 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07001179 // Bin the strength.
1180 int bin;
Amith Yamasanif37447b2009-10-08 18:28:01 -07001181 if (mPhoneServiceState == ServiceState.STATE_POWER_OFF
1182 || mPhoneServiceState == ServiceState.STATE_OUT_OF_SERVICE) {
1183 // Ignore any signal strength changes when radio was turned off or out of service.
1184 return;
1185 }
Wink Savillee9b06d72009-05-18 21:47:50 -07001186 if (!signalStrength.isGsm()) {
1187 int dBm = signalStrength.getCdmaDbm();
Amith Yamasanif37447b2009-10-08 18:28:01 -07001188 if (dBm >= -75) bin = SIGNAL_STRENGTH_GREAT;
1189 else if (dBm >= -85) bin = SIGNAL_STRENGTH_GOOD;
1190 else if (dBm >= -95) bin = SIGNAL_STRENGTH_MODERATE;
1191 else if (dBm >= -100) bin = SIGNAL_STRENGTH_POOR;
1192 else bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Wink Savillee9b06d72009-05-18 21:47:50 -07001193 } else {
1194 int asu = signalStrength.getGsmSignalStrength();
1195 if (asu < 0 || asu >= 99) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
1196 else if (asu >= 16) bin = SIGNAL_STRENGTH_GREAT;
1197 else if (asu >= 8) bin = SIGNAL_STRENGTH_GOOD;
1198 else if (asu >= 4) bin = SIGNAL_STRENGTH_MODERATE;
1199 else bin = SIGNAL_STRENGTH_POOR;
1200 }
Dianne Hackborn627bba72009-03-24 22:32:56 -07001201 if (mPhoneSignalStrengthBin != bin) {
1202 if (mPhoneSignalStrengthBin >= 0) {
1203 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
1204 }
1205 mPhoneSignalStrengthBin = bin;
1206 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
1207 }
1208 }
1209
1210 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
1211 int bin = DATA_CONNECTION_NONE;
1212 if (hasData) {
1213 switch (dataType) {
1214 case TelephonyManager.NETWORK_TYPE_EDGE:
1215 bin = DATA_CONNECTION_EDGE;
1216 break;
1217 case TelephonyManager.NETWORK_TYPE_GPRS:
1218 bin = DATA_CONNECTION_GPRS;
1219 break;
1220 case TelephonyManager.NETWORK_TYPE_UMTS:
1221 bin = DATA_CONNECTION_UMTS;
1222 break;
1223 default:
1224 bin = DATA_CONNECTION_OTHER;
1225 break;
1226 }
1227 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001228 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001229 if (mPhoneDataConnectionType != bin) {
1230 if (mPhoneDataConnectionType >= 0) {
1231 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this);
1232 }
1233 mPhoneDataConnectionType = bin;
1234 mPhoneDataConnectionsTimer[bin].startRunningLocked(this);
1235 }
1236 }
1237
Dianne Hackborn617f8772009-03-31 15:04:46 -07001238 public void noteWifiOnLocked(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001239 if (!mWifiOn) {
1240 mWifiOn = true;
1241 mWifiOnTimer.startRunningLocked(this);
1242 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001243 if (mWifiOnUid != uid) {
1244 if (mWifiOnUid >= 0) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001245 getUidStatsLocked(mWifiOnUid).noteWifiTurnedOffLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001246 }
1247 mWifiOnUid = uid;
Dianne Hackborn2e418422009-06-22 20:00:17 -07001248 getUidStatsLocked(uid).noteWifiTurnedOnLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001249 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001250 }
1251
Dianne Hackborn617f8772009-03-31 15:04:46 -07001252 public void noteWifiOffLocked(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001253 if (mWifiOn) {
1254 mWifiOn = false;
1255 mWifiOnTimer.stopRunningLocked(this);
1256 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001257 if (mWifiOnUid >= 0) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001258 getUidStatsLocked(mWifiOnUid).noteWifiTurnedOffLocked();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001259 mWifiOnUid = -1;
1260 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001261 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001262
1263 public void noteAudioOnLocked(int uid) {
1264 if (!mAudioOn) {
1265 mAudioOn = true;
1266 mAudioOnTimer.startRunningLocked(this);
1267 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001268 getUidStatsLocked(uid).noteAudioTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001269 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001270
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001271 public void noteAudioOffLocked(int uid) {
1272 if (mAudioOn) {
1273 mAudioOn = false;
1274 mAudioOnTimer.stopRunningLocked(this);
1275 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001276 getUidStatsLocked(uid).noteAudioTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001277 }
1278
1279 public void noteVideoOnLocked(int uid) {
1280 if (!mVideoOn) {
1281 mVideoOn = true;
1282 mVideoOnTimer.startRunningLocked(this);
1283 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001284 getUidStatsLocked(uid).noteVideoTurnedOnLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001285 }
1286
1287 public void noteVideoOffLocked(int uid) {
1288 if (mVideoOn) {
1289 mVideoOn = false;
1290 mVideoOnTimer.stopRunningLocked(this);
1291 }
Dianne Hackborn2e418422009-06-22 20:00:17 -07001292 getUidStatsLocked(uid).noteVideoTurnedOffLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001293 }
1294
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001295 public void noteWifiRunningLocked() {
1296 if (!mWifiRunning) {
1297 mWifiRunning = true;
1298 mWifiRunningTimer.startRunningLocked(this);
1299 }
1300 }
1301
1302 public void noteWifiStoppedLocked() {
1303 if (mWifiRunning) {
1304 mWifiRunning = false;
1305 mWifiRunningTimer.stopRunningLocked(this);
1306 }
1307 }
1308
The Android Open Source Project10592532009-03-18 17:39:46 -07001309 public void noteBluetoothOnLocked() {
1310 if (!mBluetoothOn) {
1311 mBluetoothOn = true;
1312 mBluetoothOnTimer.startRunningLocked(this);
1313 }
1314 }
1315
1316 public void noteBluetoothOffLocked() {
1317 if (mBluetoothOn) {
1318 mBluetoothOn = false;
1319 mBluetoothOnTimer.stopRunningLocked(this);
1320 }
1321 }
1322
1323 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001324 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001325 }
1326
1327 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001328 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001329 }
1330
1331 public void noteScanWifiLockAcquiredLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001332 getUidStatsLocked(uid).noteScanWifiLockAcquiredLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001333 }
1334
1335 public void noteScanWifiLockReleasedLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001336 getUidStatsLocked(uid).noteScanWifiLockReleasedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07001337 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001338
1339 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001340 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001341 }
1342
1343 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn2e418422009-06-22 20:00:17 -07001344 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001345 }
1346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001347 @Override public long getScreenOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001348 return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 }
1350
Dianne Hackborn617f8772009-03-31 15:04:46 -07001351 @Override public long getScreenBrightnessTime(int brightnessBin,
1352 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001353 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn617f8772009-03-31 15:04:46 -07001354 batteryRealtime, which);
1355 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001356
Dianne Hackborn617f8772009-03-31 15:04:46 -07001357 @Override public int getInputEventCount(int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001358 return mInputEventCounter.getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001359 }
1360
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001361 @Override public long getPhoneOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001362 return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001363 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001364
Dianne Hackborn627bba72009-03-24 22:32:56 -07001365 @Override public long getPhoneSignalStrengthTime(int strengthBin,
1366 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001367 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07001368 batteryRealtime, which);
1369 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07001370
1371 @Override public long getPhoneSignalScanningTime(
1372 long batteryRealtime, int which) {
1373 return mPhoneSignalScanningTimer.getTotalTimeLocked(
1374 batteryRealtime, which);
1375 }
1376
Dianne Hackborn617f8772009-03-31 15:04:46 -07001377 @Override public int getPhoneSignalStrengthCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001378 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001379 }
1380
Dianne Hackborn627bba72009-03-24 22:32:56 -07001381 @Override public long getPhoneDataConnectionTime(int dataType,
1382 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001383 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07001384 batteryRealtime, which);
1385 }
1386
Dianne Hackborn617f8772009-03-31 15:04:46 -07001387 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001388 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001389 }
1390
The Android Open Source Project10592532009-03-18 17:39:46 -07001391 @Override public long getWifiOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001392 return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001393 }
1394
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001395 @Override public long getWifiRunningTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001396 return mWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001397 }
1398
The Android Open Source Project10592532009-03-18 17:39:46 -07001399 @Override public long getBluetoothOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001400 return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001401 }
1402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001403 @Override public boolean getIsOnBattery() {
1404 return mOnBattery;
1405 }
1406
1407 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
1408 return mUidStats;
1409 }
1410
1411 /**
1412 * The statistics associated with a particular uid.
1413 */
1414 public final class Uid extends BatteryStats.Uid {
1415
1416 final int mUid;
1417 long mLoadedTcpBytesReceived;
1418 long mLoadedTcpBytesSent;
1419 long mCurrentTcpBytesReceived;
1420 long mCurrentTcpBytesSent;
1421 long mTcpBytesReceivedAtLastUnplug;
1422 long mTcpBytesSentAtLastUnplug;
1423
1424 // These are not saved/restored when parcelling, since we want
1425 // to return from the parcel with a snapshot of the state.
1426 long mStartedTcpBytesReceived = -1;
1427 long mStartedTcpBytesSent = -1;
1428
Dianne Hackborn617f8772009-03-31 15:04:46 -07001429 boolean mWifiTurnedOn;
Evan Millarc64edde2009-04-18 12:26:32 -07001430 StopwatchTimer mWifiTurnedOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -07001431
The Android Open Source Project10592532009-03-18 17:39:46 -07001432 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07001433 StopwatchTimer mFullWifiLockTimer;
The Android Open Source Project10592532009-03-18 17:39:46 -07001434
1435 boolean mScanWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07001436 StopwatchTimer mScanWifiLockTimer;
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001437
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001438 boolean mWifiMulticastEnabled;
1439 StopwatchTimer mWifiMulticastTimer;
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001440
1441 boolean mAudioTurnedOn;
1442 StopwatchTimer mAudioTurnedOnTimer;
1443
1444 boolean mVideoTurnedOn;
1445 StopwatchTimer mVideoTurnedOnTimer;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001446
Dianne Hackborn617f8772009-03-31 15:04:46 -07001447 Counter[] mUserActivityCounters;
1448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001449 /**
1450 * The statistics we have collected for this uid's wake locks.
1451 */
1452 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>();
1453
1454 /**
1455 * The statistics we have collected for this uid's sensor activations.
1456 */
1457 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>();
1458
1459 /**
1460 * The statistics we have collected for this uid's processes.
1461 */
1462 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>();
1463
1464 /**
1465 * The statistics we have collected for this uid's processes.
1466 */
1467 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>();
1468
1469 public Uid(int uid) {
1470 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001471 mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, null, mUnpluggables);
1472 mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables);
1473 mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001474 mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED,
1475 null, mUnpluggables);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001476 mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, null, mUnpluggables);
1477 mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001478 }
1479
1480 @Override
1481 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
1482 return mWakelockStats;
1483 }
1484
1485 @Override
1486 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() {
1487 return mSensorStats;
1488 }
1489
1490 @Override
1491 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
1492 return mProcessStats;
1493 }
1494
1495 @Override
1496 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
1497 return mPackageStats;
1498 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001499
1500 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001501 public int getUid() {
1502 return mUid;
1503 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001504
1505 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001506 public long getTcpBytesReceived(int which) {
1507 if (which == STATS_LAST) {
1508 return mLoadedTcpBytesReceived;
1509 } else {
1510 long current = computeCurrentTcpBytesReceived();
1511 if (which == STATS_UNPLUGGED) {
1512 current -= mTcpBytesReceivedAtLastUnplug;
1513 } else if (which == STATS_TOTAL) {
1514 current += mLoadedTcpBytesReceived;
1515 }
1516 return current;
1517 }
1518 }
1519
1520 public long computeCurrentTcpBytesReceived() {
1521 return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0
1522 ? (NetStat.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0);
1523 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001524
1525 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001526 public long getTcpBytesSent(int which) {
1527 if (which == STATS_LAST) {
1528 return mLoadedTcpBytesSent;
1529 } else {
1530 long current = computeCurrentTcpBytesSent();
1531 if (which == STATS_UNPLUGGED) {
1532 current -= mTcpBytesSentAtLastUnplug;
1533 } else if (which == STATS_TOTAL) {
1534 current += mLoadedTcpBytesSent;
1535 }
1536 return current;
1537 }
1538 }
1539
The Android Open Source Project10592532009-03-18 17:39:46 -07001540 @Override
Dianne Hackborn617f8772009-03-31 15:04:46 -07001541 public void noteWifiTurnedOnLocked() {
1542 if (!mWifiTurnedOn) {
1543 mWifiTurnedOn = true;
1544 mWifiTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
1545 }
1546 }
1547
1548 @Override
1549 public void noteWifiTurnedOffLocked() {
1550 if (mWifiTurnedOn) {
1551 mWifiTurnedOn = false;
1552 mWifiTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
1553 }
1554 }
1555
1556 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07001557 public void noteFullWifiLockAcquiredLocked() {
1558 if (!mFullWifiLockOut) {
1559 mFullWifiLockOut = true;
1560 mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
1561 }
1562 }
1563
1564 @Override
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001565 public void noteVideoTurnedOnLocked() {
1566 if (!mVideoTurnedOn) {
1567 mVideoTurnedOn = true;
1568 mVideoTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
1569 }
1570 }
1571
1572 @Override
1573 public void noteVideoTurnedOffLocked() {
1574 if (mVideoTurnedOn) {
1575 mVideoTurnedOn = false;
1576 mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
1577 }
1578 }
1579
1580 @Override
1581 public void noteAudioTurnedOnLocked() {
1582 if (!mAudioTurnedOn) {
1583 mAudioTurnedOn = true;
1584 mAudioTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
1585 }
1586 }
1587
1588 @Override
1589 public void noteAudioTurnedOffLocked() {
1590 if (mAudioTurnedOn) {
1591 mAudioTurnedOn = false;
1592 mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
1593 }
1594 }
1595
1596 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07001597 public void noteFullWifiLockReleasedLocked() {
1598 if (mFullWifiLockOut) {
1599 mFullWifiLockOut = false;
1600 mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
1601 }
1602 }
1603
1604 @Override
1605 public void noteScanWifiLockAcquiredLocked() {
1606 if (!mScanWifiLockOut) {
1607 mScanWifiLockOut = true;
1608 mScanWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
1609 }
1610 }
1611
1612 @Override
1613 public void noteScanWifiLockReleasedLocked() {
1614 if (mScanWifiLockOut) {
1615 mScanWifiLockOut = false;
1616 mScanWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
1617 }
1618 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001619
1620 @Override
1621 public void noteWifiMulticastEnabledLocked() {
1622 if (!mWifiMulticastEnabled) {
1623 mWifiMulticastEnabled = true;
1624 mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this);
1625 }
1626 }
1627
1628 @Override
1629 public void noteWifiMulticastDisabledLocked() {
1630 if (mWifiMulticastEnabled) {
1631 mWifiMulticastEnabled = false;
1632 mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this);
1633 }
1634 }
1635
Dianne Hackborn617f8772009-03-31 15:04:46 -07001636 @Override
1637 public long getWifiTurnedOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001638 return mWifiTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001639 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001640
1641 @Override
1642 public long getAudioTurnedOnTime(long batteryRealtime, int which) {
1643 return mAudioTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
1644 }
1645
1646 @Override
1647 public long getVideoTurnedOnTime(long batteryRealtime, int which) {
1648 return mVideoTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
1649 }
1650
The Android Open Source Project10592532009-03-18 17:39:46 -07001651 @Override
1652 public long getFullWifiLockTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001653 return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001654 }
1655
1656 @Override
1657 public long getScanWifiLockTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001658 return mScanWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001659 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001660
1661 @Override
1662 public long getWifiMulticastTime(long batteryRealtime, int which) {
1663 return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime,
1664 which);
1665 }
1666
Dianne Hackborn617f8772009-03-31 15:04:46 -07001667 @Override
1668 public void noteUserActivityLocked(int type) {
1669 if (mUserActivityCounters == null) {
1670 initUserActivityLocked();
1671 }
1672 if (type < 0) type = 0;
1673 else if (type >= NUM_USER_ACTIVITY_TYPES) type = NUM_USER_ACTIVITY_TYPES-1;
1674 mUserActivityCounters[type].stepLocked();
1675 }
1676
1677 @Override
1678 public boolean hasUserActivity() {
1679 return mUserActivityCounters != null;
1680 }
1681
1682 @Override
1683 public int getUserActivityCount(int type, int which) {
1684 if (mUserActivityCounters == null) {
1685 return 0;
1686 }
Evan Millarc64edde2009-04-18 12:26:32 -07001687 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001688 }
1689
1690 void initUserActivityLocked() {
1691 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
1692 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
1693 mUserActivityCounters[i] = new Counter(mUnpluggables);
1694 }
1695 }
1696
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001697 public long computeCurrentTcpBytesSent() {
1698 return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0
1699 ? (NetStat.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0);
1700 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001702 void writeToParcelLocked(Parcel out, long batteryRealtime) {
1703 out.writeInt(mWakelockStats.size());
1704 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
1705 out.writeString(wakelockEntry.getKey());
1706 Uid.Wakelock wakelock = wakelockEntry.getValue();
1707 wakelock.writeToParcelLocked(out, batteryRealtime);
1708 }
1709
1710 out.writeInt(mSensorStats.size());
1711 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) {
1712 out.writeInt(sensorEntry.getKey());
1713 Uid.Sensor sensor = sensorEntry.getValue();
1714 sensor.writeToParcelLocked(out, batteryRealtime);
1715 }
1716
1717 out.writeInt(mProcessStats.size());
1718 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) {
1719 out.writeString(procEntry.getKey());
1720 Uid.Proc proc = procEntry.getValue();
1721 proc.writeToParcelLocked(out);
1722 }
1723
1724 out.writeInt(mPackageStats.size());
1725 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
1726 out.writeString(pkgEntry.getKey());
1727 Uid.Pkg pkg = pkgEntry.getValue();
1728 pkg.writeToParcelLocked(out);
1729 }
1730
1731 out.writeLong(mLoadedTcpBytesReceived);
1732 out.writeLong(mLoadedTcpBytesSent);
1733 out.writeLong(computeCurrentTcpBytesReceived());
1734 out.writeLong(computeCurrentTcpBytesSent());
1735 out.writeLong(mTcpBytesReceivedAtLastUnplug);
1736 out.writeLong(mTcpBytesSentAtLastUnplug);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001737 mWifiTurnedOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07001738 mFullWifiLockTimer.writeToParcel(out, batteryRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001739 mAudioTurnedOnTimer.writeToParcel(out, batteryRealtime);
1740 mVideoTurnedOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07001741 mScanWifiLockTimer.writeToParcel(out, batteryRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001742 mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001743 if (mUserActivityCounters == null) {
1744 out.writeInt(0);
1745 } else {
1746 out.writeInt(1);
1747 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
1748 mUserActivityCounters[i].writeToParcel(out);
1749 }
1750 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001751 }
1752
1753 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
1754 int numWakelocks = in.readInt();
1755 mWakelockStats.clear();
1756 for (int j = 0; j < numWakelocks; j++) {
1757 String wakelockName = in.readString();
1758 Uid.Wakelock wakelock = new Wakelock();
1759 wakelock.readFromParcelLocked(unpluggables, in);
1760 mWakelockStats.put(wakelockName, wakelock);
1761 }
1762
1763 int numSensors = in.readInt();
1764 mSensorStats.clear();
1765 for (int k = 0; k < numSensors; k++) {
1766 int sensorNumber = in.readInt();
1767 Uid.Sensor sensor = new Sensor(sensorNumber);
1768 sensor.readFromParcelLocked(mUnpluggables, in);
1769 mSensorStats.put(sensorNumber, sensor);
1770 }
1771
1772 int numProcs = in.readInt();
1773 mProcessStats.clear();
1774 for (int k = 0; k < numProcs; k++) {
1775 String processName = in.readString();
1776 Uid.Proc proc = new Proc();
1777 proc.readFromParcelLocked(in);
1778 mProcessStats.put(processName, proc);
1779 }
1780
1781 int numPkgs = in.readInt();
1782 mPackageStats.clear();
1783 for (int l = 0; l < numPkgs; l++) {
1784 String packageName = in.readString();
1785 Uid.Pkg pkg = new Pkg();
1786 pkg.readFromParcelLocked(in);
1787 mPackageStats.put(packageName, pkg);
1788 }
1789
1790 mLoadedTcpBytesReceived = in.readLong();
1791 mLoadedTcpBytesSent = in.readLong();
1792 mCurrentTcpBytesReceived = in.readLong();
1793 mCurrentTcpBytesSent = in.readLong();
1794 mTcpBytesReceivedAtLastUnplug = in.readLong();
1795 mTcpBytesSentAtLastUnplug = in.readLong();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001796 mWifiTurnedOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001797 mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07001798 mFullWifiLockOut = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001799 mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables, in);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001800 mAudioTurnedOn = false;
1801 mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, null, mUnpluggables, in);
1802 mVideoTurnedOn = false;
1803 mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07001804 mScanWifiLockOut = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001805 mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables, in);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001806 mWifiMulticastEnabled = false;
1807 mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED,
1808 null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001809 if (in.readInt() == 0) {
1810 mUserActivityCounters = null;
1811 } else {
1812 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
1813 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
1814 mUserActivityCounters[i] = new Counter(mUnpluggables, in);
1815 }
1816 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001817 }
1818
1819 /**
1820 * The statistics associated with a particular wake lock.
1821 */
1822 public final class Wakelock extends BatteryStats.Uid.Wakelock {
1823 /**
1824 * How long (in ms) this uid has been keeping the device partially awake.
1825 */
Evan Millarc64edde2009-04-18 12:26:32 -07001826 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001827
1828 /**
1829 * How long (in ms) this uid has been keeping the device fully awake.
1830 */
Evan Millarc64edde2009-04-18 12:26:32 -07001831 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001832
1833 /**
1834 * How long (in ms) this uid has had a window keeping the device awake.
1835 */
Evan Millarc64edde2009-04-18 12:26:32 -07001836 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001837
1838 /**
1839 * Reads a possibly null Timer from a Parcel. The timer is associated with the
1840 * proper timer pool from the given BatteryStatsImpl object.
1841 *
1842 * @param in the Parcel to be read from.
1843 * return a new Timer, or null.
1844 */
Evan Millarc64edde2009-04-18 12:26:32 -07001845 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001846 ArrayList<Unpluggable> unpluggables, Parcel in) {
1847 if (in.readInt() == 0) {
1848 return null;
1849 }
1850
Evan Millarc64edde2009-04-18 12:26:32 -07001851 return new StopwatchTimer(type, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001852 }
1853
1854 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
1855 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
1856 mPartialTimers, unpluggables, in);
1857 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
1858 mFullTimers, unpluggables, in);
1859 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
1860 mWindowTimers, unpluggables, in);
1861 }
1862
1863 void writeToParcelLocked(Parcel out, long batteryRealtime) {
1864 Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime);
1865 Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime);
1866 Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime);
1867 }
1868
1869 @Override
1870 public Timer getWakeTime(int type) {
1871 switch (type) {
1872 case WAKE_TYPE_FULL: return mTimerFull;
1873 case WAKE_TYPE_PARTIAL: return mTimerPartial;
1874 case WAKE_TYPE_WINDOW: return mTimerWindow;
1875 default: throw new IllegalArgumentException("type = " + type);
1876 }
1877 }
1878 }
1879
1880 public final class Sensor extends BatteryStats.Uid.Sensor {
1881 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07001882 StopwatchTimer mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001883
1884 public Sensor(int handle) {
1885 mHandle = handle;
1886 }
1887
Evan Millarc64edde2009-04-18 12:26:32 -07001888 private StopwatchTimer readTimerFromParcel(ArrayList<Unpluggable> unpluggables,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001889 Parcel in) {
1890 if (in.readInt() == 0) {
1891 return null;
1892 }
1893
Evan Millarc64edde2009-04-18 12:26:32 -07001894 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001895 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001896 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001897 mSensorTimers.put(mHandle, pool);
1898 }
Evan Millarc64edde2009-04-18 12:26:32 -07001899 return new StopwatchTimer(0, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001900 }
1901
1902 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
1903 mTimer = readTimerFromParcel(unpluggables, in);
1904 }
1905
1906 void writeToParcelLocked(Parcel out, long batteryRealtime) {
1907 Timer.writeTimerToParcel(out, mTimer, batteryRealtime);
1908 }
1909
1910 @Override
1911 public Timer getSensorTime() {
1912 return mTimer;
1913 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001914
1915 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001916 public int getHandle() {
1917 return mHandle;
1918 }
1919 }
1920
1921 /**
1922 * The statistics associated with a particular process.
1923 */
1924 public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable {
1925 /**
1926 * Total time (in 1/100 sec) spent executing in user code.
1927 */
1928 long mUserTime;
1929
1930 /**
1931 * Total time (in 1/100 sec) spent executing in kernel code.
1932 */
1933 long mSystemTime;
1934
1935 /**
1936 * Number of times the process has been started.
1937 */
1938 int mStarts;
1939
1940 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001941 * Amount of time the process was running in the foreground.
1942 */
1943 long mForegroundTime;
1944
1945 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001946 * The amount of user time loaded from a previous save.
1947 */
1948 long mLoadedUserTime;
1949
1950 /**
1951 * The amount of system time loaded from a previous save.
1952 */
1953 long mLoadedSystemTime;
1954
1955 /**
1956 * The number of times the process has started from a previous save.
1957 */
1958 int mLoadedStarts;
1959
1960 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001961 * The amount of foreground time loaded from a previous save.
1962 */
1963 long mLoadedForegroundTime;
1964
1965 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001966 * The amount of user time loaded from the previous run.
1967 */
1968 long mLastUserTime;
1969
1970 /**
1971 * The amount of system time loaded from the previous run.
1972 */
1973 long mLastSystemTime;
1974
1975 /**
1976 * The number of times the process has started from the previous run.
1977 */
1978 int mLastStarts;
1979
1980 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001981 * The amount of foreground time loaded from the previous run
1982 */
1983 long mLastForegroundTime;
1984
1985 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001986 * The amount of user time when last unplugged.
1987 */
1988 long mUnpluggedUserTime;
1989
1990 /**
1991 * The amount of system time when last unplugged.
1992 */
1993 long mUnpluggedSystemTime;
1994
1995 /**
1996 * The number of times the process has started before unplugged.
1997 */
1998 int mUnpluggedStarts;
1999
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002000 /**
2001 * The amount of foreground time since unplugged.
2002 */
2003 long mUnpluggedForegroundTime;
2004
Amith Yamasanie43530a2009-08-21 13:11:37 -07002005 SamplingCounter[] mSpeedBins;
2006
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002007 Proc() {
2008 mUnpluggables.add(this);
Amith Yamasanie43530a2009-08-21 13:11:37 -07002009 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
2010 for (int i = 0; i < mSpeedBins.length; i++) {
2011 mSpeedBins[i] = new SamplingCounter(mUnpluggables);
2012 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002013 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07002014
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002015 public void unplug(long batteryUptime, long batteryRealtime) {
2016 mUnpluggedUserTime = mUserTime;
2017 mUnpluggedSystemTime = mSystemTime;
2018 mUnpluggedStarts = mStarts;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002019 mUnpluggedForegroundTime = mForegroundTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002020 }
2021
2022 public void plug(long batteryUptime, long batteryRealtime) {
2023 }
2024
2025 void writeToParcelLocked(Parcel out) {
The Android Open Source Project10592532009-03-18 17:39:46 -07002026 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
2027 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
2028
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002029 out.writeLong(mUserTime);
2030 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002031 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002032 out.writeInt(mStarts);
2033 out.writeLong(mLoadedUserTime);
2034 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002035 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002036 out.writeInt(mLoadedStarts);
2037 out.writeLong(mLastUserTime);
2038 out.writeLong(mLastSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002039 out.writeLong(mLastForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002040 out.writeInt(mLastStarts);
2041 out.writeLong(mUnpluggedUserTime);
2042 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002043 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002044 out.writeInt(mUnpluggedStarts);
Amith Yamasanie43530a2009-08-21 13:11:37 -07002045
2046 out.writeInt(mSpeedBins.length);
2047 for (int i = 0; i < mSpeedBins.length; i++) {
2048 mSpeedBins[i].writeToParcel(out);
2049 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002050 }
2051
2052 void readFromParcelLocked(Parcel in) {
2053 mUserTime = in.readLong();
2054 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002055 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002056 mStarts = in.readInt();
2057 mLoadedUserTime = in.readLong();
2058 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002059 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002060 mLoadedStarts = in.readInt();
2061 mLastUserTime = in.readLong();
2062 mLastSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002063 mLastForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002064 mLastStarts = in.readInt();
2065 mUnpluggedUserTime = in.readLong();
2066 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002067 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002068 mUnpluggedStarts = in.readInt();
Amith Yamasanie43530a2009-08-21 13:11:37 -07002069
2070 int bins = in.readInt();
2071 mSpeedBins = new SamplingCounter[bins];
2072 for (int i = 0; i < bins; i++) {
2073 mSpeedBins[i] = new SamplingCounter(mUnpluggables, in);
2074 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002075 }
2076
2077 public BatteryStatsImpl getBatteryStats() {
2078 return BatteryStatsImpl.this;
2079 }
2080
2081 public void addCpuTimeLocked(int utime, int stime) {
2082 mUserTime += utime;
2083 mSystemTime += stime;
2084 }
2085
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002086 public void addForegroundTimeLocked(long ttime) {
2087 mForegroundTime += ttime;
2088 }
2089
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002090 public void incStartsLocked() {
2091 mStarts++;
2092 }
2093
2094 @Override
2095 public long getUserTime(int which) {
2096 long val;
2097 if (which == STATS_LAST) {
2098 val = mLastUserTime;
2099 } else {
2100 val = mUserTime;
2101 if (which == STATS_CURRENT) {
2102 val -= mLoadedUserTime;
2103 } else if (which == STATS_UNPLUGGED) {
2104 val -= mUnpluggedUserTime;
2105 }
2106 }
2107 return val;
2108 }
2109
2110 @Override
2111 public long getSystemTime(int which) {
2112 long val;
2113 if (which == STATS_LAST) {
2114 val = mLastSystemTime;
2115 } else {
2116 val = mSystemTime;
2117 if (which == STATS_CURRENT) {
2118 val -= mLoadedSystemTime;
2119 } else if (which == STATS_UNPLUGGED) {
2120 val -= mUnpluggedSystemTime;
2121 }
2122 }
2123 return val;
2124 }
2125
2126 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07002127 public long getForegroundTime(int which) {
2128 long val;
2129 if (which == STATS_LAST) {
2130 val = mLastForegroundTime;
2131 } else {
2132 val = mForegroundTime;
2133 if (which == STATS_CURRENT) {
2134 val -= mLoadedForegroundTime;
2135 } else if (which == STATS_UNPLUGGED) {
2136 val -= mUnpluggedForegroundTime;
2137 }
2138 }
2139 return val;
2140 }
2141
2142 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002143 public int getStarts(int which) {
2144 int val;
2145 if (which == STATS_LAST) {
2146 val = mLastStarts;
2147 } else {
2148 val = mStarts;
2149 if (which == STATS_CURRENT) {
2150 val -= mLoadedStarts;
2151 } else if (which == STATS_UNPLUGGED) {
2152 val -= mUnpluggedStarts;
2153 }
2154 }
2155 return val;
2156 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07002157
2158 /* Called by ActivityManagerService when CPU times are updated. */
2159 public void addSpeedStepTimes(long[] values) {
2160 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) {
2161 mSpeedBins[i].addCountLocked(values[i]);
2162 }
2163 }
2164
2165 @Override
2166 public long getTimeAtCpuSpeedStep(int speedStep, int which) {
2167 if (speedStep < mSpeedBins.length) {
2168 return mSpeedBins[speedStep].getCountLocked(which);
2169 } else {
2170 return 0;
2171 }
2172 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002173 }
2174
2175 /**
2176 * The statistics associated with a particular package.
2177 */
2178 public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable {
2179 /**
2180 * Number of times this package has done something that could wake up the
2181 * device from sleep.
2182 */
2183 int mWakeups;
2184
2185 /**
2186 * Number of things that could wake up the device loaded from a
2187 * previous save.
2188 */
2189 int mLoadedWakeups;
2190
2191 /**
2192 * Number of things that could wake up the device as of the
2193 * last run.
2194 */
2195 int mLastWakeups;
2196
2197 /**
2198 * Number of things that could wake up the device as of the
2199 * last run.
2200 */
2201 int mUnpluggedWakeups;
2202
2203 /**
2204 * The statics we have collected for this package's services.
2205 */
2206 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
2207
2208 Pkg() {
2209 mUnpluggables.add(this);
2210 }
2211
2212 public void unplug(long batteryUptime, long batteryRealtime) {
2213 mUnpluggedWakeups = mWakeups;
2214 }
2215
2216 public void plug(long batteryUptime, long batteryRealtime) {
2217 }
2218
2219 void readFromParcelLocked(Parcel in) {
2220 mWakeups = in.readInt();
2221 mLoadedWakeups = in.readInt();
2222 mLastWakeups = in.readInt();
2223 mUnpluggedWakeups = in.readInt();
2224
2225 int numServs = in.readInt();
2226 mServiceStats.clear();
2227 for (int m = 0; m < numServs; m++) {
2228 String serviceName = in.readString();
2229 Uid.Pkg.Serv serv = new Serv();
2230 mServiceStats.put(serviceName, serv);
2231
2232 serv.readFromParcelLocked(in);
2233 }
2234 }
2235
2236 void writeToParcelLocked(Parcel out) {
2237 out.writeInt(mWakeups);
2238 out.writeInt(mLoadedWakeups);
2239 out.writeInt(mLastWakeups);
2240 out.writeInt(mUnpluggedWakeups);
2241
2242 out.writeInt(mServiceStats.size());
2243 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
2244 out.writeString(servEntry.getKey());
2245 Uid.Pkg.Serv serv = servEntry.getValue();
2246
2247 serv.writeToParcelLocked(out);
2248 }
2249 }
2250
2251 @Override
2252 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
2253 return mServiceStats;
2254 }
2255
2256 @Override
2257 public int getWakeups(int which) {
2258 int val;
2259 if (which == STATS_LAST) {
2260 val = mLastWakeups;
2261 } else {
2262 val = mWakeups;
2263 if (which == STATS_CURRENT) {
2264 val -= mLoadedWakeups;
2265 } else if (which == STATS_UNPLUGGED) {
2266 val -= mUnpluggedWakeups;
2267 }
2268 }
2269
2270 return val;
2271 }
2272
2273 /**
2274 * The statistics associated with a particular service.
2275 */
2276 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable {
2277 /**
2278 * Total time (ms in battery uptime) the service has been left started.
2279 */
2280 long mStartTime;
2281
2282 /**
2283 * If service has been started and not yet stopped, this is
2284 * when it was started.
2285 */
2286 long mRunningSince;
2287
2288 /**
2289 * True if we are currently running.
2290 */
2291 boolean mRunning;
2292
2293 /**
2294 * Total number of times startService() has been called.
2295 */
2296 int mStarts;
2297
2298 /**
2299 * Total time (ms in battery uptime) the service has been left launched.
2300 */
2301 long mLaunchedTime;
2302
2303 /**
2304 * If service has been launched and not yet exited, this is
2305 * when it was launched (ms in battery uptime).
2306 */
2307 long mLaunchedSince;
2308
2309 /**
2310 * True if we are currently launched.
2311 */
2312 boolean mLaunched;
2313
2314 /**
2315 * Total number times the service has been launched.
2316 */
2317 int mLaunches;
2318
2319 /**
2320 * The amount of time spent started loaded from a previous save
2321 * (ms in battery uptime).
2322 */
2323 long mLoadedStartTime;
2324
2325 /**
2326 * The number of starts loaded from a previous save.
2327 */
2328 int mLoadedStarts;
2329
2330 /**
2331 * The number of launches loaded from a previous save.
2332 */
2333 int mLoadedLaunches;
2334
2335 /**
2336 * The amount of time spent started as of the last run (ms
2337 * in battery uptime).
2338 */
2339 long mLastStartTime;
2340
2341 /**
2342 * The number of starts as of the last run.
2343 */
2344 int mLastStarts;
2345
2346 /**
2347 * The number of launches as of the last run.
2348 */
2349 int mLastLaunches;
2350
2351 /**
2352 * The amount of time spent started when last unplugged (ms
2353 * in battery uptime).
2354 */
2355 long mUnpluggedStartTime;
2356
2357 /**
2358 * The number of starts when last unplugged.
2359 */
2360 int mUnpluggedStarts;
2361
2362 /**
2363 * The number of launches when last unplugged.
2364 */
2365 int mUnpluggedLaunches;
2366
2367 Serv() {
2368 mUnpluggables.add(this);
2369 }
2370
2371 public void unplug(long batteryUptime, long batteryRealtime) {
2372 mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime);
2373 mUnpluggedStarts = mStarts;
2374 mUnpluggedLaunches = mLaunches;
2375 }
2376
2377 public void plug(long batteryUptime, long batteryRealtime) {
2378 }
2379
2380 void readFromParcelLocked(Parcel in) {
2381 mStartTime = in.readLong();
2382 mRunningSince = in.readLong();
2383 mRunning = in.readInt() != 0;
2384 mStarts = in.readInt();
2385 mLaunchedTime = in.readLong();
2386 mLaunchedSince = in.readLong();
2387 mLaunched = in.readInt() != 0;
2388 mLaunches = in.readInt();
2389 mLoadedStartTime = in.readLong();
2390 mLoadedStarts = in.readInt();
2391 mLoadedLaunches = in.readInt();
2392 mLastStartTime = in.readLong();
2393 mLastStarts = in.readInt();
2394 mLastLaunches = in.readInt();
2395 mUnpluggedStartTime = in.readLong();
2396 mUnpluggedStarts = in.readInt();
2397 mUnpluggedLaunches = in.readInt();
2398 }
2399
2400 void writeToParcelLocked(Parcel out) {
2401 out.writeLong(mStartTime);
2402 out.writeLong(mRunningSince);
2403 out.writeInt(mRunning ? 1 : 0);
2404 out.writeInt(mStarts);
2405 out.writeLong(mLaunchedTime);
2406 out.writeLong(mLaunchedSince);
2407 out.writeInt(mLaunched ? 1 : 0);
2408 out.writeInt(mLaunches);
2409 out.writeLong(mLoadedStartTime);
2410 out.writeInt(mLoadedStarts);
2411 out.writeInt(mLoadedLaunches);
2412 out.writeLong(mLastStartTime);
2413 out.writeInt(mLastStarts);
2414 out.writeInt(mLastLaunches);
2415 out.writeLong(mUnpluggedStartTime);
2416 out.writeInt(mUnpluggedStarts);
2417 out.writeInt(mUnpluggedLaunches);
2418 }
2419
2420 long getLaunchTimeToNowLocked(long batteryUptime) {
2421 if (!mLaunched) return mLaunchedTime;
2422 return mLaunchedTime + batteryUptime - mLaunchedSince;
2423 }
2424
2425 long getStartTimeToNowLocked(long batteryUptime) {
2426 if (!mRunning) return mStartTime;
2427 return mStartTime + batteryUptime - mRunningSince;
2428 }
2429
2430 public void startLaunchedLocked() {
2431 if (!mLaunched) {
2432 mLaunches++;
2433 mLaunchedSince = getBatteryUptimeLocked();
2434 mLaunched = true;
2435 }
2436 }
2437
2438 public void stopLaunchedLocked() {
2439 if (mLaunched) {
2440 long time = getBatteryUptimeLocked() - mLaunchedSince;
2441 if (time > 0) {
2442 mLaunchedTime += time;
2443 } else {
2444 mLaunches--;
2445 }
2446 mLaunched = false;
2447 }
2448 }
2449
2450 public void startRunningLocked() {
2451 if (!mRunning) {
2452 mStarts++;
2453 mRunningSince = getBatteryUptimeLocked();
2454 mRunning = true;
2455 }
2456 }
2457
2458 public void stopRunningLocked() {
2459 if (mRunning) {
2460 long time = getBatteryUptimeLocked() - mRunningSince;
2461 if (time > 0) {
2462 mStartTime += time;
2463 } else {
2464 mStarts--;
2465 }
2466 mRunning = false;
2467 }
2468 }
2469
2470 public BatteryStatsImpl getBatteryStats() {
2471 return BatteryStatsImpl.this;
2472 }
2473
2474 @Override
2475 public int getLaunches(int which) {
2476 int val;
2477
2478 if (which == STATS_LAST) {
2479 val = mLastLaunches;
2480 } else {
2481 val = mLaunches;
2482 if (which == STATS_CURRENT) {
2483 val -= mLoadedLaunches;
2484 } else if (which == STATS_UNPLUGGED) {
2485 val -= mUnpluggedLaunches;
2486 }
2487 }
2488
2489 return val;
2490 }
2491
2492 @Override
2493 public long getStartTime(long now, int which) {
2494 long val;
2495 if (which == STATS_LAST) {
2496 val = mLastStartTime;
2497 } else {
2498 val = getStartTimeToNowLocked(now);
2499 if (which == STATS_CURRENT) {
2500 val -= mLoadedStartTime;
2501 } else if (which == STATS_UNPLUGGED) {
2502 val -= mUnpluggedStartTime;
2503 }
2504 }
2505
2506 return val;
2507 }
2508
2509 @Override
2510 public int getStarts(int which) {
2511 int val;
2512 if (which == STATS_LAST) {
2513 val = mLastStarts;
2514 } else {
2515 val = mStarts;
2516 if (which == STATS_CURRENT) {
2517 val -= mLoadedStarts;
2518 } else if (which == STATS_UNPLUGGED) {
2519 val -= mUnpluggedStarts;
2520 }
2521 }
2522
2523 return val;
2524 }
2525 }
2526
2527 public BatteryStatsImpl getBatteryStats() {
2528 return BatteryStatsImpl.this;
2529 }
2530
2531 public void incWakeupsLocked() {
2532 mWakeups++;
2533 }
2534
2535 final Serv newServiceStatsLocked() {
2536 return new Serv();
2537 }
2538 }
2539
2540 /**
2541 * Retrieve the statistics object for a particular process, creating
2542 * if needed.
2543 */
2544 public Proc getProcessStatsLocked(String name) {
2545 Proc ps = mProcessStats.get(name);
2546 if (ps == null) {
2547 ps = new Proc();
2548 mProcessStats.put(name, ps);
2549 }
2550
2551 return ps;
2552 }
2553
2554 /**
2555 * Retrieve the statistics object for a particular service, creating
2556 * if needed.
2557 */
2558 public Pkg getPackageStatsLocked(String name) {
2559 Pkg ps = mPackageStats.get(name);
2560 if (ps == null) {
2561 ps = new Pkg();
2562 mPackageStats.put(name, ps);
2563 }
2564
2565 return ps;
2566 }
2567
2568 /**
2569 * Retrieve the statistics object for a particular service, creating
2570 * if needed.
2571 */
2572 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
2573 Pkg ps = getPackageStatsLocked(pkg);
2574 Pkg.Serv ss = ps.mServiceStats.get(serv);
2575 if (ss == null) {
2576 ss = ps.newServiceStatsLocked();
2577 ps.mServiceStats.put(serv, ss);
2578 }
2579
2580 return ss;
2581 }
2582
Evan Millarc64edde2009-04-18 12:26:32 -07002583 public StopwatchTimer getWakeTimerLocked(String name, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002584 Wakelock wl = mWakelockStats.get(name);
2585 if (wl == null) {
2586 wl = new Wakelock();
2587 mWakelockStats.put(name, wl);
2588 }
Evan Millarc64edde2009-04-18 12:26:32 -07002589 StopwatchTimer t = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002590 switch (type) {
2591 case WAKE_TYPE_PARTIAL:
2592 t = wl.mTimerPartial;
2593 if (t == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002594 t = new StopwatchTimer(WAKE_TYPE_PARTIAL, mPartialTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002595 wl.mTimerPartial = t;
2596 }
2597 return t;
2598 case WAKE_TYPE_FULL:
2599 t = wl.mTimerFull;
2600 if (t == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002601 t = new StopwatchTimer(WAKE_TYPE_FULL, mFullTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002602 wl.mTimerFull = t;
2603 }
2604 return t;
2605 case WAKE_TYPE_WINDOW:
2606 t = wl.mTimerWindow;
2607 if (t == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002608 t = new StopwatchTimer(WAKE_TYPE_WINDOW, mWindowTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002609 wl.mTimerWindow = t;
2610 }
2611 return t;
2612 default:
2613 throw new IllegalArgumentException("type=" + type);
2614 }
2615 }
2616
Evan Millarc64edde2009-04-18 12:26:32 -07002617 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002618 Sensor se = mSensorStats.get(sensor);
2619 if (se == null) {
2620 if (!create) {
2621 return null;
2622 }
2623 se = new Sensor(sensor);
2624 mSensorStats.put(sensor, se);
2625 }
Evan Millarc64edde2009-04-18 12:26:32 -07002626 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002627 if (t != null) {
2628 return t;
2629 }
Evan Millarc64edde2009-04-18 12:26:32 -07002630 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002631 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002632 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002633 mSensorTimers.put(sensor, timers);
2634 }
Evan Millarc64edde2009-04-18 12:26:32 -07002635 t = new StopwatchTimer(BatteryStats.SENSOR, timers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002636 se.mTimer = t;
2637 return t;
2638 }
2639
2640 public void noteStartWakeLocked(String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07002641 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002642 if (t != null) {
2643 t.startRunningLocked(BatteryStatsImpl.this);
2644 }
2645 }
2646
2647 public void noteStopWakeLocked(String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07002648 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002649 if (t != null) {
2650 t.stopRunningLocked(BatteryStatsImpl.this);
2651 }
2652 }
2653
2654 public void noteStartSensor(int sensor) {
Evan Millarc64edde2009-04-18 12:26:32 -07002655 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002656 if (t != null) {
2657 t.startRunningLocked(BatteryStatsImpl.this);
2658 }
2659 }
2660
2661 public void noteStopSensor(int sensor) {
2662 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07002663 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002664 if (t != null) {
2665 t.stopRunningLocked(BatteryStatsImpl.this);
2666 }
2667 }
2668
2669 public void noteStartGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07002670 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002671 if (t != null) {
2672 t.startRunningLocked(BatteryStatsImpl.this);
2673 }
2674 }
2675
2676 public void noteStopGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07002677 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002678 if (t != null) {
2679 t.stopRunningLocked(BatteryStatsImpl.this);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07002680 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002681 }
2682
2683 public BatteryStatsImpl getBatteryStats() {
2684 return BatteryStatsImpl.this;
2685 }
2686 }
2687
2688 public BatteryStatsImpl(String filename) {
2689 mFile = new File(filename);
2690 mBackupFile = new File(filename + ".bak");
2691 mStartCount++;
Evan Millarc64edde2009-04-18 12:26:32 -07002692 mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002693 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07002694 mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002695 }
2696 mInputEventCounter = new Counter(mUnpluggables);
Evan Millarc64edde2009-04-18 12:26:32 -07002697 mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002698 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07002699 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002700 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07002701 mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002702 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07002703 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002704 }
Evan Millarc64edde2009-04-18 12:26:32 -07002705 mWifiOnTimer = new StopwatchTimer(-3, null, mUnpluggables);
2706 mWifiRunningTimer = new StopwatchTimer(-4, null, mUnpluggables);
2707 mBluetoothOnTimer = new StopwatchTimer(-5, null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002708 mOnBattery = mOnBatteryInternal = false;
2709 mTrackBatteryPastUptime = 0;
2710 mTrackBatteryPastRealtime = 0;
2711 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
2712 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
2713 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
2714 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
Evan Millar633a1742009-04-02 16:36:33 -07002715 mDischargeStartLevel = 0;
2716 mDischargeCurrentLevel = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002717 }
2718
2719 public BatteryStatsImpl(Parcel p) {
2720 mFile = mBackupFile = null;
2721 readFromParcel(p);
2722 }
2723
Amith Yamasanie43530a2009-08-21 13:11:37 -07002724 public void setNumSpeedSteps(int steps) {
2725 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
2726 }
2727
Amith Yamasanif37447b2009-10-08 18:28:01 -07002728 public void setRadioScanningTimeout(long timeout) {
2729 if (mPhoneSignalScanningTimer != null) {
2730 mPhoneSignalScanningTimer.setTimeout(timeout);
2731 }
2732 }
2733
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002734 @Override
2735 public int getStartCount() {
2736 return mStartCount;
2737 }
2738
2739 public boolean isOnBattery() {
2740 return mOnBattery;
2741 }
2742
The Android Open Source Project10592532009-03-18 17:39:46 -07002743 public void setOnBattery(boolean onBattery, int level) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002744 synchronized(this) {
Evan Millarc64edde2009-04-18 12:26:32 -07002745 updateKernelWakelocksLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002746 if (mOnBattery != onBattery) {
2747 mOnBattery = mOnBatteryInternal = onBattery;
2748
2749 long uptime = SystemClock.uptimeMillis() * 1000;
2750 long mSecRealtime = SystemClock.elapsedRealtime();
2751 long realtime = mSecRealtime * 1000;
2752 if (onBattery) {
2753 mTrackBatteryUptimeStart = uptime;
2754 mTrackBatteryRealtimeStart = realtime;
2755 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
2756 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
Evan Millar633a1742009-04-02 16:36:33 -07002757 mDischargeCurrentLevel = mDischargeStartLevel = level;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002758 doUnplug(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
2759 } else {
2760 mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
2761 mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
Evan Millar633a1742009-04-02 16:36:33 -07002762 mDischargeCurrentLevel = level;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002763 doPlug(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
2764 }
2765 if ((mLastWriteTime + (60 * 1000)) < mSecRealtime) {
2766 if (mFile != null) {
2767 writeLocked();
2768 }
2769 }
2770 }
2771 }
2772 }
Evan Millar633a1742009-04-02 16:36:33 -07002773
2774 public void recordCurrentLevel(int level) {
2775 mDischargeCurrentLevel = level;
2776 }
Evan Millarc64edde2009-04-18 12:26:32 -07002777
2778 public void updateKernelWakelocksLocked() {
2779 Map<String, KernelWakelockStats> m = readKernelWakelockStats();
2780
Marco Nelissend8593312009-04-30 14:45:06 -07002781 if (m == null) {
2782 // Not crashing might make board bringup easier.
2783 Log.w(TAG, "Couldn't get kernel wake lock stats");
2784 return;
2785 }
2786
Evan Millarc64edde2009-04-18 12:26:32 -07002787 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) {
2788 String name = ent.getKey();
2789 KernelWakelockStats kws = ent.getValue();
2790
2791 SamplingTimer kwlt = mKernelWakelockStats.get(name);
2792 if (kwlt == null) {
2793 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
2794 true /* track reported values */);
2795 mKernelWakelockStats.put(name, kwlt);
2796 }
2797 kwlt.updateCurrentReportedCount(kws.mCount);
2798 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
2799 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion);
2800 }
2801
2802 if (m.size() != mKernelWakelockStats.size()) {
2803 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
2804 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
2805 SamplingTimer st = ent.getValue();
2806 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) {
2807 st.setStale();
2808 }
2809 }
2810 }
2811 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002812
2813 public long getAwakeTimeBattery() {
2814 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
2815 }
2816
2817 public long getAwakeTimePlugged() {
2818 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
2819 }
2820
2821 @Override
2822 public long computeUptime(long curTime, int which) {
2823 switch (which) {
2824 case STATS_TOTAL: return mUptime + (curTime-mUptimeStart);
2825 case STATS_LAST: return mLastUptime;
2826 case STATS_CURRENT: return (curTime-mUptimeStart);
2827 case STATS_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart);
2828 }
2829 return 0;
2830 }
2831
2832 @Override
2833 public long computeRealtime(long curTime, int which) {
2834 switch (which) {
2835 case STATS_TOTAL: return mRealtime + (curTime-mRealtimeStart);
2836 case STATS_LAST: return mLastRealtime;
2837 case STATS_CURRENT: return (curTime-mRealtimeStart);
2838 case STATS_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart);
2839 }
2840 return 0;
2841 }
2842
2843 @Override
2844 public long computeBatteryUptime(long curTime, int which) {
2845 switch (which) {
2846 case STATS_TOTAL:
2847 return mBatteryUptime + getBatteryUptime(curTime);
2848 case STATS_LAST:
2849 return mBatteryLastUptime;
2850 case STATS_CURRENT:
2851 return getBatteryUptime(curTime);
2852 case STATS_UNPLUGGED:
2853 return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime;
2854 }
2855 return 0;
2856 }
2857
2858 @Override
2859 public long computeBatteryRealtime(long curTime, int which) {
2860 switch (which) {
2861 case STATS_TOTAL:
2862 return mBatteryRealtime + getBatteryRealtimeLocked(curTime);
2863 case STATS_LAST:
2864 return mBatteryLastRealtime;
2865 case STATS_CURRENT:
2866 return getBatteryRealtimeLocked(curTime);
2867 case STATS_UNPLUGGED:
2868 return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime;
2869 }
2870 return 0;
2871 }
2872
2873 long getBatteryUptimeLocked(long curTime) {
2874 long time = mTrackBatteryPastUptime;
2875 if (mOnBatteryInternal) {
2876 time += curTime - mTrackBatteryUptimeStart;
2877 }
2878 return time;
2879 }
2880
2881 long getBatteryUptimeLocked() {
2882 return getBatteryUptime(SystemClock.uptimeMillis() * 1000);
2883 }
2884
2885 @Override
2886 public long getBatteryUptime(long curTime) {
2887 return getBatteryUptimeLocked(curTime);
2888 }
2889
2890 long getBatteryRealtimeLocked(long curTime) {
2891 long time = mTrackBatteryPastRealtime;
2892 if (mOnBatteryInternal) {
2893 time += curTime - mTrackBatteryRealtimeStart;
2894 }
2895 return time;
2896 }
2897
2898 @Override
2899 public long getBatteryRealtime(long curTime) {
2900 return getBatteryRealtimeLocked(curTime);
2901 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002902
2903 private long getTcpBytes(long current, long[] dataBytes, int which) {
2904 if (which == STATS_LAST) {
2905 return dataBytes[STATS_LAST];
2906 } else {
2907 if (which == STATS_UNPLUGGED) {
2908 if (dataBytes[STATS_UNPLUGGED] < 0) {
2909 return dataBytes[STATS_LAST];
2910 } else {
2911 return current - dataBytes[STATS_UNPLUGGED];
2912 }
2913 } else if (which == STATS_TOTAL) {
2914 return (current - dataBytes[STATS_CURRENT]) + dataBytes[STATS_TOTAL];
2915 }
2916 return current - dataBytes[STATS_CURRENT];
2917 }
2918 }
2919
2920 /** Only STATS_UNPLUGGED works properly */
2921 public long getMobileTcpBytesSent(int which) {
2922 return getTcpBytes(NetStat.getMobileTxBytes(), mMobileDataTx, which);
2923 }
2924
2925 /** Only STATS_UNPLUGGED works properly */
2926 public long getMobileTcpBytesReceived(int which) {
2927 return getTcpBytes(NetStat.getMobileRxBytes(), mMobileDataRx, which);
2928 }
2929
2930 /** Only STATS_UNPLUGGED works properly */
2931 public long getTotalTcpBytesSent(int which) {
2932 return getTcpBytes(NetStat.getTotalTxBytes(), mTotalDataTx, which);
2933 }
2934
2935 /** Only STATS_UNPLUGGED works properly */
2936 public long getTotalTcpBytesReceived(int which) {
2937 return getTcpBytes(NetStat.getTotalRxBytes(), mTotalDataRx, which);
2938 }
2939
The Android Open Source Project10592532009-03-18 17:39:46 -07002940 @Override
Evan Millar633a1742009-04-02 16:36:33 -07002941 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002942 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07002943 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002944 }
2945 }
2946
Evan Millar633a1742009-04-02 16:36:33 -07002947 public int getDischargeStartLevelLocked() {
2948 return mDischargeStartLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07002949 }
2950
2951 @Override
Evan Millar633a1742009-04-02 16:36:33 -07002952 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002953 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07002954 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002955 }
2956 }
2957
Evan Millar633a1742009-04-02 16:36:33 -07002958 public int getDischargeCurrentLevelLocked() {
2959 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07002960 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002961
Amith Yamasanie43530a2009-08-21 13:11:37 -07002962 @Override
2963 public int getCpuSpeedSteps() {
2964 return sNumSpeedSteps;
2965 }
2966
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002967 /**
2968 * Retrieve the statistics object for a particular uid, creating if needed.
2969 */
2970 public Uid getUidStatsLocked(int uid) {
2971 Uid u = mUidStats.get(uid);
2972 if (u == null) {
2973 u = new Uid(uid);
2974 mUidStats.put(uid, u);
2975 }
2976 return u;
2977 }
2978
2979 /**
2980 * Remove the statistics object for a particular uid.
2981 */
2982 public void removeUidStatsLocked(int uid) {
2983 mUidStats.remove(uid);
2984 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002985
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002986 /**
2987 * Retrieve the statistics object for a particular process, creating
2988 * if needed.
2989 */
2990 public Uid.Proc getProcessStatsLocked(int uid, String name) {
2991 Uid u = getUidStatsLocked(uid);
2992 return u.getProcessStatsLocked(name);
2993 }
2994
2995 /**
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002996 * Retrieve the statistics object for a particular process, given
2997 * the name of the process.
2998 * @param name process name
2999 * @return the statistics object for the process
3000 */
Amith Yamasani819f9282009-06-24 23:18:15 -07003001 public Uid.Proc getProcessStatsLocked(String name, int pid) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -07003002 int uid;
3003 if (mUidCache.containsKey(name)) {
3004 uid = mUidCache.get(name);
3005 } else {
Amith Yamasani819f9282009-06-24 23:18:15 -07003006 uid = Process.getUidForPid(pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07003007 mUidCache.put(name, uid);
3008 }
3009 Uid u = getUidStatsLocked(uid);
3010 return u.getProcessStatsLocked(name);
3011 }
3012
3013 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003014 * Retrieve the statistics object for a particular process, creating
3015 * if needed.
3016 */
3017 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
3018 Uid u = getUidStatsLocked(uid);
3019 return u.getPackageStatsLocked(pkg);
3020 }
3021
3022 /**
3023 * Retrieve the statistics object for a particular service, creating
3024 * if needed.
3025 */
3026 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
3027 Uid u = getUidStatsLocked(uid);
3028 return u.getServiceStatsLocked(pkg, name);
3029 }
3030
3031 public void writeLocked() {
3032 if ((mFile == null) || (mBackupFile == null)) {
3033 Log.w("BatteryStats", "writeLocked: no file associated with this instance");
3034 return;
3035 }
3036
3037 // Keep the old file around until we know the new one has
3038 // been successfully written.
3039 if (mFile.exists()) {
3040 if (mBackupFile.exists()) {
3041 mBackupFile.delete();
3042 }
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07003043 if (!mFile.renameTo(mBackupFile)) {
3044 Log.w("BatteryStats", "Failed to back up file before writing new stats");
3045 return;
3046 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003047 }
3048
3049 try {
3050 FileOutputStream stream = new FileOutputStream(mFile);
3051 Parcel out = Parcel.obtain();
3052 writeSummaryToParcel(out);
3053 stream.write(out.marshall());
3054 out.recycle();
3055
3056 stream.flush();
3057 stream.close();
3058 mBackupFile.delete();
3059
3060 mLastWriteTime = SystemClock.elapsedRealtime();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07003061 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003062 } catch (IOException e) {
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07003063 Log.w("BatteryStats", "Error writing battery statistics", e);
3064 }
3065 if (mFile.exists()) {
3066 if (!mFile.delete()) {
3067 Log.w(TAG, "Failed to delete mangled file " + mFile);
3068 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003069 }
3070 }
3071
3072 static byte[] readFully(FileInputStream stream) throws java.io.IOException {
3073 int pos = 0;
3074 int avail = stream.available();
3075 byte[] data = new byte[avail];
3076 while (true) {
3077 int amt = stream.read(data, pos, data.length-pos);
3078 //Log.i("foo", "Read " + amt + " bytes at " + pos
3079 // + " of avail " + data.length);
3080 if (amt <= 0) {
3081 //Log.i("foo", "**** FINISHED READING: pos=" + pos
3082 // + " len=" + data.length);
3083 return data;
3084 }
3085 pos += amt;
3086 avail = stream.available();
3087 if (avail > data.length-pos) {
3088 byte[] newData = new byte[pos+avail];
3089 System.arraycopy(data, 0, newData, 0, pos);
3090 data = newData;
3091 }
3092 }
3093 }
3094
3095 public void readLocked() {
3096 if ((mFile == null) || (mBackupFile == null)) {
3097 Log.w("BatteryStats", "readLocked: no file associated with this instance");
3098 return;
3099 }
3100
3101 mUidStats.clear();
3102
3103 FileInputStream stream = null;
3104 if (mBackupFile.exists()) {
3105 try {
3106 stream = new FileInputStream(mBackupFile);
3107 } catch (java.io.IOException e) {
3108 // We'll try for the normal settings file.
3109 }
3110 }
3111
3112 try {
3113 if (stream == null) {
3114 if (!mFile.exists()) {
3115 return;
3116 }
3117 stream = new FileInputStream(mFile);
3118 }
3119
3120 byte[] raw = readFully(stream);
3121 Parcel in = Parcel.obtain();
3122 in.unmarshall(raw, 0, raw.length);
3123 in.setDataPosition(0);
3124 stream.close();
3125
3126 readSummaryFromParcel(in);
3127 } catch(java.io.IOException e) {
3128 Log.e("BatteryStats", "Error reading battery statistics", e);
3129 }
3130 }
3131
3132 public int describeContents() {
3133 return 0;
3134 }
3135
3136 private void readSummaryFromParcel(Parcel in) {
3137 final int version = in.readInt();
3138 if (version != VERSION) {
3139 Log.w("BatteryStats", "readFromParcel: version got " + version
3140 + ", expected " + VERSION + "; erasing old stats");
3141 return;
3142 }
3143
3144 mStartCount = in.readInt();
3145 mBatteryUptime = in.readLong();
3146 mBatteryLastUptime = in.readLong();
3147 mBatteryRealtime = in.readLong();
3148 mBatteryLastRealtime = in.readLong();
3149 mUptime = in.readLong();
3150 mLastUptime = in.readLong();
3151 mRealtime = in.readLong();
3152 mLastRealtime = in.readLong();
Evan Millar633a1742009-04-02 16:36:33 -07003153 mDischargeStartLevel = in.readInt();
3154 mDischargeCurrentLevel = in.readInt();
The Android Open Source Project10592532009-03-18 17:39:46 -07003155
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003156 mStartCount++;
3157
3158 mScreenOn = false;
3159 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003160 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
3161 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
3162 }
3163 mInputEventCounter.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003164 mPhoneOn = false;
3165 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003166 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
3167 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
3168 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07003169 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003170 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
3171 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
3172 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003173 mWifiOn = false;
3174 mWifiOnTimer.readSummaryFromParcelLocked(in);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003175 mWifiRunning = false;
3176 mWifiRunningTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07003177 mBluetoothOn = false;
3178 mBluetoothOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003179
Evan Millarc64edde2009-04-18 12:26:32 -07003180 int NKW = in.readInt();
3181 for (int ikw = 0; ikw < NKW; ikw++) {
3182 if (in.readInt() != 0) {
3183 String kwltName = in.readString();
3184 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
3185 }
3186 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003187
3188 sNumSpeedSteps = in.readInt();
3189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003190 final int NU = in.readInt();
3191 for (int iu = 0; iu < NU; iu++) {
3192 int uid = in.readInt();
3193 Uid u = new Uid(uid);
3194 mUidStats.put(uid, u);
3195
Dianne Hackborn617f8772009-03-31 15:04:46 -07003196 u.mWifiTurnedOn = false;
3197 u.mWifiTurnedOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07003198 u.mFullWifiLockOut = false;
3199 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003200 u.mAudioTurnedOn = false;
3201 u.mAudioTurnedOnTimer.readSummaryFromParcelLocked(in);
3202 u.mVideoTurnedOn = false;
3203 u.mVideoTurnedOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07003204 u.mScanWifiLockOut = false;
3205 u.mScanWifiLockTimer.readSummaryFromParcelLocked(in);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003206 u.mWifiMulticastEnabled = false;
3207 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
3208
Dianne Hackborn617f8772009-03-31 15:04:46 -07003209 if (in.readInt() != 0) {
3210 if (u.mUserActivityCounters == null) {
3211 u.initUserActivityLocked();
3212 }
3213 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
3214 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
3215 }
3216 }
3217
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003218 int NW = in.readInt();
3219 for (int iw = 0; iw < NW; iw++) {
3220 String wlName = in.readString();
3221 if (in.readInt() != 0) {
3222 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
3223 }
3224 if (in.readInt() != 0) {
3225 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
3226 }
3227 if (in.readInt() != 0) {
3228 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
3229 }
3230 }
3231
3232 int NP = in.readInt();
3233 for (int is = 0; is < NP; is++) {
3234 int seNumber = in.readInt();
3235 if (in.readInt() != 0) {
3236 u.getSensorTimerLocked(seNumber, true)
3237 .readSummaryFromParcelLocked(in);
3238 }
3239 }
3240
3241 NP = in.readInt();
3242 for (int ip = 0; ip < NP; ip++) {
3243 String procName = in.readString();
3244 Uid.Proc p = u.getProcessStatsLocked(procName);
3245 p.mUserTime = p.mLoadedUserTime = in.readLong();
3246 p.mLastUserTime = in.readLong();
3247 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
3248 p.mLastSystemTime = in.readLong();
3249 p.mStarts = p.mLoadedStarts = in.readInt();
3250 p.mLastStarts = in.readInt();
3251 }
3252
3253 NP = in.readInt();
3254 for (int ip = 0; ip < NP; ip++) {
3255 String pkgName = in.readString();
3256 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
3257 p.mWakeups = p.mLoadedWakeups = in.readInt();
3258 p.mLastWakeups = in.readInt();
3259 final int NS = in.readInt();
3260 for (int is = 0; is < NS; is++) {
3261 String servName = in.readString();
3262 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
3263 s.mStartTime = s.mLoadedStartTime = in.readLong();
3264 s.mLastStartTime = in.readLong();
3265 s.mStarts = s.mLoadedStarts = in.readInt();
3266 s.mLastStarts = in.readInt();
3267 s.mLaunches = s.mLoadedLaunches = in.readInt();
3268 s.mLastLaunches = in.readInt();
3269 }
3270 }
3271
3272 u.mLoadedTcpBytesReceived = in.readLong();
3273 u.mLoadedTcpBytesSent = in.readLong();
3274 }
3275 }
3276
3277 /**
3278 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
3279 * disk. This format does not allow a lossless round-trip.
3280 *
3281 * @param out the Parcel to be written to.
3282 */
3283 public void writeSummaryToParcel(Parcel out) {
3284 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
3285 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
3286 final long NOW = getBatteryUptimeLocked(NOW_SYS);
3287 final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS);
3288
3289 out.writeInt(VERSION);
3290
3291 out.writeInt(mStartCount);
3292 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_TOTAL));
3293 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_CURRENT));
3294 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_TOTAL));
3295 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_CURRENT));
3296 out.writeLong(computeUptime(NOW_SYS, STATS_TOTAL));
3297 out.writeLong(computeUptime(NOW_SYS, STATS_CURRENT));
3298 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_TOTAL));
3299 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_CURRENT));
Evan Millar633a1742009-04-02 16:36:33 -07003300 out.writeInt(mDischargeStartLevel);
3301 out.writeInt(mDischargeCurrentLevel);
The Android Open Source Project10592532009-03-18 17:39:46 -07003302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003303
3304 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003305 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
3306 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
3307 }
3308 mInputEventCounter.writeSummaryFromParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003309 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003310 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
3311 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
3312 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07003313 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003314 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
3315 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
3316 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003317 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003318 mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07003319 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003320
Evan Millarc64edde2009-04-18 12:26:32 -07003321 out.writeInt(mKernelWakelockStats.size());
3322 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
3323 Timer kwlt = ent.getValue();
3324 if (kwlt != null) {
3325 out.writeInt(1);
3326 out.writeString(ent.getKey());
3327 ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL);
3328 } else {
3329 out.writeInt(0);
3330 }
3331 }
3332
Amith Yamasanie43530a2009-08-21 13:11:37 -07003333 out.writeInt(sNumSpeedSteps);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003334 final int NU = mUidStats.size();
3335 out.writeInt(NU);
3336 for (int iu = 0; iu < NU; iu++) {
3337 out.writeInt(mUidStats.keyAt(iu));
3338 Uid u = mUidStats.valueAt(iu);
The Android Open Source Project10592532009-03-18 17:39:46 -07003339
Dianne Hackborn617f8772009-03-31 15:04:46 -07003340 u.mWifiTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07003341 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Amith Yamasanic33fe6c2009-05-27 15:29:04 -07003342 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
3343 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07003344 u.mScanWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003345 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003346
Dianne Hackborn617f8772009-03-31 15:04:46 -07003347 if (u.mUserActivityCounters == null) {
3348 out.writeInt(0);
3349 } else {
3350 out.writeInt(1);
3351 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
3352 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
3353 }
3354 }
3355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003356 int NW = u.mWakelockStats.size();
3357 out.writeInt(NW);
3358 if (NW > 0) {
3359 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent
3360 : u.mWakelockStats.entrySet()) {
3361 out.writeString(ent.getKey());
3362 Uid.Wakelock wl = ent.getValue();
3363 if (wl.mTimerFull != null) {
3364 out.writeInt(1);
3365 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL);
3366 } else {
3367 out.writeInt(0);
3368 }
3369 if (wl.mTimerPartial != null) {
3370 out.writeInt(1);
3371 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL);
3372 } else {
3373 out.writeInt(0);
3374 }
3375 if (wl.mTimerWindow != null) {
3376 out.writeInt(1);
3377 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL);
3378 } else {
3379 out.writeInt(0);
3380 }
3381 }
3382 }
3383
3384 int NSE = u.mSensorStats.size();
3385 out.writeInt(NSE);
3386 if (NSE > 0) {
3387 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent
3388 : u.mSensorStats.entrySet()) {
3389 out.writeInt(ent.getKey());
3390 Uid.Sensor se = ent.getValue();
3391 if (se.mTimer != null) {
3392 out.writeInt(1);
3393 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL);
3394 } else {
3395 out.writeInt(0);
3396 }
3397 }
3398 }
3399
3400 int NP = u.mProcessStats.size();
3401 out.writeInt(NP);
3402 if (NP > 0) {
3403 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent
3404 : u.mProcessStats.entrySet()) {
3405 out.writeString(ent.getKey());
3406 Uid.Proc ps = ent.getValue();
3407 out.writeLong(ps.mUserTime);
3408 out.writeLong(ps.mUserTime - ps.mLoadedUserTime);
3409 out.writeLong(ps.mSystemTime);
3410 out.writeLong(ps.mSystemTime - ps.mLoadedSystemTime);
3411 out.writeInt(ps.mStarts);
3412 out.writeInt(ps.mStarts - ps.mLoadedStarts);
3413 }
3414 }
3415
3416 NP = u.mPackageStats.size();
3417 out.writeInt(NP);
3418 if (NP > 0) {
3419 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
3420 : u.mPackageStats.entrySet()) {
3421 out.writeString(ent.getKey());
3422 Uid.Pkg ps = ent.getValue();
3423 out.writeInt(ps.mWakeups);
3424 out.writeInt(ps.mWakeups - ps.mLoadedWakeups);
3425 final int NS = ps.mServiceStats.size();
3426 out.writeInt(NS);
3427 if (NS > 0) {
3428 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
3429 : ps.mServiceStats.entrySet()) {
3430 out.writeString(sent.getKey());
3431 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
3432 long time = ss.getStartTimeToNowLocked(NOW);
3433 out.writeLong(time);
3434 out.writeLong(time - ss.mLoadedStartTime);
3435 out.writeInt(ss.mStarts);
3436 out.writeInt(ss.mStarts - ss.mLoadedStarts);
3437 out.writeInt(ss.mLaunches);
3438 out.writeInt(ss.mLaunches - ss.mLoadedLaunches);
3439 }
3440 }
3441 }
3442 }
3443
3444 out.writeLong(u.getTcpBytesReceived(STATS_TOTAL));
3445 out.writeLong(u.getTcpBytesSent(STATS_TOTAL));
3446 }
3447 }
3448
3449 public void readFromParcel(Parcel in) {
3450 readFromParcelLocked(in);
3451 }
3452
3453 void readFromParcelLocked(Parcel in) {
3454 int magic = in.readInt();
3455 if (magic != MAGIC) {
3456 throw new ParcelFormatException("Bad magic number");
3457 }
3458
3459 mStartCount = in.readInt();
3460 mBatteryUptime = in.readLong();
3461 mBatteryLastUptime = in.readLong();
3462 mBatteryRealtime = in.readLong();
3463 mBatteryLastRealtime = in.readLong();
3464 mScreenOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003465 mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003466 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07003467 mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003468 }
3469 mInputEventCounter = new Counter(mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003470 mPhoneOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003471 mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003472 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07003473 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003474 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07003475 mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003476 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07003477 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003478 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003479 mWifiOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003480 mWifiOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003481 mWifiRunning = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003482 mWifiRunningTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07003483 mBluetoothOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003484 mBluetoothOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003485 mUptime = in.readLong();
3486 mUptimeStart = in.readLong();
3487 mLastUptime = in.readLong();
3488 mRealtime = in.readLong();
3489 mRealtimeStart = in.readLong();
3490 mLastRealtime = in.readLong();
3491 mOnBattery = in.readInt() != 0;
3492 mOnBatteryInternal = false; // we are no longer really running.
3493 mTrackBatteryPastUptime = in.readLong();
3494 mTrackBatteryUptimeStart = in.readLong();
3495 mTrackBatteryPastRealtime = in.readLong();
3496 mTrackBatteryRealtimeStart = in.readLong();
3497 mUnpluggedBatteryUptime = in.readLong();
3498 mUnpluggedBatteryRealtime = in.readLong();
Evan Millar633a1742009-04-02 16:36:33 -07003499 mDischargeStartLevel = in.readInt();
3500 mDischargeCurrentLevel = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003501 mLastWriteTime = in.readLong();
3502
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003503 mMobileDataRx[STATS_LAST] = in.readLong();
3504 mMobileDataRx[STATS_UNPLUGGED] = -1;
3505 mMobileDataTx[STATS_LAST] = in.readLong();
3506 mMobileDataTx[STATS_UNPLUGGED] = -1;
3507 mTotalDataRx[STATS_LAST] = in.readLong();
3508 mTotalDataRx[STATS_UNPLUGGED] = -1;
3509 mTotalDataTx[STATS_LAST] = in.readLong();
3510 mTotalDataTx[STATS_UNPLUGGED] = -1;
3511
3512 mRadioDataUptime = in.readLong();
3513 mRadioDataStart = -1;
3514
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07003515 mBluetoothPingCount = in.readInt();
3516 mBluetoothPingStart = -1;
3517
Evan Millarc64edde2009-04-18 12:26:32 -07003518 mKernelWakelockStats.clear();
3519 int NKW = in.readInt();
3520 for (int ikw = 0; ikw < NKW; ikw++) {
3521 if (in.readInt() != 0) {
3522 String wakelockName = in.readString();
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003523 in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel
Evan Millarc64edde2009-04-18 12:26:32 -07003524 SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in);
3525 mKernelWakelockStats.put(wakelockName, kwlt);
3526 }
3527 }
3528
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003529 mPartialTimers.clear();
3530 mFullTimers.clear();
3531 mWindowTimers.clear();
3532
Amith Yamasanie43530a2009-08-21 13:11:37 -07003533 sNumSpeedSteps = in.readInt();
3534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003535 int numUids = in.readInt();
3536 mUidStats.clear();
3537 for (int i = 0; i < numUids; i++) {
3538 int uid = in.readInt();
3539 Uid u = new Uid(uid);
3540 u.readFromParcelLocked(mUnpluggables, in);
3541 mUidStats.append(uid, u);
3542 }
3543 }
3544
3545 public void writeToParcel(Parcel out, int flags) {
3546 writeToParcelLocked(out, flags);
3547 }
3548
3549 @SuppressWarnings("unused")
3550 void writeToParcelLocked(Parcel out, int flags) {
3551 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
3552 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
3553 final long batteryUptime = getBatteryUptimeLocked(uSecUptime);
3554 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
3555
3556 out.writeInt(MAGIC);
3557 out.writeInt(mStartCount);
3558 out.writeLong(mBatteryUptime);
3559 out.writeLong(mBatteryLastUptime);
3560 out.writeLong(mBatteryRealtime);
3561 out.writeLong(mBatteryLastRealtime);
3562 mScreenOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003563 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
3564 mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime);
3565 }
3566 mInputEventCounter.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003567 mPhoneOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003568 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
3569 mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
3570 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07003571 mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003572 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
3573 mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime);
3574 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003575 mWifiOnTimer.writeToParcel(out, batteryRealtime);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003576 mWifiRunningTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003577 mBluetoothOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003578 out.writeLong(mUptime);
3579 out.writeLong(mUptimeStart);
3580 out.writeLong(mLastUptime);
3581 out.writeLong(mRealtime);
3582 out.writeLong(mRealtimeStart);
3583 out.writeLong(mLastRealtime);
3584 out.writeInt(mOnBattery ? 1 : 0);
3585 out.writeLong(batteryUptime);
3586 out.writeLong(mTrackBatteryUptimeStart);
3587 out.writeLong(batteryRealtime);
3588 out.writeLong(mTrackBatteryRealtimeStart);
3589 out.writeLong(mUnpluggedBatteryUptime);
3590 out.writeLong(mUnpluggedBatteryRealtime);
Evan Millar633a1742009-04-02 16:36:33 -07003591 out.writeInt(mDischargeStartLevel);
3592 out.writeInt(mDischargeCurrentLevel);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003593 out.writeLong(mLastWriteTime);
3594
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003595 out.writeLong(getMobileTcpBytesReceived(STATS_UNPLUGGED));
3596 out.writeLong(getMobileTcpBytesSent(STATS_UNPLUGGED));
3597 out.writeLong(getTotalTcpBytesReceived(STATS_UNPLUGGED));
3598 out.writeLong(getTotalTcpBytesSent(STATS_UNPLUGGED));
3599
3600 // Write radio uptime for data
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07003601 out.writeLong(getRadioDataUptime());
3602
3603 out.writeInt(getBluetoothPingCount());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003604
Evan Millarc64edde2009-04-18 12:26:32 -07003605 out.writeInt(mKernelWakelockStats.size());
3606 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
3607 SamplingTimer kwlt = ent.getValue();
3608 if (kwlt != null) {
3609 out.writeInt(1);
3610 out.writeString(ent.getKey());
3611 Timer.writeTimerToParcel(out, kwlt, batteryRealtime);
3612 } else {
3613 out.writeInt(0);
3614 }
3615 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07003616
3617 out.writeInt(sNumSpeedSteps);
3618
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003619 int size = mUidStats.size();
3620 out.writeInt(size);
3621 for (int i = 0; i < size; i++) {
3622 out.writeInt(mUidStats.keyAt(i));
3623 Uid uid = mUidStats.valueAt(i);
3624
3625 uid.writeToParcelLocked(out, batteryRealtime);
3626 }
3627 }
3628
3629 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
3630 new Parcelable.Creator<BatteryStatsImpl>() {
3631 public BatteryStatsImpl createFromParcel(Parcel in) {
3632 return new BatteryStatsImpl(in);
3633 }
3634
3635 public BatteryStatsImpl[] newArray(int size) {
3636 return new BatteryStatsImpl[size];
3637 }
3638 };
3639
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003640 public void dumpLocked(PrintWriter pw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003641 if (DEBUG) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003642 Printer pr = new PrintWriterPrinter(pw);
3643 pr.println("*** Screen timer:");
3644 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07003645 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003646 pr.println("*** Screen brightness #" + i + ":");
3647 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07003648 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003649 pr.println("*** Input event counter:");
3650 mInputEventCounter.logState(pr, " ");
3651 pr.println("*** Phone timer:");
3652 mPhoneOnTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07003653 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003654 pr.println("*** Signal strength #" + i + ":");
3655 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07003656 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07003657 pr.println("*** Signal scanning :");
3658 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07003659 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003660 pr.println("*** Data connection type #" + i + ":");
3661 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07003662 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003663 pr.println("*** Wifi timer:");
3664 mWifiOnTimer.logState(pr, " ");
3665 pr.println("*** WifiRunning timer:");
3666 mWifiRunningTimer.logState(pr, " ");
3667 pr.println("*** Bluetooth timer:");
3668 mBluetoothOnTimer.logState(pr, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003669 }
3670 super.dumpLocked(pw);
3671 }
3672}