blob: b0f3ac3e23a491f03550f854c4822f8f07b6c6f7 [file] [log] [blame]
Kenny Root15a4d2f2010-03-11 18:20:12 -08001/*
2 * Copyright (C) 2008 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080017package android.os;
18
19import java.io.PrintWriter;
Dianne Hackborne4a59512010-12-07 11:08:07 -080020import java.util.ArrayList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import java.util.Formatter;
Dianne Hackborne4a59512010-12-07 11:08:07 -080022import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import java.util.Map;
24
Dianne Hackborne4a59512010-12-07 11:08:07 -080025import android.content.pm.ApplicationInfo;
Wink Saville52840902011-02-18 12:40:47 -080026import android.telephony.SignalStrength;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import android.util.Log;
28import android.util.Printer;
Dianne Hackborn1fadab52011-04-14 17:57:33 -070029import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070031import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032
33/**
34 * A class providing access to battery usage statistics, including information on
35 * wakelocks, processes, packages, and services. All times are represented in microseconds
36 * except where indicated otherwise.
37 * @hide
38 */
39public abstract class BatteryStats implements Parcelable {
40
41 private static final boolean LOCAL_LOGV = false;
42
43 /**
44 * A constant indicating a partial wake lock timer.
45 */
46 public static final int WAKE_TYPE_PARTIAL = 0;
47
48 /**
49 * A constant indicating a full wake lock timer.
50 */
51 public static final int WAKE_TYPE_FULL = 1;
52
53 /**
54 * A constant indicating a window wake lock timer.
55 */
56 public static final int WAKE_TYPE_WINDOW = 2;
57
58 /**
59 * A constant indicating a sensor timer.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060 */
61 public static final int SENSOR = 3;
The Android Open Source Project10592532009-03-18 17:39:46 -070062
63 /**
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070064 * A constant indicating a a wifi running timer
Dianne Hackborn617f8772009-03-31 15:04:46 -070065 */
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070066 public static final int WIFI_RUNNING = 4;
Dianne Hackborn617f8772009-03-31 15:04:46 -070067
68 /**
The Android Open Source Project10592532009-03-18 17:39:46 -070069 * A constant indicating a full wifi lock timer
The Android Open Source Project10592532009-03-18 17:39:46 -070070 */
Dianne Hackborn617f8772009-03-31 15:04:46 -070071 public static final int FULL_WIFI_LOCK = 5;
The Android Open Source Project10592532009-03-18 17:39:46 -070072
73 /**
74 * A constant indicating a scan wifi lock timer
The Android Open Source Project10592532009-03-18 17:39:46 -070075 */
Dianne Hackborn617f8772009-03-31 15:04:46 -070076 public static final int SCAN_WIFI_LOCK = 6;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077
Robert Greenwalt5347bd42009-05-13 15:10:16 -070078 /**
79 * A constant indicating a wifi multicast timer
Robert Greenwalt5347bd42009-05-13 15:10:16 -070080 */
81 public static final int WIFI_MULTICAST_ENABLED = 7;
82
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083 /**
Amith Yamasani244fa5c2009-05-22 14:36:07 -070084 * A constant indicating an audio turn on timer
Amith Yamasani244fa5c2009-05-22 14:36:07 -070085 */
86 public static final int AUDIO_TURNED_ON = 7;
87
88 /**
89 * A constant indicating a video turn on timer
Amith Yamasani244fa5c2009-05-22 14:36:07 -070090 */
91 public static final int VIDEO_TURNED_ON = 8;
92
93 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 * Include all of the data in the stats, including previously saved data.
95 */
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070096 public static final int STATS_SINCE_CHARGED = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097
98 /**
99 * Include only the last run in the stats.
100 */
101 public static final int STATS_LAST = 1;
102
103 /**
104 * Include only the current run in the stats.
105 */
106 public static final int STATS_CURRENT = 2;
107
108 /**
109 * Include only the run since the last time the device was unplugged in the stats.
110 */
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700111 public static final int STATS_SINCE_UNPLUGGED = 3;
Evan Millare84de8d2009-04-02 22:16:12 -0700112
113 // NOTE: Update this list if you add/change any stats above.
114 // These characters are supposed to represent "total", "last", "current",
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700115 // and "unplugged". They were shortened for efficiency sake.
Evan Millare84de8d2009-04-02 22:16:12 -0700116 private static final String[] STAT_NAMES = { "t", "l", "c", "u" };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117
118 /**
119 * Bump the version on this if the checkin format changes.
120 */
Evan Millarc64edde2009-04-18 12:26:32 -0700121 private static final int BATTERY_STATS_CHECKIN_VERSION = 5;
Evan Millar22ac0432009-03-31 11:33:18 -0700122
123 private static final long BYTES_PER_KB = 1024;
124 private static final long BYTES_PER_MB = 1048576; // 1024^2
125 private static final long BYTES_PER_GB = 1073741824; //1024^3
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127
Dianne Hackborne4a59512010-12-07 11:08:07 -0800128 private static final String UID_DATA = "uid";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129 private static final String APK_DATA = "apk";
Evan Millare84de8d2009-04-02 22:16:12 -0700130 private static final String PROCESS_DATA = "pr";
131 private static final String SENSOR_DATA = "sr";
132 private static final String WAKELOCK_DATA = "wl";
Evan Millarc64edde2009-04-18 12:26:32 -0700133 private static final String KERNEL_WAKELOCK_DATA = "kwl";
Evan Millare84de8d2009-04-02 22:16:12 -0700134 private static final String NETWORK_DATA = "nt";
135 private static final String USER_ACTIVITY_DATA = "ua";
136 private static final String BATTERY_DATA = "bt";
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800137 private static final String BATTERY_DISCHARGE_DATA = "dc";
Evan Millare84de8d2009-04-02 22:16:12 -0700138 private static final String BATTERY_LEVEL_DATA = "lv";
139 private static final String WIFI_LOCK_DATA = "wfl";
140 private static final String MISC_DATA = "m";
141 private static final String SCREEN_BRIGHTNESS_DATA = "br";
142 private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt";
Amith Yamasanif37447b2009-10-08 18:28:01 -0700143 private static final String SIGNAL_SCANNING_TIME_DATA = "sst";
Evan Millare84de8d2009-04-02 22:16:12 -0700144 private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc";
145 private static final String DATA_CONNECTION_TIME_DATA = "dct";
146 private static final String DATA_CONNECTION_COUNT_DATA = "dcc";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700148 private final StringBuilder mFormatBuilder = new StringBuilder(32);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 private final Formatter mFormatter = new Formatter(mFormatBuilder);
150
151 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700152 * State for keeping track of counting information.
153 */
154 public static abstract class Counter {
155
156 /**
157 * Returns the count associated with this Counter for the
158 * selected type of statistics.
159 *
160 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
161 */
Evan Millarc64edde2009-04-18 12:26:32 -0700162 public abstract int getCountLocked(int which);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700163
164 /**
165 * Temporary for debugging.
166 */
167 public abstract void logState(Printer pw, String prefix);
168 }
169
170 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 * State for keeping track of timing information.
172 */
173 public static abstract class Timer {
174
175 /**
176 * Returns the count associated with this Timer for the
177 * selected type of statistics.
178 *
179 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
180 */
Evan Millarc64edde2009-04-18 12:26:32 -0700181 public abstract int getCountLocked(int which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182
183 /**
184 * Returns the total time in microseconds associated with this Timer for the
185 * selected type of statistics.
186 *
187 * @param batteryRealtime system realtime on battery in microseconds
188 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
189 * @return a time in microseconds
190 */
Evan Millarc64edde2009-04-18 12:26:32 -0700191 public abstract long getTotalTimeLocked(long batteryRealtime, int which);
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193 /**
194 * Temporary for debugging.
195 */
Dianne Hackborn627bba72009-03-24 22:32:56 -0700196 public abstract void logState(Printer pw, String prefix);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 }
198
199 /**
200 * The statistics associated with a particular uid.
201 */
202 public static abstract class Uid {
203
204 /**
205 * Returns a mapping containing wakelock statistics.
206 *
207 * @return a Map from Strings to Uid.Wakelock objects.
208 */
209 public abstract Map<String, ? extends Wakelock> getWakelockStats();
210
211 /**
212 * The statistics associated with a particular wake lock.
213 */
214 public static abstract class Wakelock {
215 public abstract Timer getWakeTime(int type);
216 }
217
218 /**
219 * Returns a mapping containing sensor statistics.
220 *
221 * @return a Map from Integer sensor ids to Uid.Sensor objects.
222 */
223 public abstract Map<Integer, ? extends Sensor> getSensorStats();
224
225 /**
Dianne Hackbornb5e31652010-09-07 12:13:55 -0700226 * Returns a mapping containing active process data.
227 */
228 public abstract SparseArray<? extends Pid> getPidStats();
229
230 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 * Returns a mapping containing process statistics.
232 *
233 * @return a Map from Strings to Uid.Proc objects.
234 */
235 public abstract Map<String, ? extends Proc> getProcessStats();
236
237 /**
238 * Returns a mapping containing package statistics.
239 *
240 * @return a Map from Strings to Uid.Pkg objects.
241 */
242 public abstract Map<String, ? extends Pkg> getPackageStats();
243
244 /**
245 * {@hide}
246 */
247 public abstract int getUid();
248
249 /**
250 * {@hide}
251 */
252 public abstract long getTcpBytesReceived(int which);
253
254 /**
255 * {@hide}
256 */
257 public abstract long getTcpBytesSent(int which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700258
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700259 public abstract void noteWifiRunningLocked();
260 public abstract void noteWifiStoppedLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -0700261 public abstract void noteFullWifiLockAcquiredLocked();
262 public abstract void noteFullWifiLockReleasedLocked();
263 public abstract void noteScanWifiLockAcquiredLocked();
264 public abstract void noteScanWifiLockReleasedLocked();
Robert Greenwalt5347bd42009-05-13 15:10:16 -0700265 public abstract void noteWifiMulticastEnabledLocked();
266 public abstract void noteWifiMulticastDisabledLocked();
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700267 public abstract void noteAudioTurnedOnLocked();
268 public abstract void noteAudioTurnedOffLocked();
269 public abstract void noteVideoTurnedOnLocked();
270 public abstract void noteVideoTurnedOffLocked();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700271 public abstract long getWifiRunningTime(long batteryRealtime, int which);
The Android Open Source Project10592532009-03-18 17:39:46 -0700272 public abstract long getFullWifiLockTime(long batteryRealtime, int which);
273 public abstract long getScanWifiLockTime(long batteryRealtime, int which);
Robert Greenwalt5347bd42009-05-13 15:10:16 -0700274 public abstract long getWifiMulticastTime(long batteryRealtime,
275 int which);
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700276 public abstract long getAudioTurnedOnTime(long batteryRealtime, int which);
277 public abstract long getVideoTurnedOnTime(long batteryRealtime, int which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278
Dianne Hackborn617f8772009-03-31 15:04:46 -0700279 /**
280 * Note that these must match the constants in android.os.LocalPowerManager.
281 */
282 static final String[] USER_ACTIVITY_TYPES = {
283 "other", "cheek", "touch", "long_touch", "touch_up", "button", "unknown"
284 };
285
286 public static final int NUM_USER_ACTIVITY_TYPES = 7;
287
288 public abstract void noteUserActivityLocked(int type);
289 public abstract boolean hasUserActivity();
290 public abstract int getUserActivityCount(int type, int which);
291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292 public static abstract class Sensor {
293 // Magic sensor number for the GPS.
294 public static final int GPS = -10000;
295
296 public abstract int getHandle();
297
298 public abstract Timer getSensorTime();
299 }
300
Dianne Hackbornb5e31652010-09-07 12:13:55 -0700301 public class Pid {
302 public long mWakeSum;
303 public long mWakeStart;
304 }
305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 /**
307 * The statistics associated with a particular process.
308 */
309 public static abstract class Proc {
310
Dianne Hackborn287952c2010-09-22 22:34:31 -0700311 public static class ExcessivePower {
312 public static final int TYPE_WAKE = 1;
313 public static final int TYPE_CPU = 2;
314
315 public int type;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700316 public long overTime;
317 public long usedTime;
318 }
319
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 /**
321 * Returns the total time (in 1/100 sec) spent executing in user code.
322 *
323 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
324 */
325 public abstract long getUserTime(int which);
326
327 /**
328 * Returns the total time (in 1/100 sec) spent executing in system code.
329 *
330 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
331 */
332 public abstract long getSystemTime(int which);
333
334 /**
335 * Returns the number of times the process has been started.
336 *
337 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
338 */
339 public abstract int getStarts(int which);
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700340
341 /**
342 * Returns the cpu time spent in microseconds while the process was in the foreground.
343 * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED
344 * @return foreground cpu time in microseconds
345 */
346 public abstract long getForegroundTime(int which);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700347
348 /**
349 * Returns the approximate cpu time spent in microseconds, at a certain CPU speed.
350 * @param speedStep the index of the CPU speed. This is not the actual speed of the
351 * CPU.
352 * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED
353 * @see BatteryStats#getCpuSpeedSteps()
354 */
355 public abstract long getTimeAtCpuSpeedStep(int speedStep, int which);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700356
Dianne Hackborn287952c2010-09-22 22:34:31 -0700357 public abstract int countExcessivePowers();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700358
Dianne Hackborn287952c2010-09-22 22:34:31 -0700359 public abstract ExcessivePower getExcessivePower(int i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360 }
361
362 /**
363 * The statistics associated with a particular package.
364 */
365 public static abstract class Pkg {
366
367 /**
368 * Returns the number of times this package has done something that could wake up the
369 * device from sleep.
370 *
371 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
372 */
373 public abstract int getWakeups(int which);
374
375 /**
376 * Returns a mapping containing service statistics.
377 */
378 public abstract Map<String, ? extends Serv> getServiceStats();
379
380 /**
381 * The statistics associated with a particular service.
382 */
383 public abstract class Serv {
384
385 /**
386 * Returns the amount of time spent started.
387 *
388 * @param batteryUptime elapsed uptime on battery in microseconds.
389 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
390 * @return
391 */
392 public abstract long getStartTime(long batteryUptime, int which);
393
394 /**
395 * Returns the total number of times startService() has been called.
396 *
397 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
398 */
399 public abstract int getStarts(int which);
400
401 /**
402 * Returns the total number times the service has been launched.
403 *
404 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
405 */
406 public abstract int getLaunches(int which);
407 }
408 }
409 }
410
Dianne Hackbornce2ef762010-09-20 11:39:14 -0700411 public final static class HistoryItem implements Parcelable {
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700412 static final String TAG = "HistoryItem";
413 static final boolean DEBUG = false;
414
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700415 public HistoryItem next;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700416
417 public long time;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700418
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700419 public static final byte CMD_NULL = 0;
420 public static final byte CMD_UPDATE = 1;
421 public static final byte CMD_START = 2;
422 public static final byte CMD_OVERFLOW = 3;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700423
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700424 public byte cmd = CMD_NULL;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700425
426 public byte batteryLevel;
427 public byte batteryStatus;
428 public byte batteryHealth;
429 public byte batteryPlugType;
430
431 public char batteryTemperature;
432 public char batteryVoltage;
433
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700434 // Constants from SCREEN_BRIGHTNESS_*
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700435 public static final int STATE_BRIGHTNESS_MASK = 0x0000000f;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700436 public static final int STATE_BRIGHTNESS_SHIFT = 0;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700437 // Constants from SIGNAL_STRENGTH_*
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700438 public static final int STATE_SIGNAL_STRENGTH_MASK = 0x000000f0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700439 public static final int STATE_SIGNAL_STRENGTH_SHIFT = 4;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700440 // Constants from ServiceState.STATE_*
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700441 public static final int STATE_PHONE_STATE_MASK = 0x00000f00;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700442 public static final int STATE_PHONE_STATE_SHIFT = 8;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700443 // Constants from DATA_CONNECTION_*
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700444 public static final int STATE_DATA_CONNECTION_MASK = 0x0000f000;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700445 public static final int STATE_DATA_CONNECTION_SHIFT = 12;
446
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700447 // These states always appear directly in the first int token
448 // of a delta change; they should be ones that change relatively
449 // frequently.
450 public static final int STATE_WAKE_LOCK_FLAG = 1<<30;
451 public static final int STATE_SENSOR_ON_FLAG = 1<<29;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700452 public static final int STATE_GPS_ON_FLAG = 1<<28;
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700453 public static final int STATE_PHONE_SCANNING_FLAG = 1<<27;
454 public static final int STATE_WIFI_RUNNING_FLAG = 1<<26;
455 public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<25;
456 public static final int STATE_WIFI_SCAN_LOCK_FLAG = 1<<24;
457 public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<23;
458 // These are on the lower bits used for the command; if they change
459 // we need to write another int of data.
460 public static final int STATE_AUDIO_ON_FLAG = 1<<22;
461 public static final int STATE_VIDEO_ON_FLAG = 1<<21;
462 public static final int STATE_SCREEN_ON_FLAG = 1<<20;
463 public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19;
464 public static final int STATE_PHONE_IN_CALL_FLAG = 1<<18;
465 public static final int STATE_WIFI_ON_FLAG = 1<<17;
466 public static final int STATE_BLUETOOTH_ON_FLAG = 1<<16;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700467
Dianne Hackbornf47d8f22010-10-08 10:46:55 -0700468 public static final int MOST_INTERESTING_STATES =
469 STATE_BATTERY_PLUGGED_FLAG | STATE_SCREEN_ON_FLAG
470 | STATE_GPS_ON_FLAG | STATE_PHONE_IN_CALL_FLAG;
471
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700472 public int states;
473
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700474 public HistoryItem() {
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700475 }
476
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700477 public HistoryItem(long time, Parcel src) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700478 this.time = time;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700479 readFromParcel(src);
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700480 }
481
482 public int describeContents() {
483 return 0;
484 }
485
486 public void writeToParcel(Parcel dest, int flags) {
487 dest.writeLong(time);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700488 int bat = (((int)cmd)&0xff)
489 | ((((int)batteryLevel)<<8)&0xff00)
490 | ((((int)batteryStatus)<<16)&0xf0000)
491 | ((((int)batteryHealth)<<20)&0xf00000)
492 | ((((int)batteryPlugType)<<24)&0xf000000);
493 dest.writeInt(bat);
494 bat = (((int)batteryTemperature)&0xffff)
495 | ((((int)batteryVoltage)<<16)&0xffff0000);
496 dest.writeInt(bat);
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700497 dest.writeInt(states);
498 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700499
500 private void readFromParcel(Parcel src) {
501 int bat = src.readInt();
502 cmd = (byte)(bat&0xff);
503 batteryLevel = (byte)((bat>>8)&0xff);
504 batteryStatus = (byte)((bat>>16)&0xf);
505 batteryHealth = (byte)((bat>>20)&0xf);
506 batteryPlugType = (byte)((bat>>24)&0xf);
507 bat = src.readInt();
508 batteryTemperature = (char)(bat&0xffff);
509 batteryVoltage = (char)((bat>>16)&0xffff);
510 states = src.readInt();
511 }
512
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700513 // Part of initial delta int that specifies the time delta.
514 static final int DELTA_TIME_MASK = 0x3ffff;
515 static final int DELTA_TIME_ABS = 0x3fffd; // Following is an entire abs update.
516 static final int DELTA_TIME_INT = 0x3fffe; // The delta is a following int
517 static final int DELTA_TIME_LONG = 0x3ffff; // The delta is a following long
518 // Part of initial delta int holding the command code.
519 static final int DELTA_CMD_MASK = 0x3;
520 static final int DELTA_CMD_SHIFT = 18;
521 // Flag in delta int: a new battery level int follows.
522 static final int DELTA_BATTERY_LEVEL_FLAG = 1<<20;
523 // Flag in delta int: a new full state and battery status int follows.
524 static final int DELTA_STATE_FLAG = 1<<21;
525 static final int DELTA_STATE_MASK = 0xffc00000;
526
527 public void writeDelta(Parcel dest, HistoryItem last) {
528 if (last == null || last.cmd != CMD_UPDATE) {
529 dest.writeInt(DELTA_TIME_ABS);
530 writeToParcel(dest, 0);
531 return;
532 }
533
534 final long deltaTime = time - last.time;
535 final int lastBatteryLevelInt = last.buildBatteryLevelInt();
536 final int lastStateInt = last.buildStateInt();
537
538 int deltaTimeToken;
539 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) {
540 deltaTimeToken = DELTA_TIME_LONG;
541 } else if (deltaTime >= DELTA_TIME_ABS) {
542 deltaTimeToken = DELTA_TIME_INT;
543 } else {
544 deltaTimeToken = (int)deltaTime;
545 }
546 int firstToken = deltaTimeToken
547 | (cmd<<DELTA_CMD_SHIFT)
548 | (states&DELTA_STATE_MASK);
549 final int batteryLevelInt = buildBatteryLevelInt();
550 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt;
551 if (batteryLevelIntChanged) {
552 firstToken |= DELTA_BATTERY_LEVEL_FLAG;
553 }
554 final int stateInt = buildStateInt();
555 final boolean stateIntChanged = stateInt != lastStateInt;
556 if (stateIntChanged) {
557 firstToken |= DELTA_STATE_FLAG;
558 }
559 dest.writeInt(firstToken);
560 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken)
561 + " deltaTime=" + deltaTime);
562
563 if (deltaTimeToken >= DELTA_TIME_INT) {
564 if (deltaTimeToken == DELTA_TIME_INT) {
565 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime);
566 dest.writeInt((int)deltaTime);
567 } else {
568 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime);
569 dest.writeLong(deltaTime);
570 }
571 }
572 if (batteryLevelIntChanged) {
573 dest.writeInt(batteryLevelInt);
574 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x"
575 + Integer.toHexString(batteryLevelInt)
576 + " batteryLevel=" + batteryLevel
577 + " batteryTemp=" + (int)batteryTemperature
578 + " batteryVolt=" + (int)batteryVoltage);
579 }
580 if (stateIntChanged) {
581 dest.writeInt(stateInt);
582 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x"
583 + Integer.toHexString(stateInt)
584 + " batteryStatus=" + batteryStatus
585 + " batteryHealth=" + batteryHealth
586 + " batteryPlugType=" + batteryPlugType
587 + " states=0x" + Integer.toHexString(states));
588 }
589 }
590
591 private int buildBatteryLevelInt() {
592 return ((((int)batteryLevel)<<24)&0xff000000)
593 | ((((int)batteryTemperature)<<14)&0x00ffc000)
594 | (((int)batteryVoltage)&0x00003fff);
595 }
596
597 private int buildStateInt() {
598 return ((((int)batteryStatus)<<28)&0xf0000000)
599 | ((((int)batteryHealth)<<24)&0x0f000000)
600 | ((((int)batteryPlugType)<<22)&0x00c00000)
601 | (states&(~DELTA_STATE_MASK));
602 }
603
604 public void readDelta(Parcel src) {
605 int firstToken = src.readInt();
606 int deltaTimeToken = firstToken&DELTA_TIME_MASK;
607 cmd = (byte)((firstToken>>DELTA_CMD_SHIFT)&DELTA_CMD_MASK);
608 if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken)
609 + " deltaTimeToken=" + deltaTimeToken);
610
611 if (deltaTimeToken < DELTA_TIME_ABS) {
612 time += deltaTimeToken;
613 } else if (deltaTimeToken == DELTA_TIME_ABS) {
614 time = src.readLong();
615 readFromParcel(src);
616 return;
617 } else if (deltaTimeToken == DELTA_TIME_INT) {
618 int delta = src.readInt();
619 time += delta;
620 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + time);
621 } else {
622 long delta = src.readLong();
623 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + time);
624 time += delta;
625 }
626
627 if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) {
628 int batteryLevelInt = src.readInt();
629 batteryLevel = (byte)((batteryLevelInt>>24)&0xff);
630 batteryTemperature = (char)((batteryLevelInt>>14)&0x3ff);
631 batteryVoltage = (char)(batteryLevelInt&0x3fff);
632 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x"
633 + Integer.toHexString(batteryLevelInt)
634 + " batteryLevel=" + batteryLevel
635 + " batteryTemp=" + (int)batteryTemperature
636 + " batteryVolt=" + (int)batteryVoltage);
637 }
638
639 if ((firstToken&DELTA_STATE_FLAG) != 0) {
640 int stateInt = src.readInt();
641 states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~DELTA_STATE_MASK));
642 batteryStatus = (byte)((stateInt>>28)&0xf);
643 batteryHealth = (byte)((stateInt>>24)&0xf);
644 batteryPlugType = (byte)((stateInt>>22)&0x3);
645 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x"
646 + Integer.toHexString(stateInt)
647 + " batteryStatus=" + batteryStatus
648 + " batteryHealth=" + batteryHealth
649 + " batteryPlugType=" + batteryPlugType
650 + " states=0x" + Integer.toHexString(states));
651 } else {
652 states = (firstToken&DELTA_STATE_MASK) | (states&(~DELTA_STATE_MASK));
653 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700654 }
655
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700656 public void clear() {
657 time = 0;
658 cmd = CMD_NULL;
659 batteryLevel = 0;
660 batteryStatus = 0;
661 batteryHealth = 0;
662 batteryPlugType = 0;
663 batteryTemperature = 0;
664 batteryVoltage = 0;
665 states = 0;
666 }
667
Dianne Hackbornce2ef762010-09-20 11:39:14 -0700668 public void setTo(HistoryItem o) {
669 time = o.time;
670 cmd = o.cmd;
671 batteryLevel = o.batteryLevel;
672 batteryStatus = o.batteryStatus;
673 batteryHealth = o.batteryHealth;
674 batteryPlugType = o.batteryPlugType;
675 batteryTemperature = o.batteryTemperature;
676 batteryVoltage = o.batteryVoltage;
677 states = o.states;
678 }
679
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700680 public void setTo(long time, byte cmd, HistoryItem o) {
681 this.time = time;
682 this.cmd = cmd;
683 batteryLevel = o.batteryLevel;
684 batteryStatus = o.batteryStatus;
685 batteryHealth = o.batteryHealth;
686 batteryPlugType = o.batteryPlugType;
687 batteryTemperature = o.batteryTemperature;
688 batteryVoltage = o.batteryVoltage;
689 states = o.states;
690 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700691
692 public boolean same(HistoryItem o) {
693 return batteryLevel == o.batteryLevel
694 && batteryStatus == o.batteryStatus
695 && batteryHealth == o.batteryHealth
696 && batteryPlugType == o.batteryPlugType
697 && batteryTemperature == o.batteryTemperature
698 && batteryVoltage == o.batteryVoltage
699 && states == o.states;
700 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700701 }
702
703 public static final class BitDescription {
704 public final int mask;
705 public final int shift;
706 public final String name;
707 public final String[] values;
708
709 public BitDescription(int mask, String name) {
710 this.mask = mask;
711 this.shift = -1;
712 this.name = name;
713 this.values = null;
714 }
715
716 public BitDescription(int mask, int shift, String name, String[] values) {
717 this.mask = mask;
718 this.shift = shift;
719 this.name = name;
720 this.values = values;
721 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700722 }
723
Dianne Hackbornce2ef762010-09-20 11:39:14 -0700724 public abstract boolean startIteratingHistoryLocked();
725
726 public abstract boolean getNextHistoryLocked(HistoryItem out);
727
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700728 public abstract void finishIteratingHistoryLocked();
729
730 public abstract boolean startIteratingOldHistoryLocked();
731
732 public abstract boolean getNextOldHistoryLocked(HistoryItem out);
733
734 public abstract void finishIteratingOldHistoryLocked();
735
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800736 /**
Dianne Hackbornb5e31652010-09-07 12:13:55 -0700737 * Return the base time offset for the battery history.
738 */
739 public abstract long getHistoryBaseTime();
740
741 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800742 * Returns the number of times the device has been started.
743 */
744 public abstract int getStartCount();
745
746 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700747 * Returns the time in microseconds that the screen has been on while the device was
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748 * running on battery.
749 *
750 * {@hide}
751 */
752 public abstract long getScreenOnTime(long batteryRealtime, int which);
753
Dianne Hackborn617f8772009-03-31 15:04:46 -0700754 public static final int SCREEN_BRIGHTNESS_DARK = 0;
755 public static final int SCREEN_BRIGHTNESS_DIM = 1;
756 public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
757 public static final int SCREEN_BRIGHTNESS_LIGHT = 3;
758 public static final int SCREEN_BRIGHTNESS_BRIGHT = 4;
759
760 static final String[] SCREEN_BRIGHTNESS_NAMES = {
761 "dark", "dim", "medium", "light", "bright"
762 };
763
764 public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
765
766 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700767 * Returns the time in microseconds that the screen has been on with
Dianne Hackborn617f8772009-03-31 15:04:46 -0700768 * the given brightness
769 *
770 * {@hide}
771 */
772 public abstract long getScreenBrightnessTime(int brightnessBin,
773 long batteryRealtime, int which);
774
775 public abstract int getInputEventCount(int which);
776
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800777 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700778 * Returns the time in microseconds that the phone has been on while the device was
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779 * running on battery.
780 *
781 * {@hide}
782 */
783 public abstract long getPhoneOnTime(long batteryRealtime, int which);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700784
785 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700786 * Returns the time in microseconds that the phone has been running with
Dianne Hackborn627bba72009-03-24 22:32:56 -0700787 * the given signal strength.
788 *
789 * {@hide}
790 */
791 public abstract long getPhoneSignalStrengthTime(int strengthBin,
792 long batteryRealtime, int which);
793
Dianne Hackborn617f8772009-03-31 15:04:46 -0700794 /**
Amith Yamasanif37447b2009-10-08 18:28:01 -0700795 * Returns the time in microseconds that the phone has been trying to
796 * acquire a signal.
797 *
798 * {@hide}
799 */
800 public abstract long getPhoneSignalScanningTime(
801 long batteryRealtime, int which);
802
803 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700804 * Returns the number of times the phone has entered the given signal strength.
805 *
806 * {@hide}
807 */
808 public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
809
Dianne Hackborn627bba72009-03-24 22:32:56 -0700810 public static final int DATA_CONNECTION_NONE = 0;
811 public static final int DATA_CONNECTION_GPRS = 1;
812 public static final int DATA_CONNECTION_EDGE = 2;
813 public static final int DATA_CONNECTION_UMTS = 3;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700814 public static final int DATA_CONNECTION_CDMA = 4;
815 public static final int DATA_CONNECTION_EVDO_0 = 5;
816 public static final int DATA_CONNECTION_EVDO_A = 6;
817 public static final int DATA_CONNECTION_1xRTT = 7;
818 public static final int DATA_CONNECTION_HSDPA = 8;
819 public static final int DATA_CONNECTION_HSUPA = 9;
820 public static final int DATA_CONNECTION_HSPA = 10;
821 public static final int DATA_CONNECTION_IDEN = 11;
822 public static final int DATA_CONNECTION_EVDO_B = 12;
Robert Greenwalt962a9902010-11-02 11:10:25 -0700823 public static final int DATA_CONNECTION_LTE = 13;
824 public static final int DATA_CONNECTION_EHRPD = 14;
825 public static final int DATA_CONNECTION_OTHER = 15;
826
Dianne Hackborn627bba72009-03-24 22:32:56 -0700827 static final String[] DATA_CONNECTION_NAMES = {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700828 "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A",
Robert Greenwalt962a9902010-11-02 11:10:25 -0700829 "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte",
830 "ehrpd", "other"
Dianne Hackborn627bba72009-03-24 22:32:56 -0700831 };
832
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700833 public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1;
Dianne Hackborn627bba72009-03-24 22:32:56 -0700834
835 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700836 * Returns the time in microseconds that the phone has been running with
Dianne Hackborn627bba72009-03-24 22:32:56 -0700837 * the given data connection.
838 *
839 * {@hide}
840 */
841 public abstract long getPhoneDataConnectionTime(int dataType,
842 long batteryRealtime, int which);
843
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800844 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700845 * Returns the number of times the phone has entered the given data
846 * connection type.
847 *
848 * {@hide}
849 */
850 public abstract int getPhoneDataConnectionCount(int dataType, int which);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700851
852 public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS
853 = new BitDescription[] {
854 new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged"),
855 new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen"),
856 new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps"),
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700857 new BitDescription(HistoryItem.STATE_PHONE_IN_CALL_FLAG, "phone_in_call"),
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700858 new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning"),
859 new BitDescription(HistoryItem.STATE_WIFI_ON_FLAG, "wifi"),
860 new BitDescription(HistoryItem.STATE_WIFI_RUNNING_FLAG, "wifi_running"),
861 new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock"),
862 new BitDescription(HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG, "wifi_scan_lock"),
863 new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast"),
864 new BitDescription(HistoryItem.STATE_BLUETOOTH_ON_FLAG, "bluetooth"),
865 new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio"),
866 new BitDescription(HistoryItem.STATE_VIDEO_ON_FLAG, "video"),
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700867 new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock"),
868 new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor"),
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700869 new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK,
870 HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness",
871 SCREEN_BRIGHTNESS_NAMES),
872 new BitDescription(HistoryItem.STATE_SIGNAL_STRENGTH_MASK,
873 HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT, "signal_strength",
Wink Saville52840902011-02-18 12:40:47 -0800874 SignalStrength.SIGNAL_STRENGTH_NAMES),
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700875 new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK,
876 HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state",
877 new String[] {"in", "out", "emergency", "off"}),
878 new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK,
879 HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn",
880 DATA_CONNECTION_NAMES),
881 };
Dianne Hackborn617f8772009-03-31 15:04:46 -0700882
883 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700884 * Returns the time in microseconds that wifi has been on while the device was
The Android Open Source Project10592532009-03-18 17:39:46 -0700885 * running on battery.
886 *
887 * {@hide}
888 */
889 public abstract long getWifiOnTime(long batteryRealtime, int which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700890
891 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700892 * Returns the time in microseconds that wifi has been on and the driver has
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700893 * been in the running state while the device was running on battery.
894 *
895 * {@hide}
896 */
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700897 public abstract long getGlobalWifiRunningTime(long batteryRealtime, int which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700898
The Android Open Source Project10592532009-03-18 17:39:46 -0700899 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -0700900 * Returns the time in microseconds that bluetooth has been on while the device was
The Android Open Source Project10592532009-03-18 17:39:46 -0700901 * running on battery.
902 *
903 * {@hide}
904 */
905 public abstract long getBluetoothOnTime(long batteryRealtime, int which);
906
907 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800908 * Return whether we are currently running on battery.
909 */
910 public abstract boolean getIsOnBattery();
911
912 /**
913 * Returns a SparseArray containing the statistics for each uid.
914 */
915 public abstract SparseArray<? extends Uid> getUidStats();
916
917 /**
918 * Returns the current battery uptime in microseconds.
919 *
920 * @param curTime the amount of elapsed realtime in microseconds.
921 */
922 public abstract long getBatteryUptime(long curTime);
923
924 /**
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700925 * @deprecated use getRadioDataUptime
926 */
927 public long getRadioDataUptimeMs() {
928 return getRadioDataUptime() / 1000;
929 }
930
931 /**
932 * Returns the time that the radio was on for data transfers.
933 * @return the uptime in microseconds while unplugged
934 */
935 public abstract long getRadioDataUptime();
936
937 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800938 * Returns the current battery realtime in microseconds.
939 *
940 * @param curTime the amount of elapsed realtime in microseconds.
941 */
942 public abstract long getBatteryRealtime(long curTime);
The Android Open Source Project10592532009-03-18 17:39:46 -0700943
944 /**
Evan Millar633a1742009-04-02 16:36:33 -0700945 * Returns the battery percentage level at the last time the device was unplugged from power, or
946 * the last time it booted on battery power.
The Android Open Source Project10592532009-03-18 17:39:46 -0700947 */
Evan Millar633a1742009-04-02 16:36:33 -0700948 public abstract int getDischargeStartLevel();
The Android Open Source Project10592532009-03-18 17:39:46 -0700949
950 /**
Evan Millar633a1742009-04-02 16:36:33 -0700951 * Returns the current battery percentage level if we are in a discharge cycle, otherwise
952 * returns the level at the last plug event.
The Android Open Source Project10592532009-03-18 17:39:46 -0700953 */
Evan Millar633a1742009-04-02 16:36:33 -0700954 public abstract int getDischargeCurrentLevel();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800955
956 /**
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700957 * Get the amount the battery has discharged since the stats were
958 * last reset after charging, as a lower-end approximation.
959 */
960 public abstract int getLowDischargeAmountSinceCharge();
961
962 /**
963 * Get the amount the battery has discharged since the stats were
964 * last reset after charging, as an upper-end approximation.
965 */
966 public abstract int getHighDischargeAmountSinceCharge();
967
968 /**
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800969 * Get the amount the battery has discharged while the screen was on,
970 * since the last time power was unplugged.
971 */
972 public abstract int getDischargeAmountScreenOn();
973
974 /**
975 * Get the amount the battery has discharged while the screen was on,
976 * since the last time the device was charged.
977 */
978 public abstract int getDischargeAmountScreenOnSinceCharge();
979
980 /**
981 * Get the amount the battery has discharged while the screen was off,
982 * since the last time power was unplugged.
983 */
984 public abstract int getDischargeAmountScreenOff();
985
986 /**
987 * Get the amount the battery has discharged while the screen was off,
988 * since the last time the device was charged.
989 */
990 public abstract int getDischargeAmountScreenOffSinceCharge();
991
992 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800993 * Returns the total, last, or current battery uptime in microseconds.
994 *
995 * @param curTime the elapsed realtime in microseconds.
996 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
997 */
998 public abstract long computeBatteryUptime(long curTime, int which);
999
1000 /**
1001 * Returns the total, last, or current battery realtime in microseconds.
1002 *
1003 * @param curTime the current elapsed realtime in microseconds.
1004 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
1005 */
1006 public abstract long computeBatteryRealtime(long curTime, int which);
1007
1008 /**
1009 * Returns the total, last, or current uptime in microseconds.
1010 *
1011 * @param curTime the current elapsed realtime in microseconds.
1012 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
1013 */
1014 public abstract long computeUptime(long curTime, int which);
1015
1016 /**
1017 * Returns the total, last, or current realtime in microseconds.
1018 * *
1019 * @param curTime the current elapsed realtime in microseconds.
1020 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
1021 */
1022 public abstract long computeRealtime(long curTime, int which);
Evan Millarc64edde2009-04-18 12:26:32 -07001023
1024 public abstract Map<String, ? extends Timer> getKernelWakelockStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001025
Amith Yamasanie43530a2009-08-21 13:11:37 -07001026 /** Returns the number of different speeds that the CPU can run at */
1027 public abstract int getCpuSpeedSteps();
1028
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001029 private final static void formatTimeRaw(StringBuilder out, long seconds) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001030 long days = seconds / (60 * 60 * 24);
1031 if (days != 0) {
1032 out.append(days);
1033 out.append("d ");
1034 }
1035 long used = days * 60 * 60 * 24;
1036
1037 long hours = (seconds - used) / (60 * 60);
1038 if (hours != 0 || used != 0) {
1039 out.append(hours);
1040 out.append("h ");
1041 }
1042 used += hours * 60 * 60;
1043
1044 long mins = (seconds-used) / 60;
1045 if (mins != 0 || used != 0) {
1046 out.append(mins);
1047 out.append("m ");
1048 }
1049 used += mins * 60;
1050
1051 if (seconds != 0 || used != 0) {
1052 out.append(seconds-used);
1053 out.append("s ");
1054 }
1055 }
1056
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001057 private final static void formatTime(StringBuilder sb, long time) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001058 long sec = time / 100;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001059 formatTimeRaw(sb, sec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001060 sb.append((time - (sec * 100)) * 10);
1061 sb.append("ms ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062 }
1063
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001064 private final static void formatTimeMs(StringBuilder sb, long time) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001065 long sec = time / 1000;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001066 formatTimeRaw(sb, sec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001067 sb.append(time - (sec * 1000));
1068 sb.append("ms ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001069 }
1070
1071 private final String formatRatioLocked(long num, long den) {
1072 if (den == 0L) {
1073 return "---%";
1074 }
1075 float perc = ((float)num) / ((float)den) * 100;
1076 mFormatBuilder.setLength(0);
1077 mFormatter.format("%.1f%%", perc);
1078 return mFormatBuilder.toString();
1079 }
1080
Evan Millar22ac0432009-03-31 11:33:18 -07001081 private final String formatBytesLocked(long bytes) {
1082 mFormatBuilder.setLength(0);
1083
1084 if (bytes < BYTES_PER_KB) {
1085 return bytes + "B";
1086 } else if (bytes < BYTES_PER_MB) {
1087 mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB);
1088 return mFormatBuilder.toString();
1089 } else if (bytes < BYTES_PER_GB){
1090 mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB);
1091 return mFormatBuilder.toString();
1092 } else {
1093 mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB);
1094 return mFormatBuilder.toString();
1095 }
1096 }
1097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001098 /**
1099 *
1100 * @param sb a StringBuilder object.
1101 * @param timer a Timer object contining the wakelock times.
1102 * @param batteryRealtime the current on-battery time in microseconds.
1103 * @param name the name of the wakelock.
1104 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
1105 * @param linePrefix a String to be prepended to each line of output.
1106 * @return the line prefix
1107 */
1108 private static final String printWakeLock(StringBuilder sb, Timer timer,
1109 long batteryRealtime, String name, int which, String linePrefix) {
1110
1111 if (timer != null) {
1112 // Convert from microseconds to milliseconds with rounding
Evan Millarc64edde2009-04-18 12:26:32 -07001113 long totalTimeMicros = timer.getTotalTimeLocked(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001114 long totalTimeMillis = (totalTimeMicros + 500) / 1000;
1115
Evan Millarc64edde2009-04-18 12:26:32 -07001116 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117 if (totalTimeMillis != 0) {
1118 sb.append(linePrefix);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001119 formatTimeMs(sb, totalTimeMillis);
1120 if (name != null) sb.append(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001121 sb.append(' ');
1122 sb.append('(');
1123 sb.append(count);
1124 sb.append(" times)");
1125 return ", ";
1126 }
1127 }
1128 return linePrefix;
1129 }
1130
1131 /**
1132 * Checkin version of wakelock printer. Prints simple comma-separated list.
1133 *
1134 * @param sb a StringBuilder object.
1135 * @param timer a Timer object contining the wakelock times.
1136 * @param now the current time in microseconds.
1137 * @param name the name of the wakelock.
1138 * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
1139 * @param linePrefix a String to be prepended to each line of output.
1140 * @return the line prefix
1141 */
1142 private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now,
Evan Millarc64edde2009-04-18 12:26:32 -07001143 String name, int which, String linePrefix) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001144 long totalTimeMicros = 0;
1145 int count = 0;
1146 if (timer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001147 totalTimeMicros = timer.getTotalTimeLocked(now, which);
1148 count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001149 }
1150 sb.append(linePrefix);
1151 sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
1152 sb.append(',');
Evan Millarc64edde2009-04-18 12:26:32 -07001153 sb.append(name != null ? name + "," : "");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001154 sb.append(count);
1155 return ",";
1156 }
1157
1158 /**
1159 * Dump a comma-separated line of values for terse checkin mode.
1160 *
1161 * @param pw the PageWriter to dump log to
1162 * @param category category of data (e.g. "total", "last", "unplugged", "current" )
1163 * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network")
1164 * @param args type-dependent data arguments
1165 */
1166 private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
1167 Object... args ) {
1168 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
1169 pw.print(uid); pw.print(',');
1170 pw.print(category); pw.print(',');
1171 pw.print(type);
1172
1173 for (Object arg : args) {
1174 pw.print(',');
1175 pw.print(arg);
1176 }
1177 pw.print('\n');
1178 }
1179
1180 /**
1181 * Checkin server version of dump to produce more compact, computer-readable log.
1182 *
1183 * NOTE: all times are expressed in 'ms'.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001184 */
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001185 public final void dumpCheckinLocked(PrintWriter pw, int which, int reqUid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001186 final long rawUptime = SystemClock.uptimeMillis() * 1000;
1187 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
1188 final long batteryUptime = getBatteryUptime(rawUptime);
1189 final long batteryRealtime = getBatteryRealtime(rawRealtime);
1190 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
1191 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
1192 final long totalRealtime = computeRealtime(rawRealtime, which);
1193 final long totalUptime = computeUptime(rawUptime, which);
1194 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
1195 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001196 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001197 final long wifiRunningTime = getGlobalWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001198 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001199
1200 StringBuilder sb = new StringBuilder(128);
1201
Evan Millar22ac0432009-03-31 11:33:18 -07001202 SparseArray<? extends Uid> uidStats = getUidStats();
1203 final int NU = uidStats.size();
1204
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001205 String category = STAT_NAMES[which];
1206
1207 // Dump "battery" stat
1208 dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001209 which == STATS_SINCE_CHARGED ? getStartCount() : "N/A",
Dianne Hackborn617f8772009-03-31 15:04:46 -07001210 whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
1211 totalRealtime / 1000, totalUptime / 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001212
Evan Millar22ac0432009-03-31 11:33:18 -07001213 // Calculate total network and wakelock times across all uids.
1214 long rxTotal = 0;
1215 long txTotal = 0;
1216 long fullWakeLockTimeTotal = 0;
1217 long partialWakeLockTimeTotal = 0;
1218
1219 for (int iu = 0; iu < NU; iu++) {
1220 Uid u = uidStats.valueAt(iu);
1221 rxTotal += u.getTcpBytesReceived(which);
1222 txTotal += u.getTcpBytesSent(which);
1223
1224 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1225 if (wakelocks.size() > 0) {
1226 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1227 : wakelocks.entrySet()) {
1228 Uid.Wakelock wl = ent.getValue();
1229
1230 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
1231 if (fullWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001232 fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(batteryRealtime, which);
Evan Millar22ac0432009-03-31 11:33:18 -07001233 }
1234
1235 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
1236 if (partialWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001237 partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -07001238 batteryRealtime, which);
1239 }
1240 }
1241 }
1242 }
1243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001244 // Dump misc stats
1245 dumpLine(pw, 0 /* uid */, category, MISC_DATA,
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001246 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
Evan Millar22ac0432009-03-31 11:33:18 -07001247 wifiRunningTime / 1000, bluetoothOnTime / 1000, rxTotal, txTotal,
Dianne Hackborn617f8772009-03-31 15:04:46 -07001248 fullWakeLockTimeTotal, partialWakeLockTimeTotal,
1249 getInputEventCount(which));
1250
1251 // Dump screen brightness stats
1252 Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
1253 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1254 args[i] = getScreenBrightnessTime(i, batteryRealtime, which) / 1000;
1255 }
1256 dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
The Android Open Source Project10592532009-03-18 17:39:46 -07001257
Dianne Hackborn627bba72009-03-24 22:32:56 -07001258 // Dump signal strength stats
Wink Saville52840902011-02-18 12:40:47 -08001259 args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
1260 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07001261 args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000;
1262 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001263 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
Amith Yamasanif37447b2009-10-08 18:28:01 -07001264 dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA,
1265 getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
Wink Saville52840902011-02-18 12:40:47 -08001266 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07001267 args[i] = getPhoneSignalStrengthCount(i, which);
1268 }
1269 dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001270
1271 // Dump network type stats
1272 args = new Object[NUM_DATA_CONNECTION_TYPES];
1273 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
1274 args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000;
1275 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001276 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args);
1277 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
1278 args[i] = getPhoneDataConnectionCount(i, which);
1279 }
1280 dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001281
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001282 if (which == STATS_SINCE_UNPLUGGED) {
Evan Millare84de8d2009-04-02 22:16:12 -07001283 dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
Evan Millar633a1742009-04-02 16:36:33 -07001284 getDischargeCurrentLevel());
The Android Open Source Project10592532009-03-18 17:39:46 -07001285 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001286
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001287 if (which == STATS_SINCE_UNPLUGGED) {
1288 dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
1289 getDischargeStartLevel()-getDischargeCurrentLevel(),
1290 getDischargeStartLevel()-getDischargeCurrentLevel(),
1291 getDischargeAmountScreenOn(), getDischargeAmountScreenOff());
1292 } else {
1293 dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
1294 getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(),
1295 getDischargeAmountScreenOn(), getDischargeAmountScreenOff());
1296 }
1297
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001298 if (reqUid < 0) {
1299 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
1300 if (kernelWakelocks.size() > 0) {
1301 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
1302 sb.setLength(0);
1303 printWakeLockCheckin(sb, ent.getValue(), batteryRealtime, null, which, "");
1304
1305 dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
1306 sb.toString());
1307 }
Evan Millarc64edde2009-04-18 12:26:32 -07001308 }
1309 }
1310
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001311 for (int iu = 0; iu < NU; iu++) {
1312 final int uid = uidStats.keyAt(iu);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001313 if (reqUid >= 0 && uid != reqUid) {
1314 continue;
1315 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001316 Uid u = uidStats.valueAt(iu);
1317 // Dump Network stats per uid, if any
1318 long rx = u.getTcpBytesReceived(which);
1319 long tx = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001320 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
1321 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001322 long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001324 if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx);
The Android Open Source Project10592532009-03-18 17:39:46 -07001325
Dianne Hackborn617f8772009-03-31 15:04:46 -07001326 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001327 || uidWifiRunningTime != 0) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001328 dumpLine(pw, uid, category, WIFI_LOCK_DATA,
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001329 fullWifiLockOnTime, scanWifiLockOnTime, uidWifiRunningTime);
The Android Open Source Project10592532009-03-18 17:39:46 -07001330 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001331
Dianne Hackborn617f8772009-03-31 15:04:46 -07001332 if (u.hasUserActivity()) {
1333 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
1334 boolean hasData = false;
1335 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
1336 int val = u.getUserActivityCount(i, which);
1337 args[i] = val;
1338 if (val != 0) hasData = true;
1339 }
1340 if (hasData) {
1341 dumpLine(pw, 0 /* uid */, category, USER_ACTIVITY_DATA, args);
1342 }
1343 }
1344
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001345 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1346 if (wakelocks.size() > 0) {
1347 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1348 : wakelocks.entrySet()) {
1349 Uid.Wakelock wl = ent.getValue();
1350 String linePrefix = "";
1351 sb.setLength(0);
Evan Millarc64edde2009-04-18 12:26:32 -07001352 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
1353 batteryRealtime, "f", which, linePrefix);
1354 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL),
1355 batteryRealtime, "p", which, linePrefix);
1356 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
1357 batteryRealtime, "w", which, linePrefix);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001358
1359 // Only log if we had at lease one wakelock...
1360 if (sb.length() > 0) {
1361 dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString());
1362 }
1363 }
1364 }
1365
1366 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
1367 if (sensors.size() > 0) {
1368 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
1369 : sensors.entrySet()) {
1370 Uid.Sensor se = ent.getValue();
1371 int sensorNumber = ent.getKey();
1372 Timer timer = se.getSensorTime();
1373 if (timer != null) {
1374 // Convert from microseconds to milliseconds with rounding
Evan Millarc64edde2009-04-18 12:26:32 -07001375 long totalTime = (timer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
1376 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001377 if (totalTime != 0) {
1378 dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
1379 }
1380 }
1381 }
1382 }
1383
1384 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
1385 if (processStats.size() > 0) {
1386 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
1387 : processStats.entrySet()) {
1388 Uid.Proc ps = ent.getValue();
1389
1390 long userTime = ps.getUserTime(which);
1391 long systemTime = ps.getSystemTime(which);
1392 int starts = ps.getStarts(which);
1393
1394 if (userTime != 0 || systemTime != 0 || starts != 0) {
1395 dumpLine(pw, uid, category, PROCESS_DATA,
1396 ent.getKey(), // proc
1397 userTime * 10, // cpu time in ms
1398 systemTime * 10, // user time in ms
1399 starts); // process starts
1400 }
1401 }
1402 }
1403
1404 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
1405 if (packageStats.size() > 0) {
1406 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
1407 : packageStats.entrySet()) {
1408
1409 Uid.Pkg ps = ent.getValue();
1410 int wakeups = ps.getWakeups(which);
1411 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
1412 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
1413 : serviceStats.entrySet()) {
1414 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
1415 long startTime = ss.getStartTime(batteryUptime, which);
1416 int starts = ss.getStarts(which);
1417 int launches = ss.getLaunches(which);
1418 if (startTime != 0 || starts != 0 || launches != 0) {
1419 dumpLine(pw, uid, category, APK_DATA,
1420 wakeups, // wakeup alarms
1421 ent.getKey(), // Apk
1422 sent.getKey(), // service
1423 startTime / 1000, // time spent started, in ms
1424 starts,
1425 launches);
1426 }
1427 }
1428 }
1429 }
1430 }
1431 }
1432
1433 @SuppressWarnings("unused")
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001434 public final void dumpLocked(PrintWriter pw, String prefix, int which, int reqUid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001435 final long rawUptime = SystemClock.uptimeMillis() * 1000;
1436 final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
1437 final long batteryUptime = getBatteryUptime(rawUptime);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07001438 final long batteryRealtime = getBatteryRealtime(rawRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439
1440 final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
1441 final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
1442 final long totalRealtime = computeRealtime(rawRealtime, which);
1443 final long totalUptime = computeUptime(rawUptime, which);
1444
1445 StringBuilder sb = new StringBuilder(128);
Evan Millar22ac0432009-03-31 11:33:18 -07001446
1447 SparseArray<? extends Uid> uidStats = getUidStats();
1448 final int NU = uidStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001449
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001450 sb.setLength(0);
1451 sb.append(prefix);
1452 sb.append(" Time on battery: ");
1453 formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("(");
1454 sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
1455 sb.append(") realtime, ");
1456 formatTimeMs(sb, whichBatteryUptime / 1000);
1457 sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime));
1458 sb.append(") uptime");
1459 pw.println(sb.toString());
1460 sb.setLength(0);
1461 sb.append(prefix);
1462 sb.append(" Total run time: ");
1463 formatTimeMs(sb, totalRealtime / 1000);
1464 sb.append("realtime, ");
1465 formatTimeMs(sb, totalUptime / 1000);
1466 sb.append("uptime, ");
1467 pw.println(sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001468
The Android Open Source Project10592532009-03-18 17:39:46 -07001469 final long screenOnTime = getScreenOnTime(batteryRealtime, which);
1470 final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001471 final long wifiRunningTime = getGlobalWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001472 final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
1473 final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001474 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001475 sb.append(prefix);
1476 sb.append(" Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
1477 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
1478 sb.append("), Input events: "); sb.append(getInputEventCount(which));
1479 sb.append(", Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
1480 sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
1481 sb.append(")");
1482 pw.println(sb.toString());
1483 sb.setLength(0);
1484 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001485 sb.append(" Screen brightnesses: ");
1486 boolean didOne = false;
1487 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1488 final long time = getScreenBrightnessTime(i, batteryRealtime, which);
1489 if (time == 0) {
1490 continue;
1491 }
1492 if (didOne) sb.append(", ");
1493 didOne = true;
1494 sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
1495 sb.append(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001496 formatTimeMs(sb, time/1000);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001497 sb.append("(");
1498 sb.append(formatRatioLocked(time, screenOnTime));
1499 sb.append(")");
1500 }
1501 if (!didOne) sb.append("No activity");
1502 pw.println(sb.toString());
The Android Open Source Project10592532009-03-18 17:39:46 -07001503
Evan Millar22ac0432009-03-31 11:33:18 -07001504 // Calculate total network and wakelock times across all uids.
1505 long rxTotal = 0;
1506 long txTotal = 0;
1507 long fullWakeLockTimeTotalMicros = 0;
1508 long partialWakeLockTimeTotalMicros = 0;
1509
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001510 if (reqUid < 0) {
1511 Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
1512 if (kernelWakelocks.size() > 0) {
1513 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
1514
1515 String linePrefix = ": ";
1516 sb.setLength(0);
1517 sb.append(prefix);
1518 sb.append(" Kernel Wake lock ");
1519 sb.append(ent.getKey());
1520 linePrefix = printWakeLock(sb, ent.getValue(), batteryRealtime, null, which,
1521 linePrefix);
1522 if (!linePrefix.equals(": ")) {
1523 sb.append(" realtime");
Jason Parks94b916d2010-07-20 12:39:07 -05001524 // Only print out wake locks that were held
1525 pw.println(sb.toString());
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001526 }
Evan Millarc64edde2009-04-18 12:26:32 -07001527 }
Evan Millarc64edde2009-04-18 12:26:32 -07001528 }
1529 }
1530
Evan Millar22ac0432009-03-31 11:33:18 -07001531 for (int iu = 0; iu < NU; iu++) {
1532 Uid u = uidStats.valueAt(iu);
1533 rxTotal += u.getTcpBytesReceived(which);
1534 txTotal += u.getTcpBytesSent(which);
1535
1536 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1537 if (wakelocks.size() > 0) {
1538 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1539 : wakelocks.entrySet()) {
1540 Uid.Wakelock wl = ent.getValue();
1541
1542 Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
1543 if (fullWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001544 fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -07001545 batteryRealtime, which);
1546 }
1547
1548 Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
1549 if (partialWakeTimer != null) {
Evan Millarc64edde2009-04-18 12:26:32 -07001550 partialWakeLockTimeTotalMicros += partialWakeTimer.getTotalTimeLocked(
Evan Millar22ac0432009-03-31 11:33:18 -07001551 batteryRealtime, which);
1552 }
1553 }
1554 }
1555 }
1556
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001557 pw.print(prefix);
1558 pw.print(" Total received: "); pw.print(formatBytesLocked(rxTotal));
1559 pw.print(", Total sent: "); pw.println(formatBytesLocked(txTotal));
1560 sb.setLength(0);
1561 sb.append(prefix);
1562 sb.append(" Total full wakelock time: "); formatTimeMs(sb,
1563 (fullWakeLockTimeTotalMicros + 500) / 1000);
1564 sb.append(", Total partial waklock time: "); formatTimeMs(sb,
1565 (partialWakeLockTimeTotalMicros + 500) / 1000);
1566 pw.println(sb.toString());
Evan Millar22ac0432009-03-31 11:33:18 -07001567
Dianne Hackborn627bba72009-03-24 22:32:56 -07001568 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001569 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001570 sb.append(" Signal levels: ");
1571 didOne = false;
Wink Saville52840902011-02-18 12:40:47 -08001572 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07001573 final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which);
1574 if (time == 0) {
1575 continue;
1576 }
1577 if (didOne) sb.append(", ");
1578 didOne = true;
Wink Saville52840902011-02-18 12:40:47 -08001579 sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001580 sb.append(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001581 formatTimeMs(sb, time/1000);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001582 sb.append("(");
1583 sb.append(formatRatioLocked(time, whichBatteryRealtime));
Dianne Hackborn617f8772009-03-31 15:04:46 -07001584 sb.append(") ");
1585 sb.append(getPhoneSignalStrengthCount(i, which));
1586 sb.append("x");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001587 }
1588 if (!didOne) sb.append("No activity");
1589 pw.println(sb.toString());
Amith Yamasanif37447b2009-10-08 18:28:01 -07001590
1591 sb.setLength(0);
1592 sb.append(prefix);
1593 sb.append(" Signal scanning time: ");
1594 formatTimeMs(sb, getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
1595 pw.println(sb.toString());
1596
Dianne Hackborn627bba72009-03-24 22:32:56 -07001597 sb.setLength(0);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001598 sb.append(prefix);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001599 sb.append(" Radio types: ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001600 didOne = false;
1601 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
1602 final long time = getPhoneDataConnectionTime(i, batteryRealtime, which);
1603 if (time == 0) {
1604 continue;
1605 }
1606 if (didOne) sb.append(", ");
1607 didOne = true;
1608 sb.append(DATA_CONNECTION_NAMES[i]);
1609 sb.append(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001610 formatTimeMs(sb, time/1000);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001611 sb.append("(");
1612 sb.append(formatRatioLocked(time, whichBatteryRealtime));
Dianne Hackborn617f8772009-03-31 15:04:46 -07001613 sb.append(") ");
1614 sb.append(getPhoneDataConnectionCount(i, which));
1615 sb.append("x");
Dianne Hackborn627bba72009-03-24 22:32:56 -07001616 }
1617 if (!didOne) sb.append("No activity");
1618 pw.println(sb.toString());
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001619
1620 sb.setLength(0);
1621 sb.append(prefix);
1622 sb.append(" Radio data uptime when unplugged: ");
1623 sb.append(getRadioDataUptime() / 1000);
1624 sb.append(" ms");
1625 pw.println(sb.toString());
1626
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001627 sb.setLength(0);
1628 sb.append(prefix);
1629 sb.append(" Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
1630 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
1631 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000);
1632 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
1633 sb.append("), Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000);
1634 sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime));
1635 sb.append(")");
1636 pw.println(sb.toString());
Dianne Hackborn617f8772009-03-31 15:04:46 -07001637
The Android Open Source Project10592532009-03-18 17:39:46 -07001638 pw.println(" ");
1639
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001640 if (which == STATS_SINCE_UNPLUGGED) {
The Android Open Source Project10592532009-03-18 17:39:46 -07001641 if (getIsOnBattery()) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001642 pw.print(prefix); pw.println(" Device is currently unplugged");
1643 pw.print(prefix); pw.print(" Discharge cycle start level: ");
1644 pw.println(getDischargeStartLevel());
1645 pw.print(prefix); pw.print(" Discharge cycle current level: ");
1646 pw.println(getDischargeCurrentLevel());
Dianne Hackborn99d04522010-08-20 13:43:00 -07001647 } else {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001648 pw.print(prefix); pw.println(" Device is currently plugged into power");
1649 pw.print(prefix); pw.print(" Last discharge cycle start level: ");
1650 pw.println(getDischargeStartLevel());
1651 pw.print(prefix); pw.print(" Last discharge cycle end level: ");
1652 pw.println(getDischargeCurrentLevel());
The Android Open Source Project10592532009-03-18 17:39:46 -07001653 }
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001654 pw.print(prefix); pw.print(" Amount discharged while screen on: ");
1655 pw.println(getDischargeAmountScreenOn());
1656 pw.print(prefix); pw.print(" Amount discharged while screen off: ");
1657 pw.println(getDischargeAmountScreenOff());
Dianne Hackborn617f8772009-03-31 15:04:46 -07001658 pw.println(" ");
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001659 } else {
1660 pw.print(prefix); pw.println(" Device battery use since last full charge");
1661 pw.print(prefix); pw.print(" Amount discharged (lower bound): ");
1662 pw.println(getLowDischargeAmountSinceCharge());
1663 pw.print(prefix); pw.print(" Amount discharged (upper bound): ");
1664 pw.println(getHighDischargeAmountSinceCharge());
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08001665 pw.print(prefix); pw.print(" Amount discharged while screen on: ");
1666 pw.println(getDischargeAmountScreenOnSinceCharge());
1667 pw.print(prefix); pw.print(" Amount discharged while screen off: ");
1668 pw.println(getDischargeAmountScreenOffSinceCharge());
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001669 pw.println(" ");
The Android Open Source Project10592532009-03-18 17:39:46 -07001670 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001671
Evan Millar22ac0432009-03-31 11:33:18 -07001672
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001673 for (int iu=0; iu<NU; iu++) {
1674 final int uid = uidStats.keyAt(iu);
Dianne Hackborne4a59512010-12-07 11:08:07 -08001675 if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001676 continue;
1677 }
1678
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001679 Uid u = uidStats.valueAt(iu);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001681 pw.println(prefix + " #" + uid + ":");
1682 boolean uidActivity = false;
1683
1684 long tcpReceived = u.getTcpBytesReceived(which);
1685 long tcpSent = u.getTcpBytesSent(which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001686 long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
1687 long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001688 long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07001689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001690 if (tcpReceived != 0 || tcpSent != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001691 pw.print(prefix); pw.print(" Network: ");
1692 pw.print(formatBytesLocked(tcpReceived)); pw.print(" received, ");
1693 pw.print(formatBytesLocked(tcpSent)); pw.println(" sent");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001694 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001695
1696 if (u.hasUserActivity()) {
1697 boolean hasData = false;
1698 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1699 int val = u.getUserActivityCount(i, which);
1700 if (val != 0) {
1701 if (!hasData) {
1702 sb.setLength(0);
1703 sb.append(" User activity: ");
1704 hasData = true;
1705 } else {
1706 sb.append(", ");
1707 }
1708 sb.append(val);
1709 sb.append(" ");
1710 sb.append(Uid.USER_ACTIVITY_TYPES[i]);
1711 }
1712 }
1713 if (hasData) {
1714 pw.println(sb.toString());
1715 }
1716 }
1717
1718 if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001719 || uidWifiRunningTime != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001720 sb.setLength(0);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07001721 sb.append(prefix); sb.append(" Wifi Running: ");
1722 formatTimeMs(sb, uidWifiRunningTime / 1000);
1723 sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001724 whichBatteryRealtime)); sb.append(")\n");
1725 sb.append(prefix); sb.append(" Full Wifi Lock: ");
1726 formatTimeMs(sb, fullWifiLockOnTime / 1000);
1727 sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
1728 whichBatteryRealtime)); sb.append(")\n");
1729 sb.append(prefix); sb.append(" Scan Wifi Lock: ");
1730 formatTimeMs(sb, scanWifiLockOnTime / 1000);
1731 sb.append("("); sb.append(formatRatioLocked(scanWifiLockOnTime,
1732 whichBatteryRealtime)); sb.append(")");
1733 pw.println(sb.toString());
The Android Open Source Project10592532009-03-18 17:39:46 -07001734 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001735
1736 Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1737 if (wakelocks.size() > 0) {
1738 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1739 : wakelocks.entrySet()) {
1740 Uid.Wakelock wl = ent.getValue();
1741 String linePrefix = ": ";
1742 sb.setLength(0);
1743 sb.append(prefix);
1744 sb.append(" Wake lock ");
1745 sb.append(ent.getKey());
1746 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
1747 "full", which, linePrefix);
1748 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
1749 "partial", which, linePrefix);
1750 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
1751 "window", which, linePrefix);
1752 if (!linePrefix.equals(": ")) {
1753 sb.append(" realtime");
Jason Parks94b916d2010-07-20 12:39:07 -05001754 // Only print out wake locks that were held
1755 pw.println(sb.toString());
1756 uidActivity = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001757 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001758 }
1759 }
1760
1761 Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
1762 if (sensors.size() > 0) {
1763 for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
1764 : sensors.entrySet()) {
1765 Uid.Sensor se = ent.getValue();
1766 int sensorNumber = ent.getKey();
1767 sb.setLength(0);
1768 sb.append(prefix);
1769 sb.append(" Sensor ");
1770 int handle = se.getHandle();
1771 if (handle == Uid.Sensor.GPS) {
1772 sb.append("GPS");
1773 } else {
1774 sb.append(handle);
1775 }
1776 sb.append(": ");
1777
1778 Timer timer = se.getSensorTime();
1779 if (timer != null) {
1780 // Convert from microseconds to milliseconds with rounding
Evan Millarc64edde2009-04-18 12:26:32 -07001781 long totalTime = (timer.getTotalTimeLocked(
1782 batteryRealtime, which) + 500) / 1000;
1783 int count = timer.getCountLocked(which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001784 //timer.logState();
1785 if (totalTime != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001786 formatTimeMs(sb, totalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001787 sb.append("realtime (");
1788 sb.append(count);
1789 sb.append(" times)");
1790 } else {
1791 sb.append("(not used)");
1792 }
1793 } else {
1794 sb.append("(not used)");
1795 }
1796
1797 pw.println(sb.toString());
1798 uidActivity = true;
1799 }
1800 }
1801
1802 Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
1803 if (processStats.size() > 0) {
1804 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
1805 : processStats.entrySet()) {
1806 Uid.Proc ps = ent.getValue();
1807 long userTime;
1808 long systemTime;
1809 int starts;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001810 int numExcessive;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001811
1812 userTime = ps.getUserTime(which);
1813 systemTime = ps.getSystemTime(which);
1814 starts = ps.getStarts(which);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001815 numExcessive = which == STATS_SINCE_CHARGED
Dianne Hackborn287952c2010-09-22 22:34:31 -07001816 ? ps.countExcessivePowers() : 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001817
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001818 if (userTime != 0 || systemTime != 0 || starts != 0
1819 || numExcessive != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001820 sb.setLength(0);
1821 sb.append(prefix); sb.append(" Proc ");
1822 sb.append(ent.getKey()); sb.append(":\n");
1823 sb.append(prefix); sb.append(" CPU: ");
1824 formatTime(sb, userTime); sb.append("usr + ");
Dianne Hackbornb8071d792010-09-09 16:45:15 -07001825 formatTime(sb, systemTime); sb.append("krn");
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001826 if (starts != 0) {
Dianne Hackbornb8071d792010-09-09 16:45:15 -07001827 sb.append("\n"); sb.append(prefix); sb.append(" ");
1828 sb.append(starts); sb.append(" proc starts");
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001829 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001830 pw.println(sb.toString());
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001831 for (int e=0; e<numExcessive; e++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001832 Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001833 if (ew != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001834 pw.print(prefix); pw.print(" * Killed for ");
1835 if (ew.type == Uid.Proc.ExcessivePower.TYPE_WAKE) {
1836 pw.print("wake lock");
1837 } else if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) {
1838 pw.print("cpu");
1839 } else {
1840 pw.print("unknown");
1841 }
1842 pw.print(" use: ");
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001843 TimeUtils.formatDuration(ew.usedTime, pw);
1844 pw.print(" over ");
1845 TimeUtils.formatDuration(ew.overTime, pw);
1846 pw.print(" (");
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001847 pw.print((ew.usedTime*100)/ew.overTime);
1848 pw.println("%)");
1849 }
1850 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001851 uidActivity = true;
1852 }
1853 }
1854 }
1855
1856 Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
1857 if (packageStats.size() > 0) {
1858 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
1859 : packageStats.entrySet()) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001860 pw.print(prefix); pw.print(" Apk "); pw.print(ent.getKey()); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001861 boolean apkActivity = false;
1862 Uid.Pkg ps = ent.getValue();
1863 int wakeups = ps.getWakeups(which);
1864 if (wakeups != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001865 pw.print(prefix); pw.print(" ");
1866 pw.print(wakeups); pw.println(" wakeup alarms");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001867 apkActivity = true;
1868 }
1869 Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
1870 if (serviceStats.size() > 0) {
1871 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
1872 : serviceStats.entrySet()) {
1873 BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
1874 long startTime = ss.getStartTime(batteryUptime, which);
1875 int starts = ss.getStarts(which);
1876 int launches = ss.getLaunches(which);
1877 if (startTime != 0 || starts != 0 || launches != 0) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001878 sb.setLength(0);
1879 sb.append(prefix); sb.append(" Service ");
1880 sb.append(sent.getKey()); sb.append(":\n");
1881 sb.append(prefix); sb.append(" Created for: ");
1882 formatTimeMs(sb, startTime / 1000);
1883 sb.append(" uptime\n");
1884 sb.append(prefix); sb.append(" Starts: ");
1885 sb.append(starts);
1886 sb.append(", launches: "); sb.append(launches);
1887 pw.println(sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001888 apkActivity = true;
1889 }
1890 }
1891 }
1892 if (!apkActivity) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001893 pw.print(prefix); pw.println(" (nothing executed)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001894 }
1895 uidActivity = true;
1896 }
1897 }
1898 if (!uidActivity) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001899 pw.print(prefix); pw.println(" (nothing executed)");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001900 }
1901 }
1902 }
1903
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001904 static void printBitDescriptions(PrintWriter pw, int oldval, int newval, BitDescription[] descriptions) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001905 int diff = oldval ^ newval;
1906 if (diff == 0) return;
1907 for (int i=0; i<descriptions.length; i++) {
1908 BitDescription bd = descriptions[i];
1909 if ((diff&bd.mask) != 0) {
1910 if (bd.shift < 0) {
1911 pw.print((newval&bd.mask) != 0 ? " +" : " -");
1912 pw.print(bd.name);
1913 } else {
1914 pw.print(" ");
1915 pw.print(bd.name);
1916 pw.print("=");
1917 int val = (newval&bd.mask)>>bd.shift;
1918 if (bd.values != null && val >= 0 && val < bd.values.length) {
1919 pw.print(bd.values[val]);
1920 } else {
1921 pw.print(val);
1922 }
1923 }
1924 }
1925 }
1926 }
1927
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001928 public void prepareForDumpLocked() {
1929 }
1930
1931 public static class HistoryPrinter {
1932 int oldState = 0;
1933 int oldStatus = -1;
1934 int oldHealth = -1;
1935 int oldPlug = -1;
1936 int oldTemp = -1;
1937 int oldVolt = -1;
1938
1939 public void printNextItem(PrintWriter pw, HistoryItem rec, long now) {
1940 pw.print(" ");
1941 TimeUtils.formatDuration(rec.time-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
1942 pw.print(" ");
1943 if (rec.cmd == HistoryItem.CMD_START) {
1944 pw.println(" START");
1945 } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
1946 pw.println(" *OVERFLOW*");
1947 } else {
1948 if (rec.batteryLevel < 10) pw.print("00");
1949 else if (rec.batteryLevel < 100) pw.print("0");
1950 pw.print(rec.batteryLevel);
1951 pw.print(" ");
1952 if (rec.states < 0x10) pw.print("0000000");
1953 else if (rec.states < 0x100) pw.print("000000");
1954 else if (rec.states < 0x1000) pw.print("00000");
1955 else if (rec.states < 0x10000) pw.print("0000");
1956 else if (rec.states < 0x100000) pw.print("000");
1957 else if (rec.states < 0x1000000) pw.print("00");
1958 else if (rec.states < 0x10000000) pw.print("0");
1959 pw.print(Integer.toHexString(rec.states));
1960 if (oldStatus != rec.batteryStatus) {
1961 oldStatus = rec.batteryStatus;
1962 pw.print(" status=");
1963 switch (oldStatus) {
1964 case BatteryManager.BATTERY_STATUS_UNKNOWN:
1965 pw.print("unknown");
1966 break;
1967 case BatteryManager.BATTERY_STATUS_CHARGING:
1968 pw.print("charging");
1969 break;
1970 case BatteryManager.BATTERY_STATUS_DISCHARGING:
1971 pw.print("discharging");
1972 break;
1973 case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
1974 pw.print("not-charging");
1975 break;
1976 case BatteryManager.BATTERY_STATUS_FULL:
1977 pw.print("full");
1978 break;
1979 default:
1980 pw.print(oldStatus);
1981 break;
1982 }
1983 }
1984 if (oldHealth != rec.batteryHealth) {
1985 oldHealth = rec.batteryHealth;
1986 pw.print(" health=");
1987 switch (oldHealth) {
1988 case BatteryManager.BATTERY_HEALTH_UNKNOWN:
1989 pw.print("unknown");
1990 break;
1991 case BatteryManager.BATTERY_HEALTH_GOOD:
1992 pw.print("good");
1993 break;
1994 case BatteryManager.BATTERY_HEALTH_OVERHEAT:
1995 pw.print("overheat");
1996 break;
1997 case BatteryManager.BATTERY_HEALTH_DEAD:
1998 pw.print("dead");
1999 break;
2000 case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
2001 pw.print("over-voltage");
2002 break;
2003 case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
2004 pw.print("failure");
2005 break;
2006 default:
2007 pw.print(oldHealth);
2008 break;
2009 }
2010 }
2011 if (oldPlug != rec.batteryPlugType) {
2012 oldPlug = rec.batteryPlugType;
2013 pw.print(" plug=");
2014 switch (oldPlug) {
2015 case 0:
2016 pw.print("none");
2017 break;
2018 case BatteryManager.BATTERY_PLUGGED_AC:
2019 pw.print("ac");
2020 break;
2021 case BatteryManager.BATTERY_PLUGGED_USB:
2022 pw.print("usb");
2023 break;
2024 default:
2025 pw.print(oldPlug);
2026 break;
2027 }
2028 }
2029 if (oldTemp != rec.batteryTemperature) {
2030 oldTemp = rec.batteryTemperature;
2031 pw.print(" temp=");
2032 pw.print(oldTemp);
2033 }
2034 if (oldVolt != rec.batteryVoltage) {
2035 oldVolt = rec.batteryVoltage;
2036 pw.print(" volt=");
2037 pw.print(oldVolt);
2038 }
2039 printBitDescriptions(pw, oldState, rec.states,
2040 HISTORY_STATE_DESCRIPTIONS);
2041 pw.println();
2042 }
2043 oldState = rec.states;
2044 }
2045 }
2046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002047 /**
2048 * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
2049 *
2050 * @param pw a Printer to receive the dump output.
2051 */
2052 @SuppressWarnings("unused")
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002053 public void dumpLocked(PrintWriter pw) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002054 prepareForDumpLocked();
2055
2056 long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
2057
Dianne Hackbornce2ef762010-09-20 11:39:14 -07002058 final HistoryItem rec = new HistoryItem();
2059 if (startIteratingHistoryLocked()) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002060 pw.println("Battery History:");
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002061 HistoryPrinter hprinter = new HistoryPrinter();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07002062 while (getNextHistoryLocked(rec)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002063 hprinter.printNextItem(pw, rec, now);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002064 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002065 finishIteratingHistoryLocked();
2066 pw.println("");
2067 }
2068
2069 if (startIteratingOldHistoryLocked()) {
2070 pw.println("Old battery History:");
2071 HistoryPrinter hprinter = new HistoryPrinter();
2072 while (getNextOldHistoryLocked(rec)) {
2073 hprinter.printNextItem(pw, rec, now);
2074 }
2075 finishIteratingOldHistoryLocked();
Dianne Hackbornb5e31652010-09-07 12:13:55 -07002076 pw.println("");
2077 }
2078
2079 SparseArray<? extends Uid> uidStats = getUidStats();
2080 final int NU = uidStats.size();
2081 boolean didPid = false;
2082 long nowRealtime = SystemClock.elapsedRealtime();
2083 StringBuilder sb = new StringBuilder(64);
2084 for (int i=0; i<NU; i++) {
2085 Uid uid = uidStats.valueAt(i);
2086 SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
2087 if (pids != null) {
2088 for (int j=0; j<pids.size(); j++) {
2089 Uid.Pid pid = pids.valueAt(j);
2090 if (!didPid) {
2091 pw.println("Per-PID Stats:");
2092 didPid = true;
2093 }
2094 long time = pid.mWakeSum + (pid.mWakeStart != 0
2095 ? (nowRealtime - pid.mWakeStart) : 0);
2096 pw.print(" PID "); pw.print(pids.keyAt(j));
2097 pw.print(" wake time: ");
2098 TimeUtils.formatDuration(time, pw);
2099 pw.println("");
2100 }
2101 }
2102 }
2103 if (didPid) {
2104 pw.println("");
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002105 }
2106
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002107 pw.println("Statistics since last charge:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002108 pw.println(" System starts: " + getStartCount()
2109 + ", currently on battery: " + getIsOnBattery());
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002110 dumpLocked(pw, "", STATS_SINCE_CHARGED, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002111 pw.println("");
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002112 pw.println("Statistics since last unplugged:");
2113 dumpLocked(pw, "", STATS_SINCE_UNPLUGGED, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002114 }
2115
2116 @SuppressWarnings("unused")
Dianne Hackborne4a59512010-12-07 11:08:07 -08002117 public void dumpCheckinLocked(PrintWriter pw, String[] args, List<ApplicationInfo> apps) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002118 prepareForDumpLocked();
2119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002120 boolean isUnpluggedOnly = false;
2121
2122 for (String arg : args) {
2123 if ("-u".equals(arg)) {
2124 if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data");
2125 isUnpluggedOnly = true;
2126 }
2127 }
2128
Dianne Hackborne4a59512010-12-07 11:08:07 -08002129 if (apps != null) {
2130 SparseArray<ArrayList<String>> uids = new SparseArray<ArrayList<String>>();
2131 for (int i=0; i<apps.size(); i++) {
2132 ApplicationInfo ai = apps.get(i);
2133 ArrayList<String> pkgs = uids.get(ai.uid);
2134 if (pkgs == null) {
2135 pkgs = new ArrayList<String>();
2136 uids.put(ai.uid, pkgs);
2137 }
2138 pkgs.add(ai.packageName);
2139 }
2140 SparseArray<? extends Uid> uidStats = getUidStats();
2141 final int NU = uidStats.size();
2142 String[] lineArgs = new String[2];
2143 for (int i=0; i<NU; i++) {
2144 int uid = uidStats.keyAt(i);
2145 ArrayList<String> pkgs = uids.get(uid);
2146 if (pkgs != null) {
2147 for (int j=0; j<pkgs.size(); j++) {
2148 lineArgs[0] = Integer.toString(uid);
2149 lineArgs[1] = pkgs.get(j);
2150 dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA,
2151 (Object[])lineArgs);
2152 }
2153 }
2154 }
2155 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002156 if (isUnpluggedOnly) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002157 dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002158 }
2159 else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002160 dumpCheckinLocked(pw, STATS_SINCE_CHARGED, -1);
2161 dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002162 }
2163 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002164}