blob: e8356a2c641518106cbf10c67c224ebd33bd0023 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.os;
18
19import android.os.BatteryStats;
20import android.os.NetStat;
21import android.os.Parcel;
22import android.os.ParcelFormatException;
23import android.os.Parcelable;
Evan Millarc64edde2009-04-18 12:26:32 -070024import android.os.Process;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import android.os.SystemClock;
Dianne Hackborn627bba72009-03-24 22:32:56 -070026import android.telephony.TelephonyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import android.util.Log;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070028import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.util.Printer;
30import android.util.SparseArray;
31
32import java.io.File;
33import java.io.FileInputStream;
34import java.io.FileOutputStream;
35import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070036import java.io.PrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import java.util.ArrayList;
38import java.util.HashMap;
Evan Millarc64edde2009-04-18 12:26:32 -070039import java.util.HashSet;
40import java.util.Iterator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import java.util.Map;
Evan Millarc64edde2009-04-18 12:26:32 -070042import java.util.Set;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043
44/**
45 * All information we are collecting about things that can happen that impact
46 * battery life. All times are represented in microseconds except where indicated
47 * otherwise.
48 */
49public final class BatteryStatsImpl extends BatteryStats {
50 private static final String TAG = "BatteryStatsImpl";
51 private static final boolean DEBUG = false;
52
53 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
54 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
55
56 // Current on-disk Parcel version
Evan Millarc64edde2009-04-18 12:26:32 -070057 private static final int VERSION = 34;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058
59 private final File mFile;
60 private final File mBackupFile;
61
62 /**
63 * The statistics we have collected organized by uids.
64 */
65 final SparseArray<BatteryStatsImpl.Uid> mUidStats =
66 new SparseArray<BatteryStatsImpl.Uid>();
67
68 // A set of pools of currently active timers. When a timer is queried, we will divide the
69 // elapsed time by the number of active timers to arrive at that timer's share of the time.
70 // In order to do this, we must refresh each timer whenever the number of active timers
71 // changes.
Evan Millarc64edde2009-04-18 12:26:32 -070072 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>();
73 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>();
74 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>();
75 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers
76 = new SparseArray<ArrayList<StopwatchTimer>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077
78 // These are the objects that will want to do something when the device
79 // is unplugged from power.
80 final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>();
81
82 int mStartCount;
83
84 long mBatteryUptime;
85 long mBatteryLastUptime;
86 long mBatteryRealtime;
87 long mBatteryLastRealtime;
88
89 long mUptime;
90 long mUptimeStart;
91 long mLastUptime;
92 long mRealtime;
93 long mRealtimeStart;
94 long mLastRealtime;
95
96 boolean mScreenOn;
Evan Millarc64edde2009-04-18 12:26:32 -070097 StopwatchTimer mScreenOnTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098
Dianne Hackborn617f8772009-03-31 15:04:46 -070099 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700100 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Dianne Hackborn617f8772009-03-31 15:04:46 -0700101
102 Counter mInputEventCounter;
103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700105 StopwatchTimer mPhoneOnTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106
Dianne Hackborn627bba72009-03-24 22:32:56 -0700107 int mPhoneSignalStrengthBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700108 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
109 new StopwatchTimer[NUM_SIGNAL_STRENGTH_BINS];
Dianne Hackborn627bba72009-03-24 22:32:56 -0700110
111 int mPhoneDataConnectionType = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700112 final StopwatchTimer[] mPhoneDataConnectionsTimer =
113 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Dianne Hackborn627bba72009-03-24 22:32:56 -0700114
The Android Open Source Project10592532009-03-18 17:39:46 -0700115 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700116 StopwatchTimer mWifiOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700117 int mWifiOnUid = -1;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700118
119 boolean mWifiRunning;
Evan Millarc64edde2009-04-18 12:26:32 -0700120 StopwatchTimer mWifiRunningTimer;
The Android Open Source Project10592532009-03-18 17:39:46 -0700121
122 boolean mBluetoothOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700123 StopwatchTimer mBluetoothOnTimer;
The Android Open Source Project10592532009-03-18 17:39:46 -0700124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125 /**
126 * These provide time bases that discount the time the device is plugged
127 * in to power.
128 */
129 boolean mOnBattery;
130 boolean mOnBatteryInternal;
131 long mTrackBatteryPastUptime;
132 long mTrackBatteryUptimeStart;
133 long mTrackBatteryPastRealtime;
134 long mTrackBatteryRealtimeStart;
135
136 long mUnpluggedBatteryUptime;
137 long mUnpluggedBatteryRealtime;
138
The Android Open Source Project10592532009-03-18 17:39:46 -0700139 /*
140 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
141 */
Evan Millar633a1742009-04-02 16:36:33 -0700142 int mDischargeStartLevel;
143 int mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -0700144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 long mLastWriteTime = 0; // Milliseconds
Evan Millarc64edde2009-04-18 12:26:32 -0700146
147 /*
148 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
149 */
150 private final HashMap<String, SamplingTimer> mKernelWakelockStats =
151 new HashMap<String, SamplingTimer>();
152
153 public Map<String, ? extends SamplingTimer> getKernelWakelockStats() {
154 return mKernelWakelockStats;
155 }
156
157 private static int sKernelWakelockUpdateVersion = 0;
158
159 private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
160 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name
161 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count
162 Process.PROC_TAB_TERM,
163 Process.PROC_TAB_TERM,
164 Process.PROC_TAB_TERM,
165 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime
166 };
167
168 private final String[] mProcWakelocksName = new String[3];
169 private final long[] mProcWakelocksData = new long[3];
170
171 /*
172 * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added
173 * to mKernelWakelockStats.
174 */
175 private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
176 new HashMap<String, KernelWakelockStats>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800177
178 // For debugging
179 public BatteryStatsImpl() {
180 mFile = mBackupFile = null;
181 }
182
183 public static interface Unpluggable {
184 void unplug(long batteryUptime, long batteryRealtime);
185 void plug(long batteryUptime, long batteryRealtime);
186 }
187
188 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700189 * State for keeping track of counting information.
190 */
191 public static final class Counter extends BatteryStats.Counter implements Unpluggable {
192 int mCount;
193 int mLoadedCount;
194 int mLastCount;
195 int mUnpluggedCount;
196 int mPluggedCount;
197
198 Counter(ArrayList<Unpluggable> unpluggables, Parcel in) {
199 mPluggedCount = mCount = in.readInt();
200 mLoadedCount = in.readInt();
201 mLastCount = in.readInt();
202 mUnpluggedCount = in.readInt();
203 unpluggables.add(this);
204 }
205
206 Counter(ArrayList<Unpluggable> unpluggables) {
207 unpluggables.add(this);
208 }
209
210 public void writeToParcel(Parcel out) {
211 out.writeInt(mCount);
212 out.writeInt(mLoadedCount);
213 out.writeInt(mLastCount);
214 out.writeInt(mUnpluggedCount);
215 }
216
217 public void unplug(long batteryUptime, long batteryRealtime) {
218 mUnpluggedCount = mCount = mPluggedCount;
219 }
220
221 public void plug(long batteryUptime, long batteryRealtime) {
222 mPluggedCount = mCount;
223 }
224
225 /**
226 * Writes a possibly null Counter to a Parcel.
227 *
228 * @param out the Parcel to be written to.
229 * @param counter a Counter, or null.
230 */
231 public static void writeCounterToParcel(Parcel out, Counter counter) {
232 if (counter == null) {
233 out.writeInt(0); // indicates null
234 return;
235 }
236 out.writeInt(1); // indicates non-null
237
238 counter.writeToParcel(out);
239 }
240
241 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700242 public int getCountLocked(int which) {
Dianne Hackborn617f8772009-03-31 15:04:46 -0700243 int val;
244 if (which == STATS_LAST) {
245 val = mLastCount;
246 } else {
247 val = mCount;
248 if (which == STATS_UNPLUGGED) {
249 val -= mUnpluggedCount;
250 } else if (which != STATS_TOTAL) {
251 val -= mLoadedCount;
252 }
253 }
254
255 return val;
256 }
257
258 public void logState(Printer pw, String prefix) {
259 pw.println(prefix + "mCount=" + mCount
260 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
261 + " mUnpluggedCount=" + mUnpluggedCount
262 + " mPluggedCount=" + mPluggedCount);
263 }
264
265 void stepLocked() {
266 mCount++;
267 }
268
269 void writeSummaryFromParcelLocked(Parcel out) {
270 out.writeInt(mCount);
271 out.writeInt(mCount - mLoadedCount);
272 }
273
274 void readSummaryFromParcelLocked(Parcel in) {
275 mCount = mLoadedCount = in.readInt();
276 mLastCount = in.readInt();
277 mUnpluggedCount = mPluggedCount = mCount;
278 }
279 }
280
281 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800282 * State for keeping track of timing information.
283 */
Evan Millarc64edde2009-04-18 12:26:32 -0700284 public static abstract class Timer extends BatteryStats.Timer implements Unpluggable {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285 final int mType;
Evan Millarc64edde2009-04-18 12:26:32 -0700286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800287
288 int mCount;
289 int mLoadedCount;
290 int mLastCount;
291 int mUnpluggedCount;
292
293 // Times are in microseconds for better accuracy when dividing by the
294 // lock count, and are in "battery realtime" units.
295
296 /**
297 * The total time we have accumulated since the start of the original
298 * boot, to the last time something interesting happened in the
299 * current run.
300 */
301 long mTotalTime;
302
303 /**
304 * The total time we loaded for the previous runs. Subtract this from
305 * mTotalTime to find the time for the current run of the system.
306 */
307 long mLoadedTime;
308
309 /**
310 * The run time of the last run of the system, as loaded from the
311 * saved data.
312 */
313 long mLastTime;
314
315 /**
316 * The value of mTotalTime when unplug() was last called. Subtract
317 * this from mTotalTime to find the time since the last unplug from
318 * power.
319 */
320 long mUnpluggedTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800321
Evan Millarc64edde2009-04-18 12:26:32 -0700322 Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 mType = type;
Evan Millarc64edde2009-04-18 12:26:32 -0700324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325 mCount = in.readInt();
326 mLoadedCount = in.readInt();
327 mLastCount = in.readInt();
328 mUnpluggedCount = in.readInt();
329 mTotalTime = in.readLong();
330 mLoadedTime = in.readLong();
331 mLastTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332 mUnpluggedTime = in.readLong();
333 unpluggables.add(this);
334 }
335
Evan Millarc64edde2009-04-18 12:26:32 -0700336 Timer(int type, ArrayList<Unpluggable> unpluggables) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 mType = type;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 unpluggables.add(this);
339 }
Evan Millarc64edde2009-04-18 12:26:32 -0700340
341 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
342
343 protected abstract int computeCurrentCountLocked();
344
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800345
346 public void writeToParcel(Parcel out, long batteryRealtime) {
347 out.writeInt(mCount);
348 out.writeInt(mLoadedCount);
349 out.writeInt(mLastCount);
350 out.writeInt(mUnpluggedCount);
351 out.writeLong(computeRunTimeLocked(batteryRealtime));
352 out.writeLong(mLoadedTime);
353 out.writeLong(mLastTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354 out.writeLong(mUnpluggedTime);
355 }
356
357 public void unplug(long batteryUptime, long batteryRealtime) {
358 if (DEBUG && mType < 0) {
359 Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime
360 + " old mUnpluggedTime=" + mUnpluggedTime
361 + " old mUnpluggedCount=" + mUnpluggedCount);
362 }
363 mUnpluggedTime = computeRunTimeLocked(batteryRealtime);
364 mUnpluggedCount = mCount;
365 if (DEBUG && mType < 0) {
366 Log.v(TAG, "unplug #" + mType
367 + ": new mUnpluggedTime=" + mUnpluggedTime
368 + " new mUnpluggedCount=" + mUnpluggedCount);
369 }
370 }
371
372 public void plug(long batteryUptime, long batteryRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -0700373 if (DEBUG && mType < 0) {
374 Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime
375 + " old mTotalTime=" + mTotalTime);
376 }
377 mTotalTime = computeRunTimeLocked(batteryRealtime);
378 mCount = computeCurrentCountLocked();
379 if (DEBUG && mType < 0) {
380 Log.v(TAG, "plug #" + mType
381 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 }
383 }
384
385 /**
386 * Writes a possibly null Timer to a Parcel.
387 *
388 * @param out the Parcel to be written to.
389 * @param timer a Timer, or null.
390 */
391 public static void writeTimerToParcel(Parcel out, Timer timer,
392 long batteryRealtime) {
393 if (timer == null) {
394 out.writeInt(0); // indicates null
395 return;
396 }
397 out.writeInt(1); // indicates non-null
398
399 timer.writeToParcel(out, batteryRealtime);
400 }
401
402 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700403 public long getTotalTimeLocked(long batteryRealtime, int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 long val;
405 if (which == STATS_LAST) {
406 val = mLastTime;
407 } else {
408 val = computeRunTimeLocked(batteryRealtime);
409 if (which == STATS_UNPLUGGED) {
410 val -= mUnpluggedTime;
411 } else if (which != STATS_TOTAL) {
412 val -= mLoadedTime;
413 }
414 }
415
416 return val;
417 }
418
419 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700420 public int getCountLocked(int which) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421 int val;
422 if (which == STATS_LAST) {
423 val = mLastCount;
424 } else {
Evan Millarc64edde2009-04-18 12:26:32 -0700425 val = computeCurrentCountLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426 if (which == STATS_UNPLUGGED) {
427 val -= mUnpluggedCount;
428 } else if (which != STATS_TOTAL) {
429 val -= mLoadedCount;
430 }
431 }
432
433 return val;
434 }
435
Dianne Hackborn627bba72009-03-24 22:32:56 -0700436 public void logState(Printer pw, String prefix) {
Evan Millarc64edde2009-04-18 12:26:32 -0700437 pw.println(prefix + " mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800438 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
439 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700440 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700442 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -0700444 }
445
446
447 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
448 long runTime = computeRunTimeLocked(batteryRealtime);
449 // Divide by 1000 for backwards compatibility
450 out.writeLong((runTime + 500) / 1000);
451 out.writeLong(((runTime - mLoadedTime) + 500) / 1000);
452 out.writeInt(mCount);
453 out.writeInt(mCount - mLoadedCount);
454 }
455
456 void readSummaryFromParcelLocked(Parcel in) {
457 // Multiply by 1000 for backwards compatibility
458 mTotalTime = mLoadedTime = in.readLong() * 1000;
459 mLastTime = in.readLong() * 1000;
460 mUnpluggedTime = mTotalTime;
461 mCount = mLoadedCount = in.readInt();
462 mLastCount = in.readInt();
463 mUnpluggedCount = mCount;
464 }
465 }
466
467 public static final class SamplingTimer extends Timer {
468
469 /**
470 * The most recent reported count from /proc/wakelocks.
471 */
472 int mCurrentReportedCount;
473
474 /**
475 * The reported count from /proc/wakelocks when unplug() was last
476 * called.
477 */
478 int mUnpluggedReportedCount;
479
480 /**
481 * The most recent reported total_time from /proc/wakelocks.
482 */
483 long mCurrentReportedTotalTime;
484
485
486 /**
487 * The reported total_time from /proc/wakelocks when unplug() was last
488 * called.
489 */
490 long mUnpluggedReportedTotalTime;
491
492 /**
493 * Whether we are currently in a discharge cycle.
494 */
495 boolean mInDischarge;
496
497 /**
498 * Whether we are currently recording reported values.
499 */
500 boolean mTrackingReportedValues;
501
502 /*
503 * A sequnce counter, incremented once for each update of the stats.
504 */
505 int mUpdateVersion;
506
507 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) {
508 super(0, unpluggables, in);
509 mCurrentReportedCount = in.readInt();
510 mUnpluggedReportedCount = in.readInt();
511 mCurrentReportedTotalTime = in.readLong();
512 mUnpluggedReportedTotalTime = in.readLong();
513 mTrackingReportedValues = in.readInt() == 1;
514 mInDischarge = inDischarge;
515 }
516
517 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge,
518 boolean trackReportedValues) {
519 super(0, unpluggables);
520 mTrackingReportedValues = trackReportedValues;
521 mInDischarge = inDischarge;
522 }
523
524 public void setStale() {
525 mTrackingReportedValues = false;
526 mUnpluggedReportedTotalTime = 0;
527 mUnpluggedReportedCount = 0;
528 }
529
530 public void setUpdateVersion(int version) {
531 mUpdateVersion = version;
532 }
533
534 public int getUpdateVersion() {
535 return mUpdateVersion;
536 }
537
538 public void updateCurrentReportedCount(int count) {
539 if (mInDischarge && mUnpluggedReportedCount == 0) {
540 // Updating the reported value for the first time.
541 mUnpluggedReportedCount = count;
542 // If we are receiving an update update mTrackingReportedValues;
543 mTrackingReportedValues = true;
544 }
545 mCurrentReportedCount = count;
546 }
547
548 public void updateCurrentReportedTotalTime(long totalTime) {
549 if (mInDischarge && mUnpluggedReportedTotalTime == 0) {
550 // Updating the reported value for the first time.
551 mUnpluggedReportedTotalTime = totalTime;
552 // If we are receiving an update update mTrackingReportedValues;
553 mTrackingReportedValues = true;
554 }
555 mCurrentReportedTotalTime = totalTime;
556 }
557
558 public void unplug(long batteryUptime, long batteryRealtime) {
559 super.unplug(batteryUptime, batteryRealtime);
560 if (mTrackingReportedValues) {
561 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
562 mUnpluggedReportedCount = mCurrentReportedCount;
563 }
564 mInDischarge = true;
565 }
566
567 public void plug(long batteryUptime, long batteryRealtime) {
568 super.plug(batteryUptime, batteryRealtime);
569 mInDischarge = false;
570 }
571
572 public void logState(Printer pw, String prefix) {
573 super.logState(pw, prefix);
574 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
575 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
576 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
577 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
578 }
579
580 protected long computeRunTimeLocked(long curBatteryRealtime) {
581 return mTotalTime + (mInDischarge && mTrackingReportedValues
582 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
583 }
584
585 protected int computeCurrentCountLocked() {
586 return mCount + (mInDischarge && mTrackingReportedValues
587 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
588 }
589
590 public void writeToParcel(Parcel out, long batteryRealtime) {
591 super.writeToParcel(out, batteryRealtime);
592 out.writeInt(mCurrentReportedCount);
593 out.writeInt(mUnpluggedReportedCount);
594 out.writeLong(mCurrentReportedTotalTime);
595 out.writeLong(mUnpluggedReportedTotalTime);
596 out.writeInt(mTrackingReportedValues ? 1 : 0);
597 }
598
599 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
600 super.writeSummaryFromParcelLocked(out, batteryRealtime);
601 out.writeLong(mCurrentReportedTotalTime);
602 out.writeInt(mCurrentReportedCount);
603 out.writeInt(mTrackingReportedValues ? 1 : 0);
604 }
605
606 void readSummaryFromParcelLocked(Parcel in) {
607 super.readSummaryFromParcelLocked(in);
608 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
609 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
610 mTrackingReportedValues = in.readInt() == 1;
611 }
612 }
613
614 /**
615 * State for keeping track of timing information.
616 */
617 public static final class StopwatchTimer extends Timer {
618 final ArrayList<StopwatchTimer> mTimerPool;
619 int mNesting;
620
621
622 /**
623 * The last time at which we updated the timer. If mNesting is > 0,
624 * subtract this from the current battery time to find the amount of
625 * time we have been running since we last computed an update.
626 */
627 long mUpdateTime;
628
629 /**
630 * The total time at which the timer was acquired, to determine if
631 * was actually held for an interesting duration.
632 */
633 long mAcquireTime;
634
635
636 StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool,
637 ArrayList<Unpluggable> unpluggables, Parcel in) {
638 super(type, unpluggables, in);
639 mTimerPool = timerPool;
640 mUpdateTime = in.readLong();
641 }
642
643 StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool,
644 ArrayList<Unpluggable> unpluggables) {
645 super(type, unpluggables);
646 mTimerPool = timerPool;
647 }
648
649 public void writeToParcel(Parcel out, long batteryRealtime) {
650 super.writeToParcel(out, batteryRealtime);
651 out.writeLong(mUpdateTime);
652 }
653
654 public void plug(long batteryUptime, long batteryRealtime) {
655 if (mNesting > 0) {
656 if (DEBUG && mType < 0) {
657 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
658 }
659 super.plug(batteryUptime, batteryRealtime);
660 mUpdateTime = batteryRealtime;
661 if (DEBUG && mType < 0) {
662 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
663 }
664 }
665 }
666
667 public void logState(Printer pw, String prefix) {
668 super.logState(pw, prefix);
669 pw.println(prefix + "mNesting=" + mNesting + "mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800670 + " mAcquireTime=" + mAcquireTime);
671 }
672
673 void startRunningLocked(BatteryStatsImpl stats) {
674 if (mNesting++ == 0) {
675 mUpdateTime = stats.getBatteryRealtimeLocked(
676 SystemClock.elapsedRealtime() * 1000);
677 if (mTimerPool != null) {
678 // Accumulate time to all currently active timers before adding
679 // this new one to the pool.
680 refreshTimersLocked(stats, mTimerPool);
681 // Add this timer to the active pool
682 mTimerPool.add(this);
683 }
684 // Increment the count
685 mCount++;
686 mAcquireTime = mTotalTime;
687 if (DEBUG && mType < 0) {
688 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
689 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
690 + " mAcquireTime=" + mAcquireTime);
691 }
692 }
693 }
694
695 void stopRunningLocked(BatteryStatsImpl stats) {
696 // Ignore attempt to stop a timer that isn't running
697 if (mNesting == 0) {
698 return;
699 }
700 if (--mNesting == 0) {
701 if (mTimerPool != null) {
702 // Accumulate time to all active counters, scaled by the total
703 // active in the pool, before taking this one out of the pool.
704 refreshTimersLocked(stats, mTimerPool);
705 // Remove this timer from the active pool
706 mTimerPool.remove(this);
707 } else {
708 final long realtime = SystemClock.elapsedRealtime() * 1000;
709 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
710 mNesting = 1;
711 mTotalTime = computeRunTimeLocked(batteryRealtime);
712 mNesting = 0;
713 }
714
715 if (DEBUG && mType < 0) {
716 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
717 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
718 + " mAcquireTime=" + mAcquireTime);
719 }
720
721 if (mTotalTime == mAcquireTime) {
722 // If there was no change in the time, then discard this
723 // count. A somewhat cheezy strategy, but hey.
724 mCount--;
725 }
726 }
727 }
728
729 // Update the total time for all other running Timers with the same type as this Timer
730 // due to a change in timer count
731 private static void refreshTimersLocked(final BatteryStatsImpl stats,
Evan Millarc64edde2009-04-18 12:26:32 -0700732 final ArrayList<StopwatchTimer> pool) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800733 final long realtime = SystemClock.elapsedRealtime() * 1000;
734 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
735 final int N = pool.size();
736 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -0700737 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800738 long heldTime = batteryRealtime - t.mUpdateTime;
739 if (heldTime > 0) {
740 t.mTotalTime += heldTime / N;
741 }
742 t.mUpdateTime = batteryRealtime;
743 }
744 }
745
Evan Millarc64edde2009-04-18 12:26:32 -0700746 @Override
747 protected long computeRunTimeLocked(long curBatteryRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748 return mTotalTime + (mNesting > 0
749 ? (curBatteryRealtime - mUpdateTime)
750 / (mTimerPool != null ? mTimerPool.size() : 1)
751 : 0);
752 }
753
Evan Millarc64edde2009-04-18 12:26:32 -0700754 @Override
755 protected int computeCurrentCountLocked() {
756 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800757 }
758
759 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -0700760 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800761 mNesting = 0;
762 }
763 }
764
Evan Millarc64edde2009-04-18 12:26:32 -0700765 private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
766
767 byte[] buffer = new byte[4096];
768 int len;
769
770 try {
771 FileInputStream is = new FileInputStream("/proc/wakelocks");
772 len = is.read(buffer);
773 is.close();
774
775 if (len > 0) {
776 int i;
777 for (i=0; i<len; i++) {
778 if (buffer[i] == '\0') {
779 len = i;
780 break;
781 }
782 }
783 }
784 } catch (java.io.FileNotFoundException e) {
785 return null;
786 } catch (java.io.IOException e) {
787 return null;
788 }
789
790 return parseProcWakelocks(buffer, len);
791 }
792
793 private final Map<String, KernelWakelockStats> parseProcWakelocks(
794 byte[] wlBuffer, int len) {
795 String name;
796 int count;
797 long totalTime;
798 int startIndex, endIndex;
799 int numUpdatedWlNames = 0;
800
801 // Advance past the first line.
802 int i;
803 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++);
804 startIndex = endIndex = i + 1;
805
806 synchronized(this) {
807 Map<String, KernelWakelockStats> m = mProcWakelockFileStats;
808
809 sKernelWakelockUpdateVersion++;
810 while (endIndex < len) {
811 for (endIndex=startIndex;
812 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
813 endIndex++);
814 endIndex++; // endIndex is an exclusive upper bound.
815
816 String[] nameStringArray = mProcWakelocksName;
817 long[] wlData = mProcWakelocksData;
818 Process.parseProcLine(wlBuffer, startIndex, endIndex, PROC_WAKELOCKS_FORMAT,
819 nameStringArray, wlData, null);
820
821 name = nameStringArray[0];
822 count = (int) wlData[1];
823 // convert nanoseconds to microseconds with rounding.
824 totalTime = (wlData[2] + 500) / 1000;
825
826 if (name.length() > 0) {
827 if (!m.containsKey(name)) {
828 m.put(name, new KernelWakelockStats(count, totalTime,
829 sKernelWakelockUpdateVersion));
830 numUpdatedWlNames++;
831 } else {
832 KernelWakelockStats kwlStats = m.get(name);
833 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) {
834 kwlStats.mCount += count;
835 kwlStats.mTotalTime += totalTime;
836 } else {
837 kwlStats.mCount = count;
838 kwlStats.mTotalTime = totalTime;
839 kwlStats.mVersion = sKernelWakelockUpdateVersion;
840 numUpdatedWlNames++;
841 }
842 }
843 }
844 startIndex = endIndex;
845 }
846
847 if (m.size() != numUpdatedWlNames) {
848 // Don't report old data.
849 Iterator<KernelWakelockStats> itr = m.values().iterator();
850 while (itr.hasNext()) {
851 if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
852 itr.remove();
853 }
854 }
855 }
856 return m;
857 }
858 }
859
860 private class KernelWakelockStats {
861 public int mCount;
862 public long mTotalTime;
863 public int mVersion;
864
865 KernelWakelockStats(int count, long totalTime, int version) {
866 mCount = count;
867 mTotalTime = totalTime;
868 mVersion = version;
869 }
870 }
871
872 /*
873 * Get the KernelWakelockTimer associated with name, and create a new one if one
874 * doesn't already exist.
875 */
876 public SamplingTimer getKernelWakelockTimerLocked(String name) {
877 SamplingTimer kwlt = mKernelWakelockStats.get(name);
878 if (kwlt == null) {
879 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
880 true /* track reported values */);
881 mKernelWakelockStats.put(name, kwlt);
882 }
883 return kwlt;
884 }
885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 public void doUnplug(long batteryUptime, long batteryRealtime) {
887 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
888 Uid u = mUidStats.valueAt(iu);
889 u.mStartedTcpBytesReceived = NetStat.getUidRxBytes(u.mUid);
890 u.mStartedTcpBytesSent = NetStat.getUidTxBytes(u.mUid);
891 u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived;
892 u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent;
893 }
894 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
895 mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime);
896 }
897 }
898
899 public void doPlug(long batteryUptime, long batteryRealtime) {
900 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
901 Uid u = mUidStats.valueAt(iu);
902 if (u.mStartedTcpBytesReceived >= 0) {
903 u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived();
904 u.mStartedTcpBytesReceived = -1;
905 }
906 if (u.mStartedTcpBytesSent >= 0) {
907 u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent();
908 u.mStartedTcpBytesSent = -1;
909 }
910 }
911 for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
912 mUnpluggables.get(i).plug(batteryUptime, batteryRealtime);
913 }
914 }
915
916 public void noteStartGps(int uid) {
917 mUidStats.get(uid).noteStartGps();
918 }
919
920 public void noteStopGps(int uid) {
921 mUidStats.get(uid).noteStopGps();
922 }
923
924 public void noteScreenOnLocked() {
925 if (!mScreenOn) {
926 mScreenOn = true;
927 mScreenOnTimer.startRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700928 if (mScreenBrightnessBin >= 0) {
929 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this);
930 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800931 }
932 }
933
934 public void noteScreenOffLocked() {
935 if (mScreenOn) {
936 mScreenOn = false;
937 mScreenOnTimer.stopRunningLocked(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700938 if (mScreenBrightnessBin >= 0) {
939 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
940 }
941 }
942 }
943
944 public void noteScreenBrightnessLocked(int brightness) {
945 // Bin the brightness.
946 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
947 if (bin < 0) bin = 0;
948 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
949 if (mScreenBrightnessBin != bin) {
950 if (mScreenOn) {
951 if (mScreenBrightnessBin >= 0) {
952 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
953 }
954 mScreenBrightnessTimer[bin].startRunningLocked(this);
955 }
956 mScreenBrightnessBin = bin;
957 }
958 }
959
960 public void noteInputEventLocked() {
961 mInputEventCounter.stepLocked();
962 }
963
964 public void noteUserActivityLocked(int uid, int event) {
965 Uid u = mUidStats.get(uid);
966 if (u != null) {
967 u.noteUserActivityLocked(event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968 }
969 }
970
971 public void notePhoneOnLocked() {
972 if (!mPhoneOn) {
973 mPhoneOn = true;
974 mPhoneOnTimer.startRunningLocked(this);
975 }
976 }
977
978 public void notePhoneOffLocked() {
979 if (mPhoneOn) {
980 mPhoneOn = false;
981 mPhoneOnTimer.stopRunningLocked(this);
982 }
983 }
984
Dianne Hackborn627bba72009-03-24 22:32:56 -0700985 public void notePhoneSignalStrengthLocked(int asu) {
986 // Bin the strength.
987 int bin;
988 if (asu < 0 || asu >= 99) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
989 else if (asu >= 16) bin = SIGNAL_STRENGTH_GREAT;
990 else if (asu >= 8) bin = SIGNAL_STRENGTH_GOOD;
991 else if (asu >= 4) bin = SIGNAL_STRENGTH_MODERATE;
992 else bin = SIGNAL_STRENGTH_POOR;
993 if (mPhoneSignalStrengthBin != bin) {
994 if (mPhoneSignalStrengthBin >= 0) {
995 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
996 }
997 mPhoneSignalStrengthBin = bin;
998 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
999 }
1000 }
1001
1002 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
1003 int bin = DATA_CONNECTION_NONE;
1004 if (hasData) {
1005 switch (dataType) {
1006 case TelephonyManager.NETWORK_TYPE_EDGE:
1007 bin = DATA_CONNECTION_EDGE;
1008 break;
1009 case TelephonyManager.NETWORK_TYPE_GPRS:
1010 bin = DATA_CONNECTION_GPRS;
1011 break;
1012 case TelephonyManager.NETWORK_TYPE_UMTS:
1013 bin = DATA_CONNECTION_UMTS;
1014 break;
1015 default:
1016 bin = DATA_CONNECTION_OTHER;
1017 break;
1018 }
1019 }
1020 if (mPhoneDataConnectionType != bin) {
1021 if (mPhoneDataConnectionType >= 0) {
1022 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this);
1023 }
1024 mPhoneDataConnectionType = bin;
1025 mPhoneDataConnectionsTimer[bin].startRunningLocked(this);
1026 }
1027 }
1028
Dianne Hackborn617f8772009-03-31 15:04:46 -07001029 public void noteWifiOnLocked(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001030 if (!mWifiOn) {
1031 mWifiOn = true;
1032 mWifiOnTimer.startRunningLocked(this);
1033 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001034 if (mWifiOnUid != uid) {
1035 if (mWifiOnUid >= 0) {
1036 Uid u = mUidStats.get(mWifiOnUid);
1037 if (u != null) {
1038 u.noteWifiTurnedOffLocked();
1039 }
1040 }
1041 mWifiOnUid = uid;
1042 Uid u = mUidStats.get(uid);
1043 if (u != null) {
1044 u.noteWifiTurnedOnLocked();
1045 }
1046 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001047 }
1048
Dianne Hackborn617f8772009-03-31 15:04:46 -07001049 public void noteWifiOffLocked(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001050 if (mWifiOn) {
1051 mWifiOn = false;
1052 mWifiOnTimer.stopRunningLocked(this);
1053 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001054 if (mWifiOnUid >= 0) {
1055 Uid u = mUidStats.get(mWifiOnUid);
1056 if (u != null) {
1057 u.noteWifiTurnedOffLocked();
1058 }
1059 mWifiOnUid = -1;
1060 }
The Android Open Source Project10592532009-03-18 17:39:46 -07001061 }
1062
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001063 public void noteWifiRunningLocked() {
1064 if (!mWifiRunning) {
1065 mWifiRunning = true;
1066 mWifiRunningTimer.startRunningLocked(this);
1067 }
1068 }
1069
1070 public void noteWifiStoppedLocked() {
1071 if (mWifiRunning) {
1072 mWifiRunning = false;
1073 mWifiRunningTimer.stopRunningLocked(this);
1074 }
1075 }
1076
The Android Open Source Project10592532009-03-18 17:39:46 -07001077 public void noteBluetoothOnLocked() {
1078 if (!mBluetoothOn) {
1079 mBluetoothOn = true;
1080 mBluetoothOnTimer.startRunningLocked(this);
1081 }
1082 }
1083
1084 public void noteBluetoothOffLocked() {
1085 if (mBluetoothOn) {
1086 mBluetoothOn = false;
1087 mBluetoothOnTimer.stopRunningLocked(this);
1088 }
1089 }
1090
1091 public void noteFullWifiLockAcquiredLocked(int uid) {
1092 Uid u = mUidStats.get(uid);
1093 if (u != null) {
1094 u.noteFullWifiLockAcquiredLocked();
1095 }
1096 }
1097
1098 public void noteFullWifiLockReleasedLocked(int uid) {
1099 Uid u = mUidStats.get(uid);
1100 if (u != null) {
1101 u.noteFullWifiLockReleasedLocked();
1102 }
1103 }
1104
1105 public void noteScanWifiLockAcquiredLocked(int uid) {
1106 Uid u = mUidStats.get(uid);
1107 if (u != null) {
1108 u.noteScanWifiLockAcquiredLocked();
1109 }
1110 }
1111
1112 public void noteScanWifiLockReleasedLocked(int uid) {
1113 Uid u = mUidStats.get(uid);
1114 if (u != null) {
1115 u.noteScanWifiLockReleasedLocked();
1116 }
1117 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001118
1119 public void noteWifiMulticastEnabledLocked(int uid) {
1120 Uid u = mUidStats.get(uid);
1121 if (u != null) {
1122 u.noteWifiMulticastEnabledLocked();
1123 }
1124 }
1125
1126 public void noteWifiMulticastDisabledLocked(int uid) {
1127 Uid u = mUidStats.get(uid);
1128 if (u != null) {
1129 u.noteWifiMulticastDisabledLocked();
1130 }
1131 }
1132
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001133 @Override public long getScreenOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001134 return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001135 }
1136
Dianne Hackborn617f8772009-03-31 15:04:46 -07001137 @Override public long getScreenBrightnessTime(int brightnessBin,
1138 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001139 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn617f8772009-03-31 15:04:46 -07001140 batteryRealtime, which);
1141 }
1142
1143 @Override public int getInputEventCount(int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001144 return mInputEventCounter.getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001145 }
1146
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001147 @Override public long getPhoneOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001148 return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001149 }
1150
Dianne Hackborn627bba72009-03-24 22:32:56 -07001151 @Override public long getPhoneSignalStrengthTime(int strengthBin,
1152 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001153 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07001154 batteryRealtime, which);
1155 }
1156
Dianne Hackborn617f8772009-03-31 15:04:46 -07001157 @Override public int getPhoneSignalStrengthCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001158 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001159 }
1160
Dianne Hackborn627bba72009-03-24 22:32:56 -07001161 @Override public long getPhoneDataConnectionTime(int dataType,
1162 long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001163 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn627bba72009-03-24 22:32:56 -07001164 batteryRealtime, which);
1165 }
1166
Dianne Hackborn617f8772009-03-31 15:04:46 -07001167 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001168 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001169 }
1170
The Android Open Source Project10592532009-03-18 17:39:46 -07001171 @Override public long getWifiOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001172 return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001173 }
1174
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001175 @Override public long getWifiRunningTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001176 return mWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001177 }
1178
The Android Open Source Project10592532009-03-18 17:39:46 -07001179 @Override public long getBluetoothOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001180 return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001181 }
1182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001183 @Override public boolean getIsOnBattery() {
1184 return mOnBattery;
1185 }
1186
1187 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
1188 return mUidStats;
1189 }
1190
1191 /**
1192 * The statistics associated with a particular uid.
1193 */
1194 public final class Uid extends BatteryStats.Uid {
1195
1196 final int mUid;
1197 long mLoadedTcpBytesReceived;
1198 long mLoadedTcpBytesSent;
1199 long mCurrentTcpBytesReceived;
1200 long mCurrentTcpBytesSent;
1201 long mTcpBytesReceivedAtLastUnplug;
1202 long mTcpBytesSentAtLastUnplug;
1203
1204 // These are not saved/restored when parcelling, since we want
1205 // to return from the parcel with a snapshot of the state.
1206 long mStartedTcpBytesReceived = -1;
1207 long mStartedTcpBytesSent = -1;
1208
Dianne Hackborn617f8772009-03-31 15:04:46 -07001209 boolean mWifiTurnedOn;
Evan Millarc64edde2009-04-18 12:26:32 -07001210 StopwatchTimer mWifiTurnedOnTimer;
Dianne Hackborn617f8772009-03-31 15:04:46 -07001211
The Android Open Source Project10592532009-03-18 17:39:46 -07001212 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07001213 StopwatchTimer mFullWifiLockTimer;
The Android Open Source Project10592532009-03-18 17:39:46 -07001214
1215 boolean mScanWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07001216 StopwatchTimer mScanWifiLockTimer;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001217
1218 boolean mWifiMulticastEnabled;
1219 StopwatchTimer mWifiMulticastTimer;
1220
Dianne Hackborn617f8772009-03-31 15:04:46 -07001221 Counter[] mUserActivityCounters;
1222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001223 /**
1224 * The statistics we have collected for this uid's wake locks.
1225 */
1226 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>();
1227
1228 /**
1229 * The statistics we have collected for this uid's sensor activations.
1230 */
1231 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>();
1232
1233 /**
1234 * The statistics we have collected for this uid's processes.
1235 */
1236 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>();
1237
1238 /**
1239 * The statistics we have collected for this uid's processes.
1240 */
1241 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>();
1242
1243 public Uid(int uid) {
1244 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001245 mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, null, mUnpluggables);
1246 mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables);
1247 mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001248 mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED,
1249 null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001250 }
1251
1252 @Override
1253 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
1254 return mWakelockStats;
1255 }
1256
1257 @Override
1258 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() {
1259 return mSensorStats;
1260 }
1261
1262 @Override
1263 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
1264 return mProcessStats;
1265 }
1266
1267 @Override
1268 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
1269 return mPackageStats;
1270 }
1271
1272 public int getUid() {
1273 return mUid;
1274 }
1275
1276 public long getTcpBytesReceived(int which) {
1277 if (which == STATS_LAST) {
1278 return mLoadedTcpBytesReceived;
1279 } else {
1280 long current = computeCurrentTcpBytesReceived();
1281 if (which == STATS_UNPLUGGED) {
1282 current -= mTcpBytesReceivedAtLastUnplug;
1283 } else if (which == STATS_TOTAL) {
1284 current += mLoadedTcpBytesReceived;
1285 }
1286 return current;
1287 }
1288 }
1289
1290 public long computeCurrentTcpBytesReceived() {
1291 return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0
1292 ? (NetStat.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0);
1293 }
1294
1295 public long getTcpBytesSent(int which) {
1296 if (which == STATS_LAST) {
1297 return mLoadedTcpBytesSent;
1298 } else {
1299 long current = computeCurrentTcpBytesSent();
1300 if (which == STATS_UNPLUGGED) {
1301 current -= mTcpBytesSentAtLastUnplug;
1302 } else if (which == STATS_TOTAL) {
1303 current += mLoadedTcpBytesSent;
1304 }
1305 return current;
1306 }
1307 }
1308
The Android Open Source Project10592532009-03-18 17:39:46 -07001309 @Override
Dianne Hackborn617f8772009-03-31 15:04:46 -07001310 public void noteWifiTurnedOnLocked() {
1311 if (!mWifiTurnedOn) {
1312 mWifiTurnedOn = true;
1313 mWifiTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
1314 }
1315 }
1316
1317 @Override
1318 public void noteWifiTurnedOffLocked() {
1319 if (mWifiTurnedOn) {
1320 mWifiTurnedOn = false;
1321 mWifiTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
1322 }
1323 }
1324
1325 @Override
The Android Open Source Project10592532009-03-18 17:39:46 -07001326 public void noteFullWifiLockAcquiredLocked() {
1327 if (!mFullWifiLockOut) {
1328 mFullWifiLockOut = true;
1329 mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
1330 }
1331 }
1332
1333 @Override
1334 public void noteFullWifiLockReleasedLocked() {
1335 if (mFullWifiLockOut) {
1336 mFullWifiLockOut = false;
1337 mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
1338 }
1339 }
1340
1341 @Override
1342 public void noteScanWifiLockAcquiredLocked() {
1343 if (!mScanWifiLockOut) {
1344 mScanWifiLockOut = true;
1345 mScanWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
1346 }
1347 }
1348
1349 @Override
1350 public void noteScanWifiLockReleasedLocked() {
1351 if (mScanWifiLockOut) {
1352 mScanWifiLockOut = false;
1353 mScanWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
1354 }
1355 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001356
1357 @Override
1358 public void noteWifiMulticastEnabledLocked() {
1359 if (!mWifiMulticastEnabled) {
1360 mWifiMulticastEnabled = true;
1361 mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this);
1362 }
1363 }
1364
1365 @Override
1366 public void noteWifiMulticastDisabledLocked() {
1367 if (mWifiMulticastEnabled) {
1368 mWifiMulticastEnabled = false;
1369 mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this);
1370 }
1371 }
1372
Dianne Hackborn617f8772009-03-31 15:04:46 -07001373 @Override
1374 public long getWifiTurnedOnTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001375 return mWifiTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001376 }
1377
The Android Open Source Project10592532009-03-18 17:39:46 -07001378 @Override
1379 public long getFullWifiLockTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001380 return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001381 }
1382
1383 @Override
1384 public long getScanWifiLockTime(long batteryRealtime, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07001385 return mScanWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001386 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001387
1388 @Override
1389 public long getWifiMulticastTime(long batteryRealtime, int which) {
1390 return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime,
1391 which);
1392 }
1393
Dianne Hackborn617f8772009-03-31 15:04:46 -07001394 @Override
1395 public void noteUserActivityLocked(int type) {
1396 if (mUserActivityCounters == null) {
1397 initUserActivityLocked();
1398 }
1399 if (type < 0) type = 0;
1400 else if (type >= NUM_USER_ACTIVITY_TYPES) type = NUM_USER_ACTIVITY_TYPES-1;
1401 mUserActivityCounters[type].stepLocked();
1402 }
1403
1404 @Override
1405 public boolean hasUserActivity() {
1406 return mUserActivityCounters != null;
1407 }
1408
1409 @Override
1410 public int getUserActivityCount(int type, int which) {
1411 if (mUserActivityCounters == null) {
1412 return 0;
1413 }
Evan Millarc64edde2009-04-18 12:26:32 -07001414 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001415 }
1416
1417 void initUserActivityLocked() {
1418 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
1419 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
1420 mUserActivityCounters[i] = new Counter(mUnpluggables);
1421 }
1422 }
1423
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001424 public long computeCurrentTcpBytesSent() {
1425 return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0
1426 ? (NetStat.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0);
1427 }
1428
1429 void writeToParcelLocked(Parcel out, long batteryRealtime) {
1430 out.writeInt(mWakelockStats.size());
1431 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
1432 out.writeString(wakelockEntry.getKey());
1433 Uid.Wakelock wakelock = wakelockEntry.getValue();
1434 wakelock.writeToParcelLocked(out, batteryRealtime);
1435 }
1436
1437 out.writeInt(mSensorStats.size());
1438 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) {
1439 out.writeInt(sensorEntry.getKey());
1440 Uid.Sensor sensor = sensorEntry.getValue();
1441 sensor.writeToParcelLocked(out, batteryRealtime);
1442 }
1443
1444 out.writeInt(mProcessStats.size());
1445 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) {
1446 out.writeString(procEntry.getKey());
1447 Uid.Proc proc = procEntry.getValue();
1448 proc.writeToParcelLocked(out);
1449 }
1450
1451 out.writeInt(mPackageStats.size());
1452 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
1453 out.writeString(pkgEntry.getKey());
1454 Uid.Pkg pkg = pkgEntry.getValue();
1455 pkg.writeToParcelLocked(out);
1456 }
1457
1458 out.writeLong(mLoadedTcpBytesReceived);
1459 out.writeLong(mLoadedTcpBytesSent);
1460 out.writeLong(computeCurrentTcpBytesReceived());
1461 out.writeLong(computeCurrentTcpBytesSent());
1462 out.writeLong(mTcpBytesReceivedAtLastUnplug);
1463 out.writeLong(mTcpBytesSentAtLastUnplug);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001464 mWifiTurnedOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07001465 mFullWifiLockTimer.writeToParcel(out, batteryRealtime);
1466 mScanWifiLockTimer.writeToParcel(out, batteryRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001467 mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001468 if (mUserActivityCounters == null) {
1469 out.writeInt(0);
1470 } else {
1471 out.writeInt(1);
1472 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
1473 mUserActivityCounters[i].writeToParcel(out);
1474 }
1475 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001476 }
1477
1478 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
1479 int numWakelocks = in.readInt();
1480 mWakelockStats.clear();
1481 for (int j = 0; j < numWakelocks; j++) {
1482 String wakelockName = in.readString();
1483 Uid.Wakelock wakelock = new Wakelock();
1484 wakelock.readFromParcelLocked(unpluggables, in);
1485 mWakelockStats.put(wakelockName, wakelock);
1486 }
1487
1488 int numSensors = in.readInt();
1489 mSensorStats.clear();
1490 for (int k = 0; k < numSensors; k++) {
1491 int sensorNumber = in.readInt();
1492 Uid.Sensor sensor = new Sensor(sensorNumber);
1493 sensor.readFromParcelLocked(mUnpluggables, in);
1494 mSensorStats.put(sensorNumber, sensor);
1495 }
1496
1497 int numProcs = in.readInt();
1498 mProcessStats.clear();
1499 for (int k = 0; k < numProcs; k++) {
1500 String processName = in.readString();
1501 Uid.Proc proc = new Proc();
1502 proc.readFromParcelLocked(in);
1503 mProcessStats.put(processName, proc);
1504 }
1505
1506 int numPkgs = in.readInt();
1507 mPackageStats.clear();
1508 for (int l = 0; l < numPkgs; l++) {
1509 String packageName = in.readString();
1510 Uid.Pkg pkg = new Pkg();
1511 pkg.readFromParcelLocked(in);
1512 mPackageStats.put(packageName, pkg);
1513 }
1514
1515 mLoadedTcpBytesReceived = in.readLong();
1516 mLoadedTcpBytesSent = in.readLong();
1517 mCurrentTcpBytesReceived = in.readLong();
1518 mCurrentTcpBytesSent = in.readLong();
1519 mTcpBytesReceivedAtLastUnplug = in.readLong();
1520 mTcpBytesSentAtLastUnplug = in.readLong();
Dianne Hackborn617f8772009-03-31 15:04:46 -07001521 mWifiTurnedOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001522 mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07001523 mFullWifiLockOut = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001524 mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07001525 mScanWifiLockOut = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001526 mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables, in);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07001527 mWifiMulticastEnabled = false;
1528 mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED,
1529 null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001530 if (in.readInt() == 0) {
1531 mUserActivityCounters = null;
1532 } else {
1533 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
1534 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
1535 mUserActivityCounters[i] = new Counter(mUnpluggables, in);
1536 }
1537 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001538 }
1539
1540 /**
1541 * The statistics associated with a particular wake lock.
1542 */
1543 public final class Wakelock extends BatteryStats.Uid.Wakelock {
1544 /**
1545 * How long (in ms) this uid has been keeping the device partially awake.
1546 */
Evan Millarc64edde2009-04-18 12:26:32 -07001547 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548
1549 /**
1550 * How long (in ms) this uid has been keeping the device fully awake.
1551 */
Evan Millarc64edde2009-04-18 12:26:32 -07001552 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001553
1554 /**
1555 * How long (in ms) this uid has had a window keeping the device awake.
1556 */
Evan Millarc64edde2009-04-18 12:26:32 -07001557 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001558
1559 /**
1560 * Reads a possibly null Timer from a Parcel. The timer is associated with the
1561 * proper timer pool from the given BatteryStatsImpl object.
1562 *
1563 * @param in the Parcel to be read from.
1564 * return a new Timer, or null.
1565 */
Evan Millarc64edde2009-04-18 12:26:32 -07001566 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001567 ArrayList<Unpluggable> unpluggables, Parcel in) {
1568 if (in.readInt() == 0) {
1569 return null;
1570 }
1571
Evan Millarc64edde2009-04-18 12:26:32 -07001572 return new StopwatchTimer(type, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001573 }
1574
1575 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
1576 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
1577 mPartialTimers, unpluggables, in);
1578 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
1579 mFullTimers, unpluggables, in);
1580 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
1581 mWindowTimers, unpluggables, in);
1582 }
1583
1584 void writeToParcelLocked(Parcel out, long batteryRealtime) {
1585 Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime);
1586 Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime);
1587 Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime);
1588 }
1589
1590 @Override
1591 public Timer getWakeTime(int type) {
1592 switch (type) {
1593 case WAKE_TYPE_FULL: return mTimerFull;
1594 case WAKE_TYPE_PARTIAL: return mTimerPartial;
1595 case WAKE_TYPE_WINDOW: return mTimerWindow;
1596 default: throw new IllegalArgumentException("type = " + type);
1597 }
1598 }
1599 }
1600
1601 public final class Sensor extends BatteryStats.Uid.Sensor {
1602 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07001603 StopwatchTimer mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001604
1605 public Sensor(int handle) {
1606 mHandle = handle;
1607 }
1608
Evan Millarc64edde2009-04-18 12:26:32 -07001609 private StopwatchTimer readTimerFromParcel(ArrayList<Unpluggable> unpluggables,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001610 Parcel in) {
1611 if (in.readInt() == 0) {
1612 return null;
1613 }
1614
Evan Millarc64edde2009-04-18 12:26:32 -07001615 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001616 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001617 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001618 mSensorTimers.put(mHandle, pool);
1619 }
Evan Millarc64edde2009-04-18 12:26:32 -07001620 return new StopwatchTimer(0, pool, unpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001621 }
1622
1623 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
1624 mTimer = readTimerFromParcel(unpluggables, in);
1625 }
1626
1627 void writeToParcelLocked(Parcel out, long batteryRealtime) {
1628 Timer.writeTimerToParcel(out, mTimer, batteryRealtime);
1629 }
1630
1631 @Override
1632 public Timer getSensorTime() {
1633 return mTimer;
1634 }
1635
1636 public int getHandle() {
1637 return mHandle;
1638 }
1639 }
1640
1641 /**
1642 * The statistics associated with a particular process.
1643 */
1644 public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable {
1645 /**
1646 * Total time (in 1/100 sec) spent executing in user code.
1647 */
1648 long mUserTime;
1649
1650 /**
1651 * Total time (in 1/100 sec) spent executing in kernel code.
1652 */
1653 long mSystemTime;
1654
1655 /**
1656 * Number of times the process has been started.
1657 */
1658 int mStarts;
1659
1660 /**
1661 * The amount of user time loaded from a previous save.
1662 */
1663 long mLoadedUserTime;
1664
1665 /**
1666 * The amount of system time loaded from a previous save.
1667 */
1668 long mLoadedSystemTime;
1669
1670 /**
1671 * The number of times the process has started from a previous save.
1672 */
1673 int mLoadedStarts;
1674
1675 /**
1676 * The amount of user time loaded from the previous run.
1677 */
1678 long mLastUserTime;
1679
1680 /**
1681 * The amount of system time loaded from the previous run.
1682 */
1683 long mLastSystemTime;
1684
1685 /**
1686 * The number of times the process has started from the previous run.
1687 */
1688 int mLastStarts;
1689
1690 /**
1691 * The amount of user time when last unplugged.
1692 */
1693 long mUnpluggedUserTime;
1694
1695 /**
1696 * The amount of system time when last unplugged.
1697 */
1698 long mUnpluggedSystemTime;
1699
1700 /**
1701 * The number of times the process has started before unplugged.
1702 */
1703 int mUnpluggedStarts;
1704
1705 Proc() {
1706 mUnpluggables.add(this);
1707 }
1708
1709 public void unplug(long batteryUptime, long batteryRealtime) {
1710 mUnpluggedUserTime = mUserTime;
1711 mUnpluggedSystemTime = mSystemTime;
1712 mUnpluggedStarts = mStarts;
1713 }
1714
1715 public void plug(long batteryUptime, long batteryRealtime) {
1716 }
1717
1718 void writeToParcelLocked(Parcel out) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001719 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
1720 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
1721
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001722 out.writeLong(mUserTime);
1723 out.writeLong(mSystemTime);
1724 out.writeInt(mStarts);
1725 out.writeLong(mLoadedUserTime);
1726 out.writeLong(mLoadedSystemTime);
1727 out.writeInt(mLoadedStarts);
1728 out.writeLong(mLastUserTime);
1729 out.writeLong(mLastSystemTime);
1730 out.writeInt(mLastStarts);
1731 out.writeLong(mUnpluggedUserTime);
1732 out.writeLong(mUnpluggedSystemTime);
1733 out.writeInt(mUnpluggedStarts);
1734 }
1735
1736 void readFromParcelLocked(Parcel in) {
1737 mUserTime = in.readLong();
1738 mSystemTime = in.readLong();
1739 mStarts = in.readInt();
1740 mLoadedUserTime = in.readLong();
1741 mLoadedSystemTime = in.readLong();
1742 mLoadedStarts = in.readInt();
1743 mLastUserTime = in.readLong();
1744 mLastSystemTime = in.readLong();
1745 mLastStarts = in.readInt();
1746 mUnpluggedUserTime = in.readLong();
1747 mUnpluggedSystemTime = in.readLong();
1748 mUnpluggedStarts = in.readInt();
1749 }
1750
1751 public BatteryStatsImpl getBatteryStats() {
1752 return BatteryStatsImpl.this;
1753 }
1754
1755 public void addCpuTimeLocked(int utime, int stime) {
1756 mUserTime += utime;
1757 mSystemTime += stime;
1758 }
1759
1760 public void incStartsLocked() {
1761 mStarts++;
1762 }
1763
1764 @Override
1765 public long getUserTime(int which) {
1766 long val;
1767 if (which == STATS_LAST) {
1768 val = mLastUserTime;
1769 } else {
1770 val = mUserTime;
1771 if (which == STATS_CURRENT) {
1772 val -= mLoadedUserTime;
1773 } else if (which == STATS_UNPLUGGED) {
1774 val -= mUnpluggedUserTime;
1775 }
1776 }
1777 return val;
1778 }
1779
1780 @Override
1781 public long getSystemTime(int which) {
1782 long val;
1783 if (which == STATS_LAST) {
1784 val = mLastSystemTime;
1785 } else {
1786 val = mSystemTime;
1787 if (which == STATS_CURRENT) {
1788 val -= mLoadedSystemTime;
1789 } else if (which == STATS_UNPLUGGED) {
1790 val -= mUnpluggedSystemTime;
1791 }
1792 }
1793 return val;
1794 }
1795
1796 @Override
1797 public int getStarts(int which) {
1798 int val;
1799 if (which == STATS_LAST) {
1800 val = mLastStarts;
1801 } else {
1802 val = mStarts;
1803 if (which == STATS_CURRENT) {
1804 val -= mLoadedStarts;
1805 } else if (which == STATS_UNPLUGGED) {
1806 val -= mUnpluggedStarts;
1807 }
1808 }
1809 return val;
1810 }
1811 }
1812
1813 /**
1814 * The statistics associated with a particular package.
1815 */
1816 public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable {
1817 /**
1818 * Number of times this package has done something that could wake up the
1819 * device from sleep.
1820 */
1821 int mWakeups;
1822
1823 /**
1824 * Number of things that could wake up the device loaded from a
1825 * previous save.
1826 */
1827 int mLoadedWakeups;
1828
1829 /**
1830 * Number of things that could wake up the device as of the
1831 * last run.
1832 */
1833 int mLastWakeups;
1834
1835 /**
1836 * Number of things that could wake up the device as of the
1837 * last run.
1838 */
1839 int mUnpluggedWakeups;
1840
1841 /**
1842 * The statics we have collected for this package's services.
1843 */
1844 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
1845
1846 Pkg() {
1847 mUnpluggables.add(this);
1848 }
1849
1850 public void unplug(long batteryUptime, long batteryRealtime) {
1851 mUnpluggedWakeups = mWakeups;
1852 }
1853
1854 public void plug(long batteryUptime, long batteryRealtime) {
1855 }
1856
1857 void readFromParcelLocked(Parcel in) {
1858 mWakeups = in.readInt();
1859 mLoadedWakeups = in.readInt();
1860 mLastWakeups = in.readInt();
1861 mUnpluggedWakeups = in.readInt();
1862
1863 int numServs = in.readInt();
1864 mServiceStats.clear();
1865 for (int m = 0; m < numServs; m++) {
1866 String serviceName = in.readString();
1867 Uid.Pkg.Serv serv = new Serv();
1868 mServiceStats.put(serviceName, serv);
1869
1870 serv.readFromParcelLocked(in);
1871 }
1872 }
1873
1874 void writeToParcelLocked(Parcel out) {
1875 out.writeInt(mWakeups);
1876 out.writeInt(mLoadedWakeups);
1877 out.writeInt(mLastWakeups);
1878 out.writeInt(mUnpluggedWakeups);
1879
1880 out.writeInt(mServiceStats.size());
1881 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
1882 out.writeString(servEntry.getKey());
1883 Uid.Pkg.Serv serv = servEntry.getValue();
1884
1885 serv.writeToParcelLocked(out);
1886 }
1887 }
1888
1889 @Override
1890 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
1891 return mServiceStats;
1892 }
1893
1894 @Override
1895 public int getWakeups(int which) {
1896 int val;
1897 if (which == STATS_LAST) {
1898 val = mLastWakeups;
1899 } else {
1900 val = mWakeups;
1901 if (which == STATS_CURRENT) {
1902 val -= mLoadedWakeups;
1903 } else if (which == STATS_UNPLUGGED) {
1904 val -= mUnpluggedWakeups;
1905 }
1906 }
1907
1908 return val;
1909 }
1910
1911 /**
1912 * The statistics associated with a particular service.
1913 */
1914 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable {
1915 /**
1916 * Total time (ms in battery uptime) the service has been left started.
1917 */
1918 long mStartTime;
1919
1920 /**
1921 * If service has been started and not yet stopped, this is
1922 * when it was started.
1923 */
1924 long mRunningSince;
1925
1926 /**
1927 * True if we are currently running.
1928 */
1929 boolean mRunning;
1930
1931 /**
1932 * Total number of times startService() has been called.
1933 */
1934 int mStarts;
1935
1936 /**
1937 * Total time (ms in battery uptime) the service has been left launched.
1938 */
1939 long mLaunchedTime;
1940
1941 /**
1942 * If service has been launched and not yet exited, this is
1943 * when it was launched (ms in battery uptime).
1944 */
1945 long mLaunchedSince;
1946
1947 /**
1948 * True if we are currently launched.
1949 */
1950 boolean mLaunched;
1951
1952 /**
1953 * Total number times the service has been launched.
1954 */
1955 int mLaunches;
1956
1957 /**
1958 * The amount of time spent started loaded from a previous save
1959 * (ms in battery uptime).
1960 */
1961 long mLoadedStartTime;
1962
1963 /**
1964 * The number of starts loaded from a previous save.
1965 */
1966 int mLoadedStarts;
1967
1968 /**
1969 * The number of launches loaded from a previous save.
1970 */
1971 int mLoadedLaunches;
1972
1973 /**
1974 * The amount of time spent started as of the last run (ms
1975 * in battery uptime).
1976 */
1977 long mLastStartTime;
1978
1979 /**
1980 * The number of starts as of the last run.
1981 */
1982 int mLastStarts;
1983
1984 /**
1985 * The number of launches as of the last run.
1986 */
1987 int mLastLaunches;
1988
1989 /**
1990 * The amount of time spent started when last unplugged (ms
1991 * in battery uptime).
1992 */
1993 long mUnpluggedStartTime;
1994
1995 /**
1996 * The number of starts when last unplugged.
1997 */
1998 int mUnpluggedStarts;
1999
2000 /**
2001 * The number of launches when last unplugged.
2002 */
2003 int mUnpluggedLaunches;
2004
2005 Serv() {
2006 mUnpluggables.add(this);
2007 }
2008
2009 public void unplug(long batteryUptime, long batteryRealtime) {
2010 mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime);
2011 mUnpluggedStarts = mStarts;
2012 mUnpluggedLaunches = mLaunches;
2013 }
2014
2015 public void plug(long batteryUptime, long batteryRealtime) {
2016 }
2017
2018 void readFromParcelLocked(Parcel in) {
2019 mStartTime = in.readLong();
2020 mRunningSince = in.readLong();
2021 mRunning = in.readInt() != 0;
2022 mStarts = in.readInt();
2023 mLaunchedTime = in.readLong();
2024 mLaunchedSince = in.readLong();
2025 mLaunched = in.readInt() != 0;
2026 mLaunches = in.readInt();
2027 mLoadedStartTime = in.readLong();
2028 mLoadedStarts = in.readInt();
2029 mLoadedLaunches = in.readInt();
2030 mLastStartTime = in.readLong();
2031 mLastStarts = in.readInt();
2032 mLastLaunches = in.readInt();
2033 mUnpluggedStartTime = in.readLong();
2034 mUnpluggedStarts = in.readInt();
2035 mUnpluggedLaunches = in.readInt();
2036 }
2037
2038 void writeToParcelLocked(Parcel out) {
2039 out.writeLong(mStartTime);
2040 out.writeLong(mRunningSince);
2041 out.writeInt(mRunning ? 1 : 0);
2042 out.writeInt(mStarts);
2043 out.writeLong(mLaunchedTime);
2044 out.writeLong(mLaunchedSince);
2045 out.writeInt(mLaunched ? 1 : 0);
2046 out.writeInt(mLaunches);
2047 out.writeLong(mLoadedStartTime);
2048 out.writeInt(mLoadedStarts);
2049 out.writeInt(mLoadedLaunches);
2050 out.writeLong(mLastStartTime);
2051 out.writeInt(mLastStarts);
2052 out.writeInt(mLastLaunches);
2053 out.writeLong(mUnpluggedStartTime);
2054 out.writeInt(mUnpluggedStarts);
2055 out.writeInt(mUnpluggedLaunches);
2056 }
2057
2058 long getLaunchTimeToNowLocked(long batteryUptime) {
2059 if (!mLaunched) return mLaunchedTime;
2060 return mLaunchedTime + batteryUptime - mLaunchedSince;
2061 }
2062
2063 long getStartTimeToNowLocked(long batteryUptime) {
2064 if (!mRunning) return mStartTime;
2065 return mStartTime + batteryUptime - mRunningSince;
2066 }
2067
2068 public void startLaunchedLocked() {
2069 if (!mLaunched) {
2070 mLaunches++;
2071 mLaunchedSince = getBatteryUptimeLocked();
2072 mLaunched = true;
2073 }
2074 }
2075
2076 public void stopLaunchedLocked() {
2077 if (mLaunched) {
2078 long time = getBatteryUptimeLocked() - mLaunchedSince;
2079 if (time > 0) {
2080 mLaunchedTime += time;
2081 } else {
2082 mLaunches--;
2083 }
2084 mLaunched = false;
2085 }
2086 }
2087
2088 public void startRunningLocked() {
2089 if (!mRunning) {
2090 mStarts++;
2091 mRunningSince = getBatteryUptimeLocked();
2092 mRunning = true;
2093 }
2094 }
2095
2096 public void stopRunningLocked() {
2097 if (mRunning) {
2098 long time = getBatteryUptimeLocked() - mRunningSince;
2099 if (time > 0) {
2100 mStartTime += time;
2101 } else {
2102 mStarts--;
2103 }
2104 mRunning = false;
2105 }
2106 }
2107
2108 public BatteryStatsImpl getBatteryStats() {
2109 return BatteryStatsImpl.this;
2110 }
2111
2112 @Override
2113 public int getLaunches(int which) {
2114 int val;
2115
2116 if (which == STATS_LAST) {
2117 val = mLastLaunches;
2118 } else {
2119 val = mLaunches;
2120 if (which == STATS_CURRENT) {
2121 val -= mLoadedLaunches;
2122 } else if (which == STATS_UNPLUGGED) {
2123 val -= mUnpluggedLaunches;
2124 }
2125 }
2126
2127 return val;
2128 }
2129
2130 @Override
2131 public long getStartTime(long now, int which) {
2132 long val;
2133 if (which == STATS_LAST) {
2134 val = mLastStartTime;
2135 } else {
2136 val = getStartTimeToNowLocked(now);
2137 if (which == STATS_CURRENT) {
2138 val -= mLoadedStartTime;
2139 } else if (which == STATS_UNPLUGGED) {
2140 val -= mUnpluggedStartTime;
2141 }
2142 }
2143
2144 return val;
2145 }
2146
2147 @Override
2148 public int getStarts(int which) {
2149 int val;
2150 if (which == STATS_LAST) {
2151 val = mLastStarts;
2152 } else {
2153 val = mStarts;
2154 if (which == STATS_CURRENT) {
2155 val -= mLoadedStarts;
2156 } else if (which == STATS_UNPLUGGED) {
2157 val -= mUnpluggedStarts;
2158 }
2159 }
2160
2161 return val;
2162 }
2163 }
2164
2165 public BatteryStatsImpl getBatteryStats() {
2166 return BatteryStatsImpl.this;
2167 }
2168
2169 public void incWakeupsLocked() {
2170 mWakeups++;
2171 }
2172
2173 final Serv newServiceStatsLocked() {
2174 return new Serv();
2175 }
2176 }
2177
2178 /**
2179 * Retrieve the statistics object for a particular process, creating
2180 * if needed.
2181 */
2182 public Proc getProcessStatsLocked(String name) {
2183 Proc ps = mProcessStats.get(name);
2184 if (ps == null) {
2185 ps = new Proc();
2186 mProcessStats.put(name, ps);
2187 }
2188
2189 return ps;
2190 }
2191
2192 /**
2193 * Retrieve the statistics object for a particular service, creating
2194 * if needed.
2195 */
2196 public Pkg getPackageStatsLocked(String name) {
2197 Pkg ps = mPackageStats.get(name);
2198 if (ps == null) {
2199 ps = new Pkg();
2200 mPackageStats.put(name, ps);
2201 }
2202
2203 return ps;
2204 }
2205
2206 /**
2207 * Retrieve the statistics object for a particular service, creating
2208 * if needed.
2209 */
2210 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
2211 Pkg ps = getPackageStatsLocked(pkg);
2212 Pkg.Serv ss = ps.mServiceStats.get(serv);
2213 if (ss == null) {
2214 ss = ps.newServiceStatsLocked();
2215 ps.mServiceStats.put(serv, ss);
2216 }
2217
2218 return ss;
2219 }
2220
Evan Millarc64edde2009-04-18 12:26:32 -07002221 public StopwatchTimer getWakeTimerLocked(String name, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002222 Wakelock wl = mWakelockStats.get(name);
2223 if (wl == null) {
2224 wl = new Wakelock();
2225 mWakelockStats.put(name, wl);
2226 }
Evan Millarc64edde2009-04-18 12:26:32 -07002227 StopwatchTimer t = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002228 switch (type) {
2229 case WAKE_TYPE_PARTIAL:
2230 t = wl.mTimerPartial;
2231 if (t == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002232 t = new StopwatchTimer(WAKE_TYPE_PARTIAL, mPartialTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002233 wl.mTimerPartial = t;
2234 }
2235 return t;
2236 case WAKE_TYPE_FULL:
2237 t = wl.mTimerFull;
2238 if (t == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002239 t = new StopwatchTimer(WAKE_TYPE_FULL, mFullTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002240 wl.mTimerFull = t;
2241 }
2242 return t;
2243 case WAKE_TYPE_WINDOW:
2244 t = wl.mTimerWindow;
2245 if (t == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002246 t = new StopwatchTimer(WAKE_TYPE_WINDOW, mWindowTimers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002247 wl.mTimerWindow = t;
2248 }
2249 return t;
2250 default:
2251 throw new IllegalArgumentException("type=" + type);
2252 }
2253 }
2254
Evan Millarc64edde2009-04-18 12:26:32 -07002255 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002256 Sensor se = mSensorStats.get(sensor);
2257 if (se == null) {
2258 if (!create) {
2259 return null;
2260 }
2261 se = new Sensor(sensor);
2262 mSensorStats.put(sensor, se);
2263 }
Evan Millarc64edde2009-04-18 12:26:32 -07002264 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002265 if (t != null) {
2266 return t;
2267 }
Evan Millarc64edde2009-04-18 12:26:32 -07002268 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002269 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07002270 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002271 mSensorTimers.put(sensor, timers);
2272 }
Evan Millarc64edde2009-04-18 12:26:32 -07002273 t = new StopwatchTimer(BatteryStats.SENSOR, timers, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002274 se.mTimer = t;
2275 return t;
2276 }
2277
2278 public void noteStartWakeLocked(String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07002279 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002280 if (t != null) {
2281 t.startRunningLocked(BatteryStatsImpl.this);
2282 }
2283 }
2284
2285 public void noteStopWakeLocked(String name, int type) {
Evan Millarc64edde2009-04-18 12:26:32 -07002286 StopwatchTimer t = getWakeTimerLocked(name, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002287 if (t != null) {
2288 t.stopRunningLocked(BatteryStatsImpl.this);
2289 }
2290 }
2291
2292 public void noteStartSensor(int sensor) {
Evan Millarc64edde2009-04-18 12:26:32 -07002293 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002294 if (t != null) {
2295 t.startRunningLocked(BatteryStatsImpl.this);
2296 }
2297 }
2298
2299 public void noteStopSensor(int sensor) {
2300 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07002301 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002302 if (t != null) {
2303 t.stopRunningLocked(BatteryStatsImpl.this);
2304 }
2305 }
2306
2307 public void noteStartGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07002308 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002309 if (t != null) {
2310 t.startRunningLocked(BatteryStatsImpl.this);
2311 }
2312 }
2313
2314 public void noteStopGps() {
Evan Millarc64edde2009-04-18 12:26:32 -07002315 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002316 if (t != null) {
2317 t.stopRunningLocked(BatteryStatsImpl.this);
2318 }
2319 }
2320
2321 public BatteryStatsImpl getBatteryStats() {
2322 return BatteryStatsImpl.this;
2323 }
2324 }
2325
2326 public BatteryStatsImpl(String filename) {
2327 mFile = new File(filename);
2328 mBackupFile = new File(filename + ".bak");
2329 mStartCount++;
Evan Millarc64edde2009-04-18 12:26:32 -07002330 mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002331 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07002332 mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002333 }
2334 mInputEventCounter = new Counter(mUnpluggables);
Evan Millarc64edde2009-04-18 12:26:32 -07002335 mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002336 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07002337 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002338 }
2339 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07002340 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002341 }
Evan Millarc64edde2009-04-18 12:26:32 -07002342 mWifiOnTimer = new StopwatchTimer(-3, null, mUnpluggables);
2343 mWifiRunningTimer = new StopwatchTimer(-4, null, mUnpluggables);
2344 mBluetoothOnTimer = new StopwatchTimer(-5, null, mUnpluggables);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002345 mOnBattery = mOnBatteryInternal = false;
2346 mTrackBatteryPastUptime = 0;
2347 mTrackBatteryPastRealtime = 0;
2348 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
2349 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
2350 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
2351 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
Evan Millar633a1742009-04-02 16:36:33 -07002352 mDischargeStartLevel = 0;
2353 mDischargeCurrentLevel = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002354 }
2355
2356 public BatteryStatsImpl(Parcel p) {
2357 mFile = mBackupFile = null;
2358 readFromParcel(p);
2359 }
2360
2361 @Override
2362 public int getStartCount() {
2363 return mStartCount;
2364 }
2365
2366 public boolean isOnBattery() {
2367 return mOnBattery;
2368 }
2369
The Android Open Source Project10592532009-03-18 17:39:46 -07002370 public void setOnBattery(boolean onBattery, int level) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002371 synchronized(this) {
Evan Millarc64edde2009-04-18 12:26:32 -07002372 updateKernelWakelocksLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002373 if (mOnBattery != onBattery) {
2374 mOnBattery = mOnBatteryInternal = onBattery;
2375
2376 long uptime = SystemClock.uptimeMillis() * 1000;
2377 long mSecRealtime = SystemClock.elapsedRealtime();
2378 long realtime = mSecRealtime * 1000;
2379 if (onBattery) {
2380 mTrackBatteryUptimeStart = uptime;
2381 mTrackBatteryRealtimeStart = realtime;
2382 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
2383 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
Evan Millar633a1742009-04-02 16:36:33 -07002384 mDischargeCurrentLevel = mDischargeStartLevel = level;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002385 doUnplug(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
2386 } else {
2387 mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
2388 mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
Evan Millar633a1742009-04-02 16:36:33 -07002389 mDischargeCurrentLevel = level;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002390 doPlug(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
2391 }
2392 if ((mLastWriteTime + (60 * 1000)) < mSecRealtime) {
2393 if (mFile != null) {
2394 writeLocked();
2395 }
2396 }
2397 }
2398 }
2399 }
Evan Millar633a1742009-04-02 16:36:33 -07002400
2401 public void recordCurrentLevel(int level) {
2402 mDischargeCurrentLevel = level;
2403 }
Evan Millarc64edde2009-04-18 12:26:32 -07002404
2405 public void updateKernelWakelocksLocked() {
2406 Map<String, KernelWakelockStats> m = readKernelWakelockStats();
2407
Marco Nelissend8593312009-04-30 14:45:06 -07002408 if (m == null) {
2409 // Not crashing might make board bringup easier.
2410 Log.w(TAG, "Couldn't get kernel wake lock stats");
2411 return;
2412 }
2413
Evan Millarc64edde2009-04-18 12:26:32 -07002414 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) {
2415 String name = ent.getKey();
2416 KernelWakelockStats kws = ent.getValue();
2417
2418 SamplingTimer kwlt = mKernelWakelockStats.get(name);
2419 if (kwlt == null) {
2420 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
2421 true /* track reported values */);
2422 mKernelWakelockStats.put(name, kwlt);
2423 }
2424 kwlt.updateCurrentReportedCount(kws.mCount);
2425 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
2426 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion);
2427 }
2428
2429 if (m.size() != mKernelWakelockStats.size()) {
2430 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
2431 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
2432 SamplingTimer st = ent.getValue();
2433 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) {
2434 st.setStale();
2435 }
2436 }
2437 }
2438 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002439
2440 public long getAwakeTimeBattery() {
2441 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
2442 }
2443
2444 public long getAwakeTimePlugged() {
2445 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
2446 }
2447
2448 @Override
2449 public long computeUptime(long curTime, int which) {
2450 switch (which) {
2451 case STATS_TOTAL: return mUptime + (curTime-mUptimeStart);
2452 case STATS_LAST: return mLastUptime;
2453 case STATS_CURRENT: return (curTime-mUptimeStart);
2454 case STATS_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart);
2455 }
2456 return 0;
2457 }
2458
2459 @Override
2460 public long computeRealtime(long curTime, int which) {
2461 switch (which) {
2462 case STATS_TOTAL: return mRealtime + (curTime-mRealtimeStart);
2463 case STATS_LAST: return mLastRealtime;
2464 case STATS_CURRENT: return (curTime-mRealtimeStart);
2465 case STATS_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart);
2466 }
2467 return 0;
2468 }
2469
2470 @Override
2471 public long computeBatteryUptime(long curTime, int which) {
2472 switch (which) {
2473 case STATS_TOTAL:
2474 return mBatteryUptime + getBatteryUptime(curTime);
2475 case STATS_LAST:
2476 return mBatteryLastUptime;
2477 case STATS_CURRENT:
2478 return getBatteryUptime(curTime);
2479 case STATS_UNPLUGGED:
2480 return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime;
2481 }
2482 return 0;
2483 }
2484
2485 @Override
2486 public long computeBatteryRealtime(long curTime, int which) {
2487 switch (which) {
2488 case STATS_TOTAL:
2489 return mBatteryRealtime + getBatteryRealtimeLocked(curTime);
2490 case STATS_LAST:
2491 return mBatteryLastRealtime;
2492 case STATS_CURRENT:
2493 return getBatteryRealtimeLocked(curTime);
2494 case STATS_UNPLUGGED:
2495 return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime;
2496 }
2497 return 0;
2498 }
2499
2500 long getBatteryUptimeLocked(long curTime) {
2501 long time = mTrackBatteryPastUptime;
2502 if (mOnBatteryInternal) {
2503 time += curTime - mTrackBatteryUptimeStart;
2504 }
2505 return time;
2506 }
2507
2508 long getBatteryUptimeLocked() {
2509 return getBatteryUptime(SystemClock.uptimeMillis() * 1000);
2510 }
2511
2512 @Override
2513 public long getBatteryUptime(long curTime) {
2514 return getBatteryUptimeLocked(curTime);
2515 }
2516
2517 long getBatteryRealtimeLocked(long curTime) {
2518 long time = mTrackBatteryPastRealtime;
2519 if (mOnBatteryInternal) {
2520 time += curTime - mTrackBatteryRealtimeStart;
2521 }
2522 return time;
2523 }
2524
2525 @Override
2526 public long getBatteryRealtime(long curTime) {
2527 return getBatteryRealtimeLocked(curTime);
2528 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002529
2530 @Override
Evan Millar633a1742009-04-02 16:36:33 -07002531 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002532 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07002533 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002534 }
2535 }
2536
Evan Millar633a1742009-04-02 16:36:33 -07002537 public int getDischargeStartLevelLocked() {
2538 return mDischargeStartLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07002539 }
2540
2541 @Override
Evan Millar633a1742009-04-02 16:36:33 -07002542 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07002543 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07002544 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07002545 }
2546 }
2547
Evan Millar633a1742009-04-02 16:36:33 -07002548 public int getDischargeCurrentLevelLocked() {
2549 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07002550 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002551
2552 /**
2553 * Retrieve the statistics object for a particular uid, creating if needed.
2554 */
2555 public Uid getUidStatsLocked(int uid) {
2556 Uid u = mUidStats.get(uid);
2557 if (u == null) {
2558 u = new Uid(uid);
2559 mUidStats.put(uid, u);
2560 }
2561 return u;
2562 }
2563
2564 /**
2565 * Remove the statistics object for a particular uid.
2566 */
2567 public void removeUidStatsLocked(int uid) {
2568 mUidStats.remove(uid);
2569 }
2570
2571 /**
2572 * Retrieve the statistics object for a particular process, creating
2573 * if needed.
2574 */
2575 public Uid.Proc getProcessStatsLocked(int uid, String name) {
2576 Uid u = getUidStatsLocked(uid);
2577 return u.getProcessStatsLocked(name);
2578 }
2579
2580 /**
2581 * Retrieve the statistics object for a particular process, creating
2582 * if needed.
2583 */
2584 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
2585 Uid u = getUidStatsLocked(uid);
2586 return u.getPackageStatsLocked(pkg);
2587 }
2588
2589 /**
2590 * Retrieve the statistics object for a particular service, creating
2591 * if needed.
2592 */
2593 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
2594 Uid u = getUidStatsLocked(uid);
2595 return u.getServiceStatsLocked(pkg, name);
2596 }
2597
2598 public void writeLocked() {
2599 if ((mFile == null) || (mBackupFile == null)) {
2600 Log.w("BatteryStats", "writeLocked: no file associated with this instance");
2601 return;
2602 }
2603
2604 // Keep the old file around until we know the new one has
2605 // been successfully written.
2606 if (mFile.exists()) {
2607 if (mBackupFile.exists()) {
2608 mBackupFile.delete();
2609 }
2610 mFile.renameTo(mBackupFile);
2611 }
2612
2613 try {
2614 FileOutputStream stream = new FileOutputStream(mFile);
2615 Parcel out = Parcel.obtain();
2616 writeSummaryToParcel(out);
2617 stream.write(out.marshall());
2618 out.recycle();
2619
2620 stream.flush();
2621 stream.close();
2622 mBackupFile.delete();
2623
2624 mLastWriteTime = SystemClock.elapsedRealtime();
2625 } catch (IOException e) {
2626 Log.e("BatteryStats", "Error writing battery statistics", e);
2627 }
2628 }
2629
2630 static byte[] readFully(FileInputStream stream) throws java.io.IOException {
2631 int pos = 0;
2632 int avail = stream.available();
2633 byte[] data = new byte[avail];
2634 while (true) {
2635 int amt = stream.read(data, pos, data.length-pos);
2636 //Log.i("foo", "Read " + amt + " bytes at " + pos
2637 // + " of avail " + data.length);
2638 if (amt <= 0) {
2639 //Log.i("foo", "**** FINISHED READING: pos=" + pos
2640 // + " len=" + data.length);
2641 return data;
2642 }
2643 pos += amt;
2644 avail = stream.available();
2645 if (avail > data.length-pos) {
2646 byte[] newData = new byte[pos+avail];
2647 System.arraycopy(data, 0, newData, 0, pos);
2648 data = newData;
2649 }
2650 }
2651 }
2652
2653 public void readLocked() {
2654 if ((mFile == null) || (mBackupFile == null)) {
2655 Log.w("BatteryStats", "readLocked: no file associated with this instance");
2656 return;
2657 }
2658
2659 mUidStats.clear();
2660
2661 FileInputStream stream = null;
2662 if (mBackupFile.exists()) {
2663 try {
2664 stream = new FileInputStream(mBackupFile);
2665 } catch (java.io.IOException e) {
2666 // We'll try for the normal settings file.
2667 }
2668 }
2669
2670 try {
2671 if (stream == null) {
2672 if (!mFile.exists()) {
2673 return;
2674 }
2675 stream = new FileInputStream(mFile);
2676 }
2677
2678 byte[] raw = readFully(stream);
2679 Parcel in = Parcel.obtain();
2680 in.unmarshall(raw, 0, raw.length);
2681 in.setDataPosition(0);
2682 stream.close();
2683
2684 readSummaryFromParcel(in);
2685 } catch(java.io.IOException e) {
2686 Log.e("BatteryStats", "Error reading battery statistics", e);
2687 }
2688 }
2689
2690 public int describeContents() {
2691 return 0;
2692 }
2693
2694 private void readSummaryFromParcel(Parcel in) {
2695 final int version = in.readInt();
2696 if (version != VERSION) {
2697 Log.w("BatteryStats", "readFromParcel: version got " + version
2698 + ", expected " + VERSION + "; erasing old stats");
2699 return;
2700 }
2701
2702 mStartCount = in.readInt();
2703 mBatteryUptime = in.readLong();
2704 mBatteryLastUptime = in.readLong();
2705 mBatteryRealtime = in.readLong();
2706 mBatteryLastRealtime = in.readLong();
2707 mUptime = in.readLong();
2708 mLastUptime = in.readLong();
2709 mRealtime = in.readLong();
2710 mLastRealtime = in.readLong();
Evan Millar633a1742009-04-02 16:36:33 -07002711 mDischargeStartLevel = in.readInt();
2712 mDischargeCurrentLevel = in.readInt();
The Android Open Source Project10592532009-03-18 17:39:46 -07002713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002714 mStartCount++;
2715
2716 mScreenOn = false;
2717 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002718 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
2719 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
2720 }
2721 mInputEventCounter.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002722 mPhoneOn = false;
2723 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002724 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
2725 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
2726 }
2727 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
2728 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
2729 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002730 mWifiOn = false;
2731 mWifiOnTimer.readSummaryFromParcelLocked(in);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002732 mWifiRunning = false;
2733 mWifiRunningTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07002734 mBluetoothOn = false;
2735 mBluetoothOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002736
Evan Millarc64edde2009-04-18 12:26:32 -07002737 int NKW = in.readInt();
2738 for (int ikw = 0; ikw < NKW; ikw++) {
2739 if (in.readInt() != 0) {
2740 String kwltName = in.readString();
2741 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
2742 }
2743 }
2744
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002745 final int NU = in.readInt();
2746 for (int iu = 0; iu < NU; iu++) {
2747 int uid = in.readInt();
2748 Uid u = new Uid(uid);
2749 mUidStats.put(uid, u);
2750
Dianne Hackborn617f8772009-03-31 15:04:46 -07002751 u.mWifiTurnedOn = false;
2752 u.mWifiTurnedOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07002753 u.mFullWifiLockOut = false;
2754 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
2755 u.mScanWifiLockOut = false;
2756 u.mScanWifiLockTimer.readSummaryFromParcelLocked(in);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002757 u.mWifiMulticastEnabled = false;
2758 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
2759
Dianne Hackborn617f8772009-03-31 15:04:46 -07002760 if (in.readInt() != 0) {
2761 if (u.mUserActivityCounters == null) {
2762 u.initUserActivityLocked();
2763 }
2764 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
2765 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
2766 }
2767 }
2768
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002769 int NW = in.readInt();
2770 for (int iw = 0; iw < NW; iw++) {
2771 String wlName = in.readString();
2772 if (in.readInt() != 0) {
2773 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
2774 }
2775 if (in.readInt() != 0) {
2776 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
2777 }
2778 if (in.readInt() != 0) {
2779 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
2780 }
2781 }
2782
2783 int NP = in.readInt();
2784 for (int is = 0; is < NP; is++) {
2785 int seNumber = in.readInt();
2786 if (in.readInt() != 0) {
2787 u.getSensorTimerLocked(seNumber, true)
2788 .readSummaryFromParcelLocked(in);
2789 }
2790 }
2791
2792 NP = in.readInt();
2793 for (int ip = 0; ip < NP; ip++) {
2794 String procName = in.readString();
2795 Uid.Proc p = u.getProcessStatsLocked(procName);
2796 p.mUserTime = p.mLoadedUserTime = in.readLong();
2797 p.mLastUserTime = in.readLong();
2798 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
2799 p.mLastSystemTime = in.readLong();
2800 p.mStarts = p.mLoadedStarts = in.readInt();
2801 p.mLastStarts = in.readInt();
2802 }
2803
2804 NP = in.readInt();
2805 for (int ip = 0; ip < NP; ip++) {
2806 String pkgName = in.readString();
2807 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
2808 p.mWakeups = p.mLoadedWakeups = in.readInt();
2809 p.mLastWakeups = in.readInt();
2810 final int NS = in.readInt();
2811 for (int is = 0; is < NS; is++) {
2812 String servName = in.readString();
2813 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
2814 s.mStartTime = s.mLoadedStartTime = in.readLong();
2815 s.mLastStartTime = in.readLong();
2816 s.mStarts = s.mLoadedStarts = in.readInt();
2817 s.mLastStarts = in.readInt();
2818 s.mLaunches = s.mLoadedLaunches = in.readInt();
2819 s.mLastLaunches = in.readInt();
2820 }
2821 }
2822
2823 u.mLoadedTcpBytesReceived = in.readLong();
2824 u.mLoadedTcpBytesSent = in.readLong();
2825 }
2826 }
2827
2828 /**
2829 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
2830 * disk. This format does not allow a lossless round-trip.
2831 *
2832 * @param out the Parcel to be written to.
2833 */
2834 public void writeSummaryToParcel(Parcel out) {
2835 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
2836 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
2837 final long NOW = getBatteryUptimeLocked(NOW_SYS);
2838 final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS);
2839
2840 out.writeInt(VERSION);
2841
2842 out.writeInt(mStartCount);
2843 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_TOTAL));
2844 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_CURRENT));
2845 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_TOTAL));
2846 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_CURRENT));
2847 out.writeLong(computeUptime(NOW_SYS, STATS_TOTAL));
2848 out.writeLong(computeUptime(NOW_SYS, STATS_CURRENT));
2849 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_TOTAL));
2850 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_CURRENT));
Evan Millar633a1742009-04-02 16:36:33 -07002851 out.writeInt(mDischargeStartLevel);
2852 out.writeInt(mDischargeCurrentLevel);
The Android Open Source Project10592532009-03-18 17:39:46 -07002853
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002854
2855 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn617f8772009-03-31 15:04:46 -07002856 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
2857 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
2858 }
2859 mInputEventCounter.writeSummaryFromParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002860 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Dianne Hackborn627bba72009-03-24 22:32:56 -07002861 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
2862 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
2863 }
2864 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
2865 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
2866 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002867 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07002868 mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07002869 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002870
Evan Millarc64edde2009-04-18 12:26:32 -07002871 out.writeInt(mKernelWakelockStats.size());
2872 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
2873 Timer kwlt = ent.getValue();
2874 if (kwlt != null) {
2875 out.writeInt(1);
2876 out.writeString(ent.getKey());
2877 ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL);
2878 } else {
2879 out.writeInt(0);
2880 }
2881 }
2882
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002883 final int NU = mUidStats.size();
2884 out.writeInt(NU);
2885 for (int iu = 0; iu < NU; iu++) {
2886 out.writeInt(mUidStats.keyAt(iu));
2887 Uid u = mUidStats.valueAt(iu);
The Android Open Source Project10592532009-03-18 17:39:46 -07002888
Dianne Hackborn617f8772009-03-31 15:04:46 -07002889 u.mWifiTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project10592532009-03-18 17:39:46 -07002890 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
2891 u.mScanWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07002892 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002893
Dianne Hackborn617f8772009-03-31 15:04:46 -07002894 if (u.mUserActivityCounters == null) {
2895 out.writeInt(0);
2896 } else {
2897 out.writeInt(1);
2898 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
2899 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
2900 }
2901 }
2902
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002903 int NW = u.mWakelockStats.size();
2904 out.writeInt(NW);
2905 if (NW > 0) {
2906 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent
2907 : u.mWakelockStats.entrySet()) {
2908 out.writeString(ent.getKey());
2909 Uid.Wakelock wl = ent.getValue();
2910 if (wl.mTimerFull != null) {
2911 out.writeInt(1);
2912 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL);
2913 } else {
2914 out.writeInt(0);
2915 }
2916 if (wl.mTimerPartial != null) {
2917 out.writeInt(1);
2918 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL);
2919 } else {
2920 out.writeInt(0);
2921 }
2922 if (wl.mTimerWindow != null) {
2923 out.writeInt(1);
2924 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL);
2925 } else {
2926 out.writeInt(0);
2927 }
2928 }
2929 }
2930
2931 int NSE = u.mSensorStats.size();
2932 out.writeInt(NSE);
2933 if (NSE > 0) {
2934 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent
2935 : u.mSensorStats.entrySet()) {
2936 out.writeInt(ent.getKey());
2937 Uid.Sensor se = ent.getValue();
2938 if (se.mTimer != null) {
2939 out.writeInt(1);
2940 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL);
2941 } else {
2942 out.writeInt(0);
2943 }
2944 }
2945 }
2946
2947 int NP = u.mProcessStats.size();
2948 out.writeInt(NP);
2949 if (NP > 0) {
2950 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent
2951 : u.mProcessStats.entrySet()) {
2952 out.writeString(ent.getKey());
2953 Uid.Proc ps = ent.getValue();
2954 out.writeLong(ps.mUserTime);
2955 out.writeLong(ps.mUserTime - ps.mLoadedUserTime);
2956 out.writeLong(ps.mSystemTime);
2957 out.writeLong(ps.mSystemTime - ps.mLoadedSystemTime);
2958 out.writeInt(ps.mStarts);
2959 out.writeInt(ps.mStarts - ps.mLoadedStarts);
2960 }
2961 }
2962
2963 NP = u.mPackageStats.size();
2964 out.writeInt(NP);
2965 if (NP > 0) {
2966 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
2967 : u.mPackageStats.entrySet()) {
2968 out.writeString(ent.getKey());
2969 Uid.Pkg ps = ent.getValue();
2970 out.writeInt(ps.mWakeups);
2971 out.writeInt(ps.mWakeups - ps.mLoadedWakeups);
2972 final int NS = ps.mServiceStats.size();
2973 out.writeInt(NS);
2974 if (NS > 0) {
2975 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
2976 : ps.mServiceStats.entrySet()) {
2977 out.writeString(sent.getKey());
2978 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
2979 long time = ss.getStartTimeToNowLocked(NOW);
2980 out.writeLong(time);
2981 out.writeLong(time - ss.mLoadedStartTime);
2982 out.writeInt(ss.mStarts);
2983 out.writeInt(ss.mStarts - ss.mLoadedStarts);
2984 out.writeInt(ss.mLaunches);
2985 out.writeInt(ss.mLaunches - ss.mLoadedLaunches);
2986 }
2987 }
2988 }
2989 }
2990
2991 out.writeLong(u.getTcpBytesReceived(STATS_TOTAL));
2992 out.writeLong(u.getTcpBytesSent(STATS_TOTAL));
2993 }
2994 }
2995
2996 public void readFromParcel(Parcel in) {
2997 readFromParcelLocked(in);
2998 }
2999
3000 void readFromParcelLocked(Parcel in) {
3001 int magic = in.readInt();
3002 if (magic != MAGIC) {
3003 throw new ParcelFormatException("Bad magic number");
3004 }
3005
3006 mStartCount = in.readInt();
3007 mBatteryUptime = in.readLong();
3008 mBatteryLastUptime = in.readLong();
3009 mBatteryRealtime = in.readLong();
3010 mBatteryLastRealtime = in.readLong();
3011 mScreenOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003012 mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003013 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07003014 mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003015 }
3016 mInputEventCounter = new Counter(mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003017 mPhoneOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003018 mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003019 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07003020 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003021 }
3022 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Evan Millarc64edde2009-04-18 12:26:32 -07003023 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables, in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003024 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003025 mWifiOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003026 mWifiOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003027 mWifiRunning = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003028 mWifiRunningTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
The Android Open Source Project10592532009-03-18 17:39:46 -07003029 mBluetoothOn = false;
Evan Millarc64edde2009-04-18 12:26:32 -07003030 mBluetoothOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003031 mUptime = in.readLong();
3032 mUptimeStart = in.readLong();
3033 mLastUptime = in.readLong();
3034 mRealtime = in.readLong();
3035 mRealtimeStart = in.readLong();
3036 mLastRealtime = in.readLong();
3037 mOnBattery = in.readInt() != 0;
3038 mOnBatteryInternal = false; // we are no longer really running.
3039 mTrackBatteryPastUptime = in.readLong();
3040 mTrackBatteryUptimeStart = in.readLong();
3041 mTrackBatteryPastRealtime = in.readLong();
3042 mTrackBatteryRealtimeStart = in.readLong();
3043 mUnpluggedBatteryUptime = in.readLong();
3044 mUnpluggedBatteryRealtime = in.readLong();
Evan Millar633a1742009-04-02 16:36:33 -07003045 mDischargeStartLevel = in.readInt();
3046 mDischargeCurrentLevel = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003047 mLastWriteTime = in.readLong();
3048
Evan Millarc64edde2009-04-18 12:26:32 -07003049 mKernelWakelockStats.clear();
3050 int NKW = in.readInt();
3051 for (int ikw = 0; ikw < NKW; ikw++) {
3052 if (in.readInt() != 0) {
3053 String wakelockName = in.readString();
3054 SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in);
3055 mKernelWakelockStats.put(wakelockName, kwlt);
3056 }
3057 }
3058
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003059 mPartialTimers.clear();
3060 mFullTimers.clear();
3061 mWindowTimers.clear();
3062
3063 int numUids = in.readInt();
3064 mUidStats.clear();
3065 for (int i = 0; i < numUids; i++) {
3066 int uid = in.readInt();
3067 Uid u = new Uid(uid);
3068 u.readFromParcelLocked(mUnpluggables, in);
3069 mUidStats.append(uid, u);
3070 }
3071 }
3072
3073 public void writeToParcel(Parcel out, int flags) {
3074 writeToParcelLocked(out, flags);
3075 }
3076
3077 @SuppressWarnings("unused")
3078 void writeToParcelLocked(Parcel out, int flags) {
3079 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
3080 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
3081 final long batteryUptime = getBatteryUptimeLocked(uSecUptime);
3082 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
3083
3084 out.writeInt(MAGIC);
3085 out.writeInt(mStartCount);
3086 out.writeLong(mBatteryUptime);
3087 out.writeLong(mBatteryLastUptime);
3088 out.writeLong(mBatteryRealtime);
3089 out.writeLong(mBatteryLastRealtime);
3090 mScreenOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003091 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
3092 mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime);
3093 }
3094 mInputEventCounter.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003095 mPhoneOnTimer.writeToParcel(out, batteryRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003096 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
3097 mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
3098 }
3099 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
3100 mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime);
3101 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003102 mWifiOnTimer.writeToParcel(out, batteryRealtime);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003103 mWifiRunningTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003104 mBluetoothOnTimer.writeToParcel(out, batteryRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003105 out.writeLong(mUptime);
3106 out.writeLong(mUptimeStart);
3107 out.writeLong(mLastUptime);
3108 out.writeLong(mRealtime);
3109 out.writeLong(mRealtimeStart);
3110 out.writeLong(mLastRealtime);
3111 out.writeInt(mOnBattery ? 1 : 0);
3112 out.writeLong(batteryUptime);
3113 out.writeLong(mTrackBatteryUptimeStart);
3114 out.writeLong(batteryRealtime);
3115 out.writeLong(mTrackBatteryRealtimeStart);
3116 out.writeLong(mUnpluggedBatteryUptime);
3117 out.writeLong(mUnpluggedBatteryRealtime);
Evan Millar633a1742009-04-02 16:36:33 -07003118 out.writeInt(mDischargeStartLevel);
3119 out.writeInt(mDischargeCurrentLevel);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003120 out.writeLong(mLastWriteTime);
3121
Evan Millarc64edde2009-04-18 12:26:32 -07003122 out.writeInt(mKernelWakelockStats.size());
3123 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
3124 SamplingTimer kwlt = ent.getValue();
3125 if (kwlt != null) {
3126 out.writeInt(1);
3127 out.writeString(ent.getKey());
3128 Timer.writeTimerToParcel(out, kwlt, batteryRealtime);
3129 } else {
3130 out.writeInt(0);
3131 }
3132 }
3133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003134 int size = mUidStats.size();
3135 out.writeInt(size);
3136 for (int i = 0; i < size; i++) {
3137 out.writeInt(mUidStats.keyAt(i));
3138 Uid uid = mUidStats.valueAt(i);
3139
3140 uid.writeToParcelLocked(out, batteryRealtime);
3141 }
3142 }
3143
3144 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
3145 new Parcelable.Creator<BatteryStatsImpl>() {
3146 public BatteryStatsImpl createFromParcel(Parcel in) {
3147 return new BatteryStatsImpl(in);
3148 }
3149
3150 public BatteryStatsImpl[] newArray(int size) {
3151 return new BatteryStatsImpl[size];
3152 }
3153 };
3154
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003155 public void dumpLocked(PrintWriter pw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003156 if (DEBUG) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003157 Printer pr = new PrintWriterPrinter(pw);
3158 pr.println("*** Screen timer:");
3159 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07003160 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003161 pr.println("*** Screen brightness #" + i + ":");
3162 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07003163 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003164 pr.println("*** Input event counter:");
3165 mInputEventCounter.logState(pr, " ");
3166 pr.println("*** Phone timer:");
3167 mPhoneOnTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07003168 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003169 pr.println("*** Signal strength #" + i + ":");
3170 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07003171 }
3172 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003173 pr.println("*** Data connection type #" + i + ":");
3174 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07003175 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003176 pr.println("*** Wifi timer:");
3177 mWifiOnTimer.logState(pr, " ");
3178 pr.println("*** WifiRunning timer:");
3179 mWifiRunningTimer.logState(pr, " ");
3180 pr.println("*** Bluetooth timer:");
3181 mBluetoothOnTimer.logState(pr, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003182 }
3183 super.dumpLocked(pw);
3184 }
3185}