Home | History | Annotate | Download | only in os
      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 
     17 package android.os;
     18 
     19 import java.io.PrintWriter;
     20 import java.util.Formatter;
     21 import java.util.Map;
     22 
     23 import android.util.Log;
     24 import android.util.Printer;
     25 import 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  */
     33 public 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