BatteryStats.java revision 15a4d2ffd04dc6c70f2cd17dae12ac6bc14c69ab
1/*
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
17package android.os;
18
19import java.io.PrintWriter;
20import java.util.Formatter;
21import java.util.Map;
22
23import android.util.Log;
24import android.util.Printer;
25import android.util.SparseArray;
26
27/**
28 * A class providing access to battery usage statistics, including information on
29 * wakelocks, processes, packages, and services.  All times are represented in microseconds
30 * except where indicated otherwise.
31 * @hide
32 */
33public abstract class BatteryStats implements Parcelable {
34
35    private static final boolean LOCAL_LOGV = false;
36
37    /**
38     * A constant indicating a partial wake lock timer.
39     */
40    public static final int WAKE_TYPE_PARTIAL = 0;
41
42    /**
43     * A constant indicating a full wake lock timer.
44     */
45    public static final int WAKE_TYPE_FULL = 1;
46
47    /**
48     * A constant indicating a window wake lock timer.
49     */
50    public static final int WAKE_TYPE_WINDOW = 2;
51
52    /**
53     * A constant indicating a sensor timer.
54     *
55     * {@hide}
56     */
57    public static final int SENSOR = 3;
58
59    /**
60     * A constant indicating a a wifi turn on timer
61     *
62     * {@hide}
63     */
64    public static final int WIFI_TURNED_ON = 4;
65
66    /**
67     * A constant indicating a full wifi lock timer
68     *
69     * {@hide}
70     */
71    public static final int FULL_WIFI_LOCK = 5;
72
73    /**
74     * A constant indicating a scan wifi lock timer
75     *
76     * {@hide}
77     */
78    public static final int SCAN_WIFI_LOCK = 6;
79
80     /**
81      * A constant indicating a wifi multicast timer
82      *
83      * {@hide}
84      */
85     public static final int WIFI_MULTICAST_ENABLED = 7;
86
87    /**
88     * A constant indicating an audio turn on timer
89     *
90     * {@hide}
91     */
92    public static final int AUDIO_TURNED_ON = 7;
93
94    /**
95     * A constant indicating a video turn on timer
96     *
97     * {@hide}
98     */
99    public static final int VIDEO_TURNED_ON = 8;
100
101    /**
102     * Include all of the data in the stats, including previously saved data.
103     */
104    public static final int STATS_TOTAL = 0;
105
106    /**
107     * Include only the last run in the stats.
108     */
109    public static final int STATS_LAST = 1;
110
111    /**
112     * Include only the current run in the stats.
113     */
114    public static final int STATS_CURRENT = 2;
115
116    /**
117     * Include only the run since the last time the device was unplugged in the stats.
118     */
119    public static final int STATS_UNPLUGGED = 3;
120
121    // NOTE: Update this list if you add/change any stats above.
122    // These characters are supposed to represent "total", "last", "current",
123    // and "unplugged". They were shortened for effeciency sake.
124    private static final String[] STAT_NAMES = { "t", "l", "c", "u" };
125
126    /**
127     * Bump the version on this if the checkin format changes.
128     */
129    private static final int BATTERY_STATS_CHECKIN_VERSION = 5;
130
131    private static final long BYTES_PER_KB = 1024;
132    private static final long BYTES_PER_MB = 1048576; // 1024^2
133    private static final long BYTES_PER_GB = 1073741824; //1024^3
134
135
136    private static final String APK_DATA = "apk";
137    private static final String PROCESS_DATA = "pr";
138    private static final String SENSOR_DATA = "sr";
139    private static final String WAKELOCK_DATA = "wl";
140    private static final String KERNEL_WAKELOCK_DATA = "kwl";
141    private static final String NETWORK_DATA = "nt";
142    private static final String USER_ACTIVITY_DATA = "ua";
143    private static final String BATTERY_DATA = "bt";
144    private static final String BATTERY_LEVEL_DATA = "lv";
145    private static final String WIFI_LOCK_DATA = "wfl";
146    private static final String MISC_DATA = "m";
147    private static final String SCREEN_BRIGHTNESS_DATA = "br";
148    private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt";
149    private static final String SIGNAL_SCANNING_TIME_DATA = "sst";
150    private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc";
151    private static final String DATA_CONNECTION_TIME_DATA = "dct";
152    private static final String DATA_CONNECTION_COUNT_DATA = "dcc";
153
154    private final StringBuilder mFormatBuilder = new StringBuilder(32);
155    private final Formatter mFormatter = new Formatter(mFormatBuilder);
156
157    /**
158     * State for keeping track of counting information.
159     */
160    public static abstract class Counter {
161
162        /**
163         * Returns the count associated with this Counter for the
164         * selected type of statistics.
165         *
166         * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
167         */
168        public abstract int getCountLocked(int which);
169
170        /**
171         * Temporary for debugging.
172         */
173        public abstract void logState(Printer pw, String prefix);
174    }
175
176    /**
177     * State for keeping track of timing information.
178     */
179    public static abstract class Timer {
180
181        /**
182         * Returns the count associated with this Timer for the
183         * selected type of statistics.
184         *
185         * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
186         */
187        public abstract int getCountLocked(int which);
188
189        /**
190         * Returns the total time in microseconds associated with this Timer for the
191         * selected type of statistics.
192         *
193         * @param batteryRealtime system realtime on  battery in microseconds
194         * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
195         * @return a time in microseconds
196         */
197        public abstract long getTotalTimeLocked(long batteryRealtime, int which);
198
199        /**
200         * Temporary for debugging.
201         */
202        public abstract void logState(Printer pw, String prefix);
203    }
204
205    /**
206     * The statistics associated with a particular uid.
207     */
208    public static abstract class Uid {
209
210        /**
211         * Returns a mapping containing wakelock statistics.
212         *
213         * @return a Map from Strings to Uid.Wakelock objects.
214         */
215        public abstract Map<String, ? extends Wakelock> getWakelockStats();
216
217        /**
218         * The statistics associated with a particular wake lock.
219         */
220        public static abstract class Wakelock {
221            public abstract Timer getWakeTime(int type);
222        }
223
224        /**
225         * Returns a mapping containing sensor statistics.
226         *
227         * @return a Map from Integer sensor ids to Uid.Sensor objects.
228         */
229        public abstract Map<Integer, ? extends Sensor> getSensorStats();
230
231        /**
232         * Returns a mapping containing process statistics.
233         *
234         * @return a Map from Strings to Uid.Proc objects.
235         */
236        public abstract Map<String, ? extends Proc> getProcessStats();
237
238        /**
239         * Returns a mapping containing package statistics.
240         *
241         * @return a Map from Strings to Uid.Pkg objects.
242         */
243        public abstract Map<String, ? extends Pkg> getPackageStats();
244
245        /**
246         * {@hide}
247         */
248        public abstract int getUid();
249
250        /**
251         * {@hide}
252         */
253        public abstract long getTcpBytesReceived(int which);
254
255        /**
256         * {@hide}
257         */
258        public abstract long getTcpBytesSent(int which);
259
260        public abstract void noteWifiTurnedOnLocked();
261        public abstract void noteWifiTurnedOffLocked();
262        public abstract void noteFullWifiLockAcquiredLocked();
263        public abstract void noteFullWifiLockReleasedLocked();
264        public abstract void noteScanWifiLockAcquiredLocked();
265        public abstract void noteScanWifiLockReleasedLocked();
266        public abstract void noteWifiMulticastEnabledLocked();
267        public abstract void noteWifiMulticastDisabledLocked();
268        public abstract void noteAudioTurnedOnLocked();
269        public abstract void noteAudioTurnedOffLocked();
270        public abstract void noteVideoTurnedOnLocked();
271        public abstract void noteVideoTurnedOffLocked();
272        public abstract long getWifiTurnedOnTime(long batteryRealtime, int which);
273        public abstract long getFullWifiLockTime(long batteryRealtime, int which);
274        public abstract long getScanWifiLockTime(long batteryRealtime, int which);
275        public abstract long getWifiMulticastTime(long batteryRealtime,
276                                                  int which);
277        public abstract long getAudioTurnedOnTime(long batteryRealtime, int which);
278        public abstract long getVideoTurnedOnTime(long batteryRealtime, int which);
279
280        /**
281         * Note that these must match the constants in android.os.LocalPowerManager.
282         */
283        static final String[] USER_ACTIVITY_TYPES = {
284            "other", "cheek", "touch", "long_touch", "touch_up", "button", "unknown"
285        };
286
287        public static final int NUM_USER_ACTIVITY_TYPES = 7;
288
289        public abstract void noteUserActivityLocked(int type);
290        public abstract boolean hasUserActivity();
291        public abstract int getUserActivityCount(int type, int which);
292
293        public static abstract class Sensor {
294            // Magic sensor number for the GPS.
295            public static final int GPS = -10000;
296
297            public abstract int getHandle();
298
299            public abstract Timer getSensorTime();
300        }
301
302        /**
303         * The statistics associated with a particular process.
304         */
305        public static abstract class Proc {
306
307            /**
308             * Returns the total time (in 1/100 sec) spent executing in user code.
309             *
310             * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
311             */
312            public abstract long getUserTime(int which);
313
314            /**
315             * Returns the total time (in 1/100 sec) spent executing in system code.
316             *
317             * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
318             */
319            public abstract long getSystemTime(int which);
320
321            /**
322             * Returns the number of times the process has been started.
323             *
324             * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
325             */
326            public abstract int getStarts(int which);
327
328            /**
329             * Returns the cpu time spent in microseconds while the process was in the foreground.
330             * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED
331             * @return foreground cpu time in microseconds
332             */
333            public abstract long getForegroundTime(int which);
334
335            /**
336             * Returns the approximate cpu time spent in microseconds, at a certain CPU speed.
337             * @param speedStep the index of the CPU speed. This is not the actual speed of the
338             * CPU.
339             * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED
340             * @see BatteryStats#getCpuSpeedSteps()
341             */
342            public abstract long getTimeAtCpuSpeedStep(int speedStep, int which);
343        }
344
345        /**
346         * The statistics associated with a particular package.
347         */
348        public static abstract class Pkg {
349
350            /**
351             * Returns the number of times this package has done something that could wake up the
352             * device from sleep.
353             *
354             * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
355             */
356            public abstract int getWakeups(int which);
357
358            /**
359             * Returns a mapping containing service statistics.
360             */
361            public abstract Map<String, ? extends Serv> getServiceStats();
362
363            /**
364             * The statistics associated with a particular service.
365             */
366            public abstract class Serv {
367
368                /**
369                 * Returns the amount of time spent started.
370                 *
371                 * @param batteryUptime elapsed uptime on battery in microseconds.
372                 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
373                 * @return
374                 */
375                public abstract long getStartTime(long batteryUptime, int which);
376
377                /**
378                 * Returns the total number of times startService() has been called.
379                 *
380                 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
381                 */
382                public abstract int getStarts(int which);
383
384                /**
385                 * Returns the total number times the service has been launched.
386                 *
387                 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
388                 */
389                public abstract int getLaunches(int which);
390            }
391        }
392    }
393
394    /**
395     * Returns the number of times the device has been started.
396     */
397    public abstract int getStartCount();
398
399    /**
400     * Returns the time in microseconds that the screen has been on while the device was
401     * running on battery.
402     *
403     * {@hide}
404     */
405    public abstract long getScreenOnTime(long batteryRealtime, int which);
406
407    public static final int SCREEN_BRIGHTNESS_DARK = 0;
408    public static final int SCREEN_BRIGHTNESS_DIM = 1;
409    public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
410    public static final int SCREEN_BRIGHTNESS_LIGHT = 3;
411    public static final int SCREEN_BRIGHTNESS_BRIGHT = 4;
412
413    static final String[] SCREEN_BRIGHTNESS_NAMES = {
414        "dark", "dim", "medium", "light", "bright"
415    };
416
417    public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
418
419    /**
420     * Returns the time in microseconds that the screen has been on with
421     * the given brightness
422     *
423     * {@hide}
424     */
425    public abstract long getScreenBrightnessTime(int brightnessBin,
426            long batteryRealtime, int which);
427
428    public abstract int getInputEventCount(int which);
429
430    /**
431     * Returns the time in microseconds that the phone has been on while the device was
432     * running on battery.
433     *
434     * {@hide}
435     */
436    public abstract long getPhoneOnTime(long batteryRealtime, int which);
437
438    public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
439    public static final int SIGNAL_STRENGTH_POOR = 1;
440    public static final int SIGNAL_STRENGTH_MODERATE = 2;
441    public static final int SIGNAL_STRENGTH_GOOD = 3;
442    public static final int SIGNAL_STRENGTH_GREAT = 4;
443
444    static final String[] SIGNAL_STRENGTH_NAMES = {
445        "none", "poor", "moderate", "good", "great"
446    };
447
448    public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
449
450    /**
451     * Returns the time in microseconds that the phone has been running with
452     * the given signal strength.
453     *
454     * {@hide}
455     */
456    public abstract long getPhoneSignalStrengthTime(int strengthBin,
457            long batteryRealtime, int which);
458
459    /**
460     * Returns the time in microseconds that the phone has been trying to
461     * acquire a signal.
462     *
463     * {@hide}
464     */
465    public abstract long getPhoneSignalScanningTime(
466            long batteryRealtime, int which);
467
468    /**
469     * Returns the number of times the phone has entered the given signal strength.
470     *
471     * {@hide}
472     */
473    public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
474
475    public static final int DATA_CONNECTION_NONE = 0;
476    public static final int DATA_CONNECTION_GPRS = 1;
477    public static final int DATA_CONNECTION_EDGE = 2;
478    public static final int DATA_CONNECTION_UMTS = 3;
479    public static final int DATA_CONNECTION_OTHER = 4;
480
481    static final String[] DATA_CONNECTION_NAMES = {
482        "none", "gprs", "edge", "umts", "other"
483    };
484
485    public static final int NUM_DATA_CONNECTION_TYPES = 5;
486
487    /**
488     * Returns the time in microseconds that the phone has been running with
489     * the given data connection.
490     *
491     * {@hide}
492     */
493    public abstract long getPhoneDataConnectionTime(int dataType,
494            long batteryRealtime, int which);
495
496    /**
497     * Returns the number of times the phone has entered the given data
498     * connection type.
499     *
500     * {@hide}
501     */
502    public abstract int getPhoneDataConnectionCount(int dataType, int which);
503
504    /**
505     * Returns the time in microseconds that wifi has been on while the device was
506     * running on battery.
507     *
508     * {@hide}
509     */
510    public abstract long getWifiOnTime(long batteryRealtime, int which);
511
512    /**
513     * Returns the time in microseconds that wifi has been on and the driver has
514     * been in the running state while the device was running on battery.
515     *
516     * {@hide}
517     */
518    public abstract long getWifiRunningTime(long batteryRealtime, int which);
519
520    /**
521     * Returns the time in microseconds that bluetooth has been on while the device was
522     * running on battery.
523     *
524     * {@hide}
525     */
526    public abstract long getBluetoothOnTime(long batteryRealtime, int which);
527
528    /**
529     * Return whether we are currently running on battery.
530     */
531    public abstract boolean getIsOnBattery();
532
533    /**
534     * Returns a SparseArray containing the statistics for each uid.
535     */
536    public abstract SparseArray<? extends Uid> getUidStats();
537
538    /**
539     * Returns the current battery uptime in microseconds.
540     *
541     * @param curTime the amount of elapsed realtime in microseconds.
542     */
543    public abstract long getBatteryUptime(long curTime);
544
545    /**
546     * @deprecated use getRadioDataUptime
547     */
548    public long getRadioDataUptimeMs() {
549        return getRadioDataUptime() / 1000;
550    }
551
552    /**
553     * Returns the time that the radio was on for data transfers.
554     * @return the uptime in microseconds while unplugged
555     */
556    public abstract long getRadioDataUptime();
557
558    /**
559     * Returns the current battery realtime in microseconds.
560     *
561     * @param curTime the amount of elapsed realtime in microseconds.
562     */
563    public abstract long getBatteryRealtime(long curTime);
564
565    /**
566     * Returns the battery percentage level at the last time the device was unplugged from power, or
567     * the last time it booted on battery power.
568     */
569    public abstract int getDischargeStartLevel();
570
571    /**
572     * Returns the current battery percentage level if we are in a discharge cycle, otherwise
573     * returns the level at the last plug event.
574     */
575    public abstract int getDischargeCurrentLevel();
576
577    /**
578     * Returns the total, last, or current battery uptime in microseconds.
579     *
580     * @param curTime the elapsed realtime in microseconds.
581     * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
582     */
583    public abstract long computeBatteryUptime(long curTime, int which);
584
585    /**
586     * Returns the total, last, or current battery realtime in microseconds.
587     *
588     * @param curTime the current elapsed realtime in microseconds.
589     * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
590     */
591    public abstract long computeBatteryRealtime(long curTime, int which);
592
593    /**
594     * Returns the total, last, or current uptime in microseconds.
595     *
596     * @param curTime the current elapsed realtime in microseconds.
597     * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
598     */
599    public abstract long computeUptime(long curTime, int which);
600
601    /**
602     * Returns the total, last, or current realtime in microseconds.
603     * *
604     * @param curTime the current elapsed realtime in microseconds.
605     * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
606     */
607    public abstract long computeRealtime(long curTime, int which);
608
609    public abstract Map<String, ? extends Timer> getKernelWakelockStats();
610
611    /** Returns the number of different speeds that the CPU can run at */
612    public abstract int getCpuSpeedSteps();
613
614    private final static void formatTimeRaw(StringBuilder out, long seconds) {
615        long days = seconds / (60 * 60 * 24);
616        if (days != 0) {
617            out.append(days);
618            out.append("d ");
619        }
620        long used = days * 60 * 60 * 24;
621
622        long hours = (seconds - used) / (60 * 60);
623        if (hours != 0 || used != 0) {
624            out.append(hours);
625            out.append("h ");
626        }
627        used += hours * 60 * 60;
628
629        long mins = (seconds-used) / 60;
630        if (mins != 0 || used != 0) {
631            out.append(mins);
632            out.append("m ");
633        }
634        used += mins * 60;
635
636        if (seconds != 0 || used != 0) {
637            out.append(seconds-used);
638            out.append("s ");
639        }
640    }
641
642    private final static void formatTime(StringBuilder sb, long time) {
643        long sec = time / 100;
644        formatTimeRaw(sb, sec);
645        sb.append((time - (sec * 100)) * 10);
646        sb.append("ms ");
647    }
648
649    private final static void formatTimeMs(StringBuilder sb, long time) {
650        long sec = time / 1000;
651        formatTimeRaw(sb, sec);
652        sb.append(time - (sec * 1000));
653        sb.append("ms ");
654    }
655
656    private final String formatRatioLocked(long num, long den) {
657        if (den == 0L) {
658            return "---%";
659        }
660        float perc = ((float)num) / ((float)den) * 100;
661        mFormatBuilder.setLength(0);
662        mFormatter.format("%.1f%%", perc);
663        return mFormatBuilder.toString();
664    }
665
666    private final String formatBytesLocked(long bytes) {
667        mFormatBuilder.setLength(0);
668
669        if (bytes < BYTES_PER_KB) {
670            return bytes + "B";
671        } else if (bytes < BYTES_PER_MB) {
672            mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB);
673            return mFormatBuilder.toString();
674        } else if (bytes < BYTES_PER_GB){
675            mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB);
676            return mFormatBuilder.toString();
677        } else {
678            mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB);
679            return mFormatBuilder.toString();
680        }
681    }
682
683    /**
684     *
685     * @param sb a StringBuilder object.
686     * @param timer a Timer object contining the wakelock times.
687     * @param batteryRealtime the current on-battery time in microseconds.
688     * @param name the name of the wakelock.
689     * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
690     * @param linePrefix a String to be prepended to each line of output.
691     * @return the line prefix
692     */
693    private static final String printWakeLock(StringBuilder sb, Timer timer,
694            long batteryRealtime, String name, int which, String linePrefix) {
695
696        if (timer != null) {
697            // Convert from microseconds to milliseconds with rounding
698            long totalTimeMicros = timer.getTotalTimeLocked(batteryRealtime, which);
699            long totalTimeMillis = (totalTimeMicros + 500) / 1000;
700
701            int count = timer.getCountLocked(which);
702            if (totalTimeMillis != 0) {
703                sb.append(linePrefix);
704                formatTimeMs(sb, totalTimeMillis);
705                if (name != null) sb.append(name);
706                sb.append(' ');
707                sb.append('(');
708                sb.append(count);
709                sb.append(" times)");
710                return ", ";
711            }
712        }
713        return linePrefix;
714    }
715
716    /**
717     * Checkin version of wakelock printer. Prints simple comma-separated list.
718     *
719     * @param sb a StringBuilder object.
720     * @param timer a Timer object contining the wakelock times.
721     * @param now the current time in microseconds.
722     * @param name the name of the wakelock.
723     * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
724     * @param linePrefix a String to be prepended to each line of output.
725     * @return the line prefix
726     */
727    private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now,
728            String name, int which, String linePrefix) {
729        long totalTimeMicros = 0;
730        int count = 0;
731        if (timer != null) {
732            totalTimeMicros = timer.getTotalTimeLocked(now, which);
733            count = timer.getCountLocked(which);
734        }
735        sb.append(linePrefix);
736        sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
737        sb.append(',');
738        sb.append(name != null ? name + "," : "");
739        sb.append(count);
740        return ",";
741    }
742
743    /**
744     * Dump a comma-separated line of values for terse checkin mode.
745     *
746     * @param pw the PageWriter to dump log to
747     * @param category category of data (e.g. "total", "last", "unplugged", "current" )
748     * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
749     * @param args type-dependent data arguments
750     */
751    private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
752           Object... args ) {
753        pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
754        pw.print(uid); pw.print(',');
755        pw.print(category); pw.print(',');
756        pw.print(type);
757
758        for (Object arg : args) {
759            pw.print(',');
760            pw.print(arg);
761        }
762        pw.print('\n');
763    }
764
765    /**
766     * Checkin server version of dump to produce more compact, computer-readable log.
767     *
768     * NOTE: all times are expressed in 'ms'.
769     */
770    public final void dumpCheckinLocked(PrintWriter pw, int which, int reqUid) {
771        final long rawUptime = SystemClock.uptimeMillis() * 1000;
772        final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
773        final long batteryUptime = getBatteryUptime(rawUptime);
774        final long batteryRealtime = getBatteryRealtime(rawRealtime);
775        final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
776        final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
777        final long totalRealtime = computeRealtime(rawRealtime, which);
778        final long totalUptime = computeUptime(rawUptime, which);
779        final long screenOnTime = getScreenOnTime(batteryRealtime, which);
780        final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
781        final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
782        final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
783        final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
784
785        StringBuilder sb = new StringBuilder(128);
786
787        SparseArray<? extends Uid> uidStats = getUidStats();
788        final int NU = uidStats.size();
789
790        String category = STAT_NAMES[which];
791
792        // Dump "battery" stat
793        dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
794                which == STATS_TOTAL ? getStartCount() : "N/A",
795                whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
796                totalRealtime / 1000, totalUptime / 1000);
797
798        // Calculate total network and wakelock times across all uids.
799        long rxTotal = 0;
800        long txTotal = 0;
801        long fullWakeLockTimeTotal = 0;
802        long partialWakeLockTimeTotal = 0;
803
804        for (int iu = 0; iu < NU; iu++) {
805            Uid u = uidStats.valueAt(iu);
806            rxTotal += u.getTcpBytesReceived(which);
807            txTotal += u.getTcpBytesSent(which);
808
809            Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
810            if (wakelocks.size() > 0) {
811                for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
812                        : wakelocks.entrySet()) {
813                    Uid.Wakelock wl = ent.getValue();
814
815                    Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
816                    if (fullWakeTimer != null) {
817                        fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(batteryRealtime, which);
818                    }
819
820                    Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
821                    if (partialWakeTimer != null) {
822                        partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
823                            batteryRealtime, which);
824                    }
825                }
826            }
827        }
828
829        // Dump misc stats
830        dumpLine(pw, 0 /* uid */, category, MISC_DATA,
831                screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
832                wifiRunningTime / 1000, bluetoothOnTime / 1000, rxTotal, txTotal,
833                fullWakeLockTimeTotal, partialWakeLockTimeTotal,
834                getInputEventCount(which));
835
836        // Dump screen brightness stats
837        Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
838        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
839            args[i] = getScreenBrightnessTime(i, batteryRealtime, which) / 1000;
840        }
841        dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
842
843        // Dump signal strength stats
844        args = new Object[NUM_SIGNAL_STRENGTH_BINS];
845        for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
846            args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000;
847        }
848        dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
849        dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA,
850                getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
851        for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
852            args[i] = getPhoneSignalStrengthCount(i, which);
853        }
854        dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
855
856        // Dump network type stats
857        args = new Object[NUM_DATA_CONNECTION_TYPES];
858        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
859            args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000;
860        }
861        dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args);
862        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
863            args[i] = getPhoneDataConnectionCount(i, which);
864        }
865        dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
866
867        if (which == STATS_UNPLUGGED) {
868            dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
869                    getDischargeCurrentLevel());
870        }
871
872        if (reqUid < 0) {
873            Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
874            if (kernelWakelocks.size() > 0) {
875                for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
876                    sb.setLength(0);
877                    printWakeLockCheckin(sb, ent.getValue(), batteryRealtime, null, which, "");
878
879                    dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
880                            sb.toString());
881                }
882            }
883        }
884
885        for (int iu = 0; iu < NU; iu++) {
886            final int uid = uidStats.keyAt(iu);
887            if (reqUid >= 0 && uid != reqUid) {
888                continue;
889            }
890            Uid u = uidStats.valueAt(iu);
891            // Dump Network stats per uid, if any
892            long rx = u.getTcpBytesReceived(which);
893            long tx = u.getTcpBytesSent(which);
894            long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
895            long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
896            long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which);
897
898            if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx);
899
900            if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0
901                    || wifiTurnedOnTime != 0) {
902                dumpLine(pw, uid, category, WIFI_LOCK_DATA,
903                        fullWifiLockOnTime, scanWifiLockOnTime, wifiTurnedOnTime);
904            }
905
906            if (u.hasUserActivity()) {
907                args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
908                boolean hasData = false;
909                for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
910                    int val = u.getUserActivityCount(i, which);
911                    args[i] = val;
912                    if (val != 0) hasData = true;
913                }
914                if (hasData) {
915                    dumpLine(pw, 0 /* uid */, category, USER_ACTIVITY_DATA, args);
916                }
917            }
918
919            Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
920            if (wakelocks.size() > 0) {
921                for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
922                        : wakelocks.entrySet()) {
923                    Uid.Wakelock wl = ent.getValue();
924                    String linePrefix = "";
925                    sb.setLength(0);
926                    linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
927                            batteryRealtime, "f", which, linePrefix);
928                    linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL),
929                            batteryRealtime, "p", which, linePrefix);
930                    linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
931                            batteryRealtime, "w", which, linePrefix);
932
933                    // Only log if we had at lease one wakelock...
934                    if (sb.length() > 0) {
935                       dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString());
936                    }
937                }
938            }
939
940            Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
941            if (sensors.size() > 0)  {
942                for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
943                        : sensors.entrySet()) {
944                    Uid.Sensor se = ent.getValue();
945                    int sensorNumber = ent.getKey();
946                    Timer timer = se.getSensorTime();
947                    if (timer != null) {
948                        // Convert from microseconds to milliseconds with rounding
949                        long totalTime = (timer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
950                        int count = timer.getCountLocked(which);
951                        if (totalTime != 0) {
952                            dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
953                        }
954                    }
955                }
956            }
957
958            Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
959            if (processStats.size() > 0) {
960                for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
961                        : processStats.entrySet()) {
962                    Uid.Proc ps = ent.getValue();
963
964                    long userTime = ps.getUserTime(which);
965                    long systemTime = ps.getSystemTime(which);
966                    int starts = ps.getStarts(which);
967
968                    if (userTime != 0 || systemTime != 0 || starts != 0) {
969                        dumpLine(pw, uid, category, PROCESS_DATA,
970                                ent.getKey(), // proc
971                                userTime * 10, // cpu time in ms
972                                systemTime * 10, // user time in ms
973                                starts); // process starts
974                    }
975                }
976            }
977
978            Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
979            if (packageStats.size() > 0) {
980                for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
981                        : packageStats.entrySet()) {
982
983                    Uid.Pkg ps = ent.getValue();
984                    int wakeups = ps.getWakeups(which);
985                    Map<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
986                    for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
987                            : serviceStats.entrySet()) {
988                        BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
989                        long startTime = ss.getStartTime(batteryUptime, which);
990                        int starts = ss.getStarts(which);
991                        int launches = ss.getLaunches(which);
992                        if (startTime != 0 || starts != 0 || launches != 0) {
993                            dumpLine(pw, uid, category, APK_DATA,
994                                    wakeups, // wakeup alarms
995                                    ent.getKey(), // Apk
996                                    sent.getKey(), // service
997                                    startTime / 1000, // time spent started, in ms
998                                    starts,
999                                    launches);
1000                        }
1001                    }
1002                }
1003            }
1004        }
1005    }
1006
1007    @SuppressWarnings("unused")
1008    public final void dumpLocked(PrintWriter pw, String prefix, int which, int reqUid) {
1009        final long rawUptime = SystemClock.uptimeMillis() * 1000;
1010        final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
1011        final long batteryUptime = getBatteryUptime(rawUptime);
1012        final long batteryRealtime = getBatteryRealtime(rawRealtime);
1013
1014        final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
1015        final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
1016        final long totalRealtime = computeRealtime(rawRealtime, which);
1017        final long totalUptime = computeUptime(rawUptime, which);
1018
1019        StringBuilder sb = new StringBuilder(128);
1020
1021        SparseArray<? extends Uid> uidStats = getUidStats();
1022        final int NU = uidStats.size();
1023
1024        sb.setLength(0);
1025        sb.append(prefix);
1026                sb.append("  Time on battery: ");
1027                formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("(");
1028                sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
1029                sb.append(") realtime, ");
1030                formatTimeMs(sb, whichBatteryUptime / 1000);
1031                sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime));
1032                sb.append(") uptime");
1033        pw.println(sb.toString());
1034        sb.setLength(0);
1035        sb.append(prefix);
1036                sb.append("  Total run time: ");
1037                formatTimeMs(sb, totalRealtime / 1000);
1038                sb.append("realtime, ");
1039                formatTimeMs(sb, totalUptime / 1000);
1040                sb.append("uptime, ");
1041        pw.println(sb.toString());
1042
1043        final long screenOnTime = getScreenOnTime(batteryRealtime, which);
1044        final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
1045        final long wifiRunningTime = getWifiRunningTime(batteryRealtime, which);
1046        final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
1047        final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
1048        sb.setLength(0);
1049        sb.append(prefix);
1050                sb.append("  Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
1051                sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
1052                sb.append("), Input events: "); sb.append(getInputEventCount(which));
1053                sb.append(", Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
1054                sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
1055                sb.append(")");
1056        pw.println(sb.toString());
1057        sb.setLength(0);
1058        sb.append(prefix);
1059        sb.append("  Screen brightnesses: ");
1060        boolean didOne = false;
1061        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1062            final long time = getScreenBrightnessTime(i, batteryRealtime, which);
1063            if (time == 0) {
1064                continue;
1065            }
1066            if (didOne) sb.append(", ");
1067            didOne = true;
1068            sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
1069            sb.append(" ");
1070            formatTimeMs(sb, time/1000);
1071            sb.append("(");
1072            sb.append(formatRatioLocked(time, screenOnTime));
1073            sb.append(")");
1074        }
1075        if (!didOne) sb.append("No activity");
1076        pw.println(sb.toString());
1077
1078        // Calculate total network and wakelock times across all uids.
1079        long rxTotal = 0;
1080        long txTotal = 0;
1081        long fullWakeLockTimeTotalMicros = 0;
1082        long partialWakeLockTimeTotalMicros = 0;
1083
1084        if (reqUid < 0) {
1085            Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
1086            if (kernelWakelocks.size() > 0) {
1087                for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
1088
1089                    String linePrefix = ": ";
1090                    sb.setLength(0);
1091                    sb.append(prefix);
1092                    sb.append("  Kernel Wake lock ");
1093                    sb.append(ent.getKey());
1094                    linePrefix = printWakeLock(sb, ent.getValue(), batteryRealtime, null, which,
1095                            linePrefix);
1096                    if (!linePrefix.equals(": ")) {
1097                        sb.append(" realtime");
1098                    } else {
1099                        sb.append(": (nothing executed)");
1100                    }
1101                    pw.println(sb.toString());
1102                }
1103            }
1104        }
1105
1106        for (int iu = 0; iu < NU; iu++) {
1107            Uid u = uidStats.valueAt(iu);
1108            rxTotal += u.getTcpBytesReceived(which);
1109            txTotal += u.getTcpBytesSent(which);
1110
1111            Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1112            if (wakelocks.size() > 0) {
1113                for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1114                        : wakelocks.entrySet()) {
1115                    Uid.Wakelock wl = ent.getValue();
1116
1117                    Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
1118                    if (fullWakeTimer != null) {
1119                        fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
1120                                batteryRealtime, which);
1121                    }
1122
1123                    Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
1124                    if (partialWakeTimer != null) {
1125                        partialWakeLockTimeTotalMicros += partialWakeTimer.getTotalTimeLocked(
1126                                batteryRealtime, which);
1127                    }
1128                }
1129            }
1130        }
1131
1132        pw.print(prefix);
1133                pw.print("  Total received: "); pw.print(formatBytesLocked(rxTotal));
1134                pw.print(", Total sent: "); pw.println(formatBytesLocked(txTotal));
1135        sb.setLength(0);
1136        sb.append(prefix);
1137                sb.append("  Total full wakelock time: "); formatTimeMs(sb,
1138                        (fullWakeLockTimeTotalMicros + 500) / 1000);
1139                sb.append(", Total partial waklock time: "); formatTimeMs(sb,
1140                        (partialWakeLockTimeTotalMicros + 500) / 1000);
1141        pw.println(sb.toString());
1142
1143        sb.setLength(0);
1144        sb.append(prefix);
1145        sb.append("  Signal levels: ");
1146        didOne = false;
1147        for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
1148            final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which);
1149            if (time == 0) {
1150                continue;
1151            }
1152            if (didOne) sb.append(", ");
1153            didOne = true;
1154            sb.append(SIGNAL_STRENGTH_NAMES[i]);
1155            sb.append(" ");
1156            formatTimeMs(sb, time/1000);
1157            sb.append("(");
1158            sb.append(formatRatioLocked(time, whichBatteryRealtime));
1159            sb.append(") ");
1160            sb.append(getPhoneSignalStrengthCount(i, which));
1161            sb.append("x");
1162        }
1163        if (!didOne) sb.append("No activity");
1164        pw.println(sb.toString());
1165
1166        sb.setLength(0);
1167        sb.append(prefix);
1168        sb.append("  Signal scanning time: ");
1169        formatTimeMs(sb, getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
1170        pw.println(sb.toString());
1171
1172        sb.setLength(0);
1173        sb.append(prefix);
1174        sb.append("  Radio types: ");
1175        didOne = false;
1176        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
1177            final long time = getPhoneDataConnectionTime(i, batteryRealtime, which);
1178            if (time == 0) {
1179                continue;
1180            }
1181            if (didOne) sb.append(", ");
1182            didOne = true;
1183            sb.append(DATA_CONNECTION_NAMES[i]);
1184            sb.append(" ");
1185            formatTimeMs(sb, time/1000);
1186            sb.append("(");
1187            sb.append(formatRatioLocked(time, whichBatteryRealtime));
1188            sb.append(") ");
1189            sb.append(getPhoneDataConnectionCount(i, which));
1190            sb.append("x");
1191        }
1192        if (!didOne) sb.append("No activity");
1193        pw.println(sb.toString());
1194
1195        sb.setLength(0);
1196        sb.append(prefix);
1197        sb.append("  Radio data uptime when unplugged: ");
1198        sb.append(getRadioDataUptime() / 1000);
1199        sb.append(" ms");
1200        pw.println(sb.toString());
1201
1202        sb.setLength(0);
1203        sb.append(prefix);
1204                sb.append("  Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
1205                sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
1206                sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000);
1207                sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
1208                sb.append("), Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000);
1209                sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime));
1210                sb.append(")");
1211        pw.println(sb.toString());
1212
1213        pw.println(" ");
1214
1215        if (which == STATS_UNPLUGGED) {
1216            if (getIsOnBattery()) {
1217                pw.print(prefix); pw.println("  Device is currently unplugged");
1218                pw.print(prefix); pw.print("    Discharge cycle start level: ");
1219                        pw.println(getDischargeStartLevel());
1220                pw.print(prefix); pw.print("    Discharge cycle current level: ");
1221                        pw.println(getDischargeCurrentLevel());
1222            } else {
1223                pw.print(prefix); pw.println("  Device is currently plugged into power");
1224                pw.print(prefix); pw.print("    Last discharge cycle start level: ");
1225                        pw.println(getDischargeStartLevel());
1226                pw.print(prefix); pw.print("    Last discharge cycle end level: ");
1227                        pw.println(getDischargeCurrentLevel());
1228            }
1229            pw.println(" ");
1230        }
1231
1232
1233        for (int iu=0; iu<NU; iu++) {
1234            final int uid = uidStats.keyAt(iu);
1235            if (reqUid >= 0 && uid != reqUid) {
1236                continue;
1237            }
1238
1239            Uid u = uidStats.valueAt(iu);
1240
1241            pw.println(prefix + "  #" + uid + ":");
1242            boolean uidActivity = false;
1243
1244            long tcpReceived = u.getTcpBytesReceived(which);
1245            long tcpSent = u.getTcpBytesSent(which);
1246            long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
1247            long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
1248            long wifiTurnedOnTime = u.getWifiTurnedOnTime(batteryRealtime, which);
1249
1250            if (tcpReceived != 0 || tcpSent != 0) {
1251                pw.print(prefix); pw.print("    Network: ");
1252                        pw.print(formatBytesLocked(tcpReceived)); pw.print(" received, ");
1253                        pw.print(formatBytesLocked(tcpSent)); pw.println(" sent");
1254            }
1255
1256            if (u.hasUserActivity()) {
1257                boolean hasData = false;
1258                for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
1259                    int val = u.getUserActivityCount(i, which);
1260                    if (val != 0) {
1261                        if (!hasData) {
1262                            sb.setLength(0);
1263                            sb.append("    User activity: ");
1264                            hasData = true;
1265                        } else {
1266                            sb.append(", ");
1267                        }
1268                        sb.append(val);
1269                        sb.append(" ");
1270                        sb.append(Uid.USER_ACTIVITY_TYPES[i]);
1271                    }
1272                }
1273                if (hasData) {
1274                    pw.println(sb.toString());
1275                }
1276            }
1277
1278            if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0
1279                    || wifiTurnedOnTime != 0) {
1280                sb.setLength(0);
1281                sb.append(prefix); sb.append("    Turned Wifi On: ");
1282                        formatTimeMs(sb, wifiTurnedOnTime / 1000);
1283                        sb.append("("); sb.append(formatRatioLocked(wifiTurnedOnTime,
1284                                whichBatteryRealtime)); sb.append(")\n");
1285                sb.append(prefix); sb.append("    Full Wifi Lock: ");
1286                        formatTimeMs(sb, fullWifiLockOnTime / 1000);
1287                        sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
1288                                whichBatteryRealtime)); sb.append(")\n");
1289                sb.append(prefix); sb.append("    Scan Wifi Lock: ");
1290                        formatTimeMs(sb, scanWifiLockOnTime / 1000);
1291                        sb.append("("); sb.append(formatRatioLocked(scanWifiLockOnTime,
1292                                whichBatteryRealtime)); sb.append(")");
1293                pw.println(sb.toString());
1294            }
1295
1296            Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
1297            if (wakelocks.size() > 0) {
1298                for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
1299                    : wakelocks.entrySet()) {
1300                    Uid.Wakelock wl = ent.getValue();
1301                    String linePrefix = ": ";
1302                    sb.setLength(0);
1303                    sb.append(prefix);
1304                    sb.append("    Wake lock ");
1305                    sb.append(ent.getKey());
1306                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
1307                            "full", which, linePrefix);
1308                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
1309                            "partial", which, linePrefix);
1310                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
1311                            "window", which, linePrefix);
1312                    if (!linePrefix.equals(": ")) {
1313                        sb.append(" realtime");
1314                    } else {
1315                        sb.append(": (nothing executed)");
1316                    }
1317                    pw.println(sb.toString());
1318                    uidActivity = true;
1319                }
1320            }
1321
1322            Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
1323            if (sensors.size() > 0) {
1324                for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
1325                    : sensors.entrySet()) {
1326                    Uid.Sensor se = ent.getValue();
1327                    int sensorNumber = ent.getKey();
1328                    sb.setLength(0);
1329                    sb.append(prefix);
1330                    sb.append("    Sensor ");
1331                    int handle = se.getHandle();
1332                    if (handle == Uid.Sensor.GPS) {
1333                        sb.append("GPS");
1334                    } else {
1335                        sb.append(handle);
1336                    }
1337                    sb.append(": ");
1338
1339                    Timer timer = se.getSensorTime();
1340                    if (timer != null) {
1341                        // Convert from microseconds to milliseconds with rounding
1342                        long totalTime = (timer.getTotalTimeLocked(
1343                                batteryRealtime, which) + 500) / 1000;
1344                        int count = timer.getCountLocked(which);
1345                        //timer.logState();
1346                        if (totalTime != 0) {
1347                            formatTimeMs(sb, totalTime);
1348                            sb.append("realtime (");
1349                            sb.append(count);
1350                            sb.append(" times)");
1351                        } else {
1352                            sb.append("(not used)");
1353                        }
1354                    } else {
1355                        sb.append("(not used)");
1356                    }
1357
1358                    pw.println(sb.toString());
1359                    uidActivity = true;
1360                }
1361            }
1362
1363            Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
1364            if (processStats.size() > 0) {
1365                for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
1366                    : processStats.entrySet()) {
1367                    Uid.Proc ps = ent.getValue();
1368                    long userTime;
1369                    long systemTime;
1370                    int starts;
1371
1372                    userTime = ps.getUserTime(which);
1373                    systemTime = ps.getSystemTime(which);
1374                    starts = ps.getStarts(which);
1375
1376                    if (userTime != 0 || systemTime != 0 || starts != 0) {
1377                        sb.setLength(0);
1378                        sb.append(prefix); sb.append("    Proc ");
1379                                sb.append(ent.getKey()); sb.append(":\n");
1380                        sb.append(prefix); sb.append("      CPU: ");
1381                                formatTime(sb, userTime); sb.append("usr + ");
1382                                formatTime(sb, systemTime); sb.append("krn\n");
1383                        sb.append(prefix); sb.append("      "); sb.append(starts);
1384                                sb.append(" proc starts");
1385                        pw.println(sb.toString());
1386                        uidActivity = true;
1387                    }
1388                }
1389            }
1390
1391            Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
1392            if (packageStats.size() > 0) {
1393                for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
1394                    : packageStats.entrySet()) {
1395                    pw.print(prefix); pw.print("    Apk "); pw.print(ent.getKey()); pw.println(":");
1396                    boolean apkActivity = false;
1397                    Uid.Pkg ps = ent.getValue();
1398                    int wakeups = ps.getWakeups(which);
1399                    if (wakeups != 0) {
1400                        pw.print(prefix); pw.print("      ");
1401                                pw.print(wakeups); pw.println(" wakeup alarms");
1402                        apkActivity = true;
1403                    }
1404                    Map<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
1405                    if (serviceStats.size() > 0) {
1406                        for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
1407                                : serviceStats.entrySet()) {
1408                            BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
1409                            long startTime = ss.getStartTime(batteryUptime, which);
1410                            int starts = ss.getStarts(which);
1411                            int launches = ss.getLaunches(which);
1412                            if (startTime != 0 || starts != 0 || launches != 0) {
1413                                sb.setLength(0);
1414                                sb.append(prefix); sb.append("      Service ");
1415                                        sb.append(sent.getKey()); sb.append(":\n");
1416                                sb.append(prefix); sb.append("        Created for: ");
1417                                        formatTimeMs(sb, startTime / 1000);
1418                                        sb.append(" uptime\n");
1419                                sb.append(prefix); sb.append("        Starts: ");
1420                                        sb.append(starts);
1421                                        sb.append(", launches: "); sb.append(launches);
1422                                pw.println(sb.toString());
1423                                apkActivity = true;
1424                            }
1425                        }
1426                    }
1427                    if (!apkActivity) {
1428                        pw.print(prefix); pw.println("      (nothing executed)");
1429                    }
1430                    uidActivity = true;
1431                }
1432            }
1433            if (!uidActivity) {
1434                pw.print(prefix); pw.println("    (nothing executed)");
1435            }
1436        }
1437    }
1438
1439    /**
1440     * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
1441     *
1442     * @param pw a Printer to receive the dump output.
1443     */
1444    @SuppressWarnings("unused")
1445    public void dumpLocked(PrintWriter pw) {
1446        pw.println("Total Statistics (Current and Historic):");
1447        pw.println("  System starts: " + getStartCount()
1448                + ", currently on battery: " + getIsOnBattery());
1449        dumpLocked(pw, "", STATS_TOTAL, -1);
1450        pw.println("");
1451        pw.println("Last Run Statistics (Previous run of system):");
1452        dumpLocked(pw, "", STATS_LAST, -1);
1453        pw.println("");
1454        pw.println("Current Battery Statistics (Currently running system):");
1455        dumpLocked(pw, "", STATS_CURRENT, -1);
1456        pw.println("");
1457        pw.println("Unplugged Statistics (Since last unplugged from power):");
1458        dumpLocked(pw, "", STATS_UNPLUGGED, -1);
1459    }
1460
1461    @SuppressWarnings("unused")
1462    public void dumpCheckinLocked(PrintWriter pw, String[] args) {
1463        boolean isUnpluggedOnly = false;
1464
1465        for (String arg : args) {
1466            if ("-u".equals(arg)) {
1467                if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data");
1468                isUnpluggedOnly = true;
1469            }
1470        }
1471
1472        if (isUnpluggedOnly) {
1473            dumpCheckinLocked(pw, STATS_UNPLUGGED, -1);
1474        }
1475        else {
1476            dumpCheckinLocked(pw, STATS_TOTAL, -1);
1477            dumpCheckinLocked(pw, STATS_LAST, -1);
1478            dumpCheckinLocked(pw, STATS_UNPLUGGED, -1);
1479            dumpCheckinLocked(pw, STATS_CURRENT, -1);
1480        }
1481    }
1482
1483}
1484