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.ArrayList;
     21 import java.util.Collections;
     22 import java.util.Comparator;
     23 import java.util.Formatter;
     24 import java.util.HashMap;
     25 import java.util.List;
     26 import java.util.Map;
     27 
     28 import android.content.Context;
     29 import android.content.pm.ApplicationInfo;
     30 import android.telephony.SignalStrength;
     31 import android.text.format.DateFormat;
     32 import android.util.Printer;
     33 import android.util.SparseArray;
     34 import android.util.SparseIntArray;
     35 import android.util.TimeUtils;
     36 import android.view.Display;
     37 import com.android.internal.os.BatterySipper;
     38 import com.android.internal.os.BatteryStatsHelper;
     39 
     40 /**
     41  * A class providing access to battery usage statistics, including information on
     42  * wakelocks, processes, packages, and services.  All times are represented in microseconds
     43  * except where indicated otherwise.
     44  * @hide
     45  */
     46 public abstract class BatteryStats implements Parcelable {
     47 
     48     private static final boolean LOCAL_LOGV = false;
     49 
     50     /** @hide */
     51     public static final String SERVICE_NAME = "batterystats";
     52 
     53     /**
     54      * A constant indicating a partial wake lock timer.
     55      */
     56     public static final int WAKE_TYPE_PARTIAL = 0;
     57 
     58     /**
     59      * A constant indicating a full wake lock timer.
     60      */
     61     public static final int WAKE_TYPE_FULL = 1;
     62 
     63     /**
     64      * A constant indicating a window wake lock timer.
     65      */
     66     public static final int WAKE_TYPE_WINDOW = 2;
     67 
     68     /**
     69      * A constant indicating a sensor timer.
     70      */
     71     public static final int SENSOR = 3;
     72 
     73     /**
     74      * A constant indicating a a wifi running timer
     75      */
     76     public static final int WIFI_RUNNING = 4;
     77 
     78     /**
     79      * A constant indicating a full wifi lock timer
     80      */
     81     public static final int FULL_WIFI_LOCK = 5;
     82 
     83     /**
     84      * A constant indicating a wifi scan
     85      */
     86     public static final int WIFI_SCAN = 6;
     87 
     88      /**
     89       * A constant indicating a wifi multicast timer
     90       */
     91      public static final int WIFI_MULTICAST_ENABLED = 7;
     92 
     93     /**
     94      * A constant indicating a video turn on timer
     95      */
     96     public static final int VIDEO_TURNED_ON = 8;
     97 
     98     /**
     99      * A constant indicating a vibrator on timer
    100      */
    101     public static final int VIBRATOR_ON = 9;
    102 
    103     /**
    104      * A constant indicating a foreground activity timer
    105      */
    106     public static final int FOREGROUND_ACTIVITY = 10;
    107 
    108     /**
    109      * A constant indicating a wifi batched scan is active
    110      */
    111     public static final int WIFI_BATCHED_SCAN = 11;
    112 
    113     /**
    114      * A constant indicating a process state timer
    115      */
    116     public static final int PROCESS_STATE = 12;
    117 
    118     /**
    119      * A constant indicating a sync timer
    120      */
    121     public static final int SYNC = 13;
    122 
    123     /**
    124      * A constant indicating a job timer
    125      */
    126     public static final int JOB = 14;
    127 
    128     /**
    129      * A constant indicating an audio turn on timer
    130      */
    131     public static final int AUDIO_TURNED_ON = 15;
    132 
    133     /**
    134      * Include all of the data in the stats, including previously saved data.
    135      */
    136     public static final int STATS_SINCE_CHARGED = 0;
    137 
    138     /**
    139      * Include only the current run in the stats.
    140      */
    141     public static final int STATS_CURRENT = 1;
    142 
    143     /**
    144      * Include only the run since the last time the device was unplugged in the stats.
    145      */
    146     public static final int STATS_SINCE_UNPLUGGED = 2;
    147 
    148     // NOTE: Update this list if you add/change any stats above.
    149     // These characters are supposed to represent "total", "last", "current",
    150     // and "unplugged". They were shortened for efficiency sake.
    151     private static final String[] STAT_NAMES = { "l", "c", "u" };
    152 
    153     /**
    154      * Bump the version on this if the checkin format changes.
    155      */
    156     private static final int BATTERY_STATS_CHECKIN_VERSION = 9;
    157 
    158     private static final long BYTES_PER_KB = 1024;
    159     private static final long BYTES_PER_MB = 1048576; // 1024^2
    160     private static final long BYTES_PER_GB = 1073741824; //1024^3
    161 
    162     private static final String VERSION_DATA = "vers";
    163     private static final String UID_DATA = "uid";
    164     private static final String APK_DATA = "apk";
    165     private static final String PROCESS_DATA = "pr";
    166     private static final String SENSOR_DATA = "sr";
    167     private static final String VIBRATOR_DATA = "vib";
    168     private static final String FOREGROUND_DATA = "fg";
    169     private static final String STATE_TIME_DATA = "st";
    170     private static final String WAKELOCK_DATA = "wl";
    171     private static final String SYNC_DATA = "sy";
    172     private static final String JOB_DATA = "jb";
    173     private static final String KERNEL_WAKELOCK_DATA = "kwl";
    174     private static final String WAKEUP_REASON_DATA = "wr";
    175     private static final String NETWORK_DATA = "nt";
    176     private static final String USER_ACTIVITY_DATA = "ua";
    177     private static final String BATTERY_DATA = "bt";
    178     private static final String BATTERY_DISCHARGE_DATA = "dc";
    179     private static final String BATTERY_LEVEL_DATA = "lv";
    180     private static final String WIFI_DATA = "wfl";
    181     private static final String MISC_DATA = "m";
    182     private static final String GLOBAL_NETWORK_DATA = "gn";
    183     private static final String HISTORY_STRING_POOL = "hsp";
    184     private static final String HISTORY_DATA = "h";
    185     private static final String SCREEN_BRIGHTNESS_DATA = "br";
    186     private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt";
    187     private static final String SIGNAL_SCANNING_TIME_DATA = "sst";
    188     private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc";
    189     private static final String DATA_CONNECTION_TIME_DATA = "dct";
    190     private static final String DATA_CONNECTION_COUNT_DATA = "dcc";
    191     private static final String WIFI_STATE_TIME_DATA = "wst";
    192     private static final String WIFI_STATE_COUNT_DATA = "wsc";
    193     private static final String WIFI_SUPPL_STATE_TIME_DATA = "wsst";
    194     private static final String WIFI_SUPPL_STATE_COUNT_DATA = "wssc";
    195     private static final String WIFI_SIGNAL_STRENGTH_TIME_DATA = "wsgt";
    196     private static final String WIFI_SIGNAL_STRENGTH_COUNT_DATA = "wsgc";
    197     private static final String BLUETOOTH_STATE_TIME_DATA = "bst";
    198     private static final String BLUETOOTH_STATE_COUNT_DATA = "bsc";
    199     private static final String POWER_USE_SUMMARY_DATA = "pws";
    200     private static final String POWER_USE_ITEM_DATA = "pwi";
    201     private static final String DISCHARGE_STEP_DATA = "dsd";
    202     private static final String CHARGE_STEP_DATA = "csd";
    203     private static final String DISCHARGE_TIME_REMAIN_DATA = "dtr";
    204     private static final String CHARGE_TIME_REMAIN_DATA = "ctr";
    205 
    206     private final StringBuilder mFormatBuilder = new StringBuilder(32);
    207     private final Formatter mFormatter = new Formatter(mFormatBuilder);
    208 
    209     /**
    210      * State for keeping track of counting information.
    211      */
    212     public static abstract class Counter {
    213 
    214         /**
    215          * Returns the count associated with this Counter for the
    216          * selected type of statistics.
    217          *
    218          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
    219          */
    220         public abstract int getCountLocked(int which);
    221 
    222         /**
    223          * Temporary for debugging.
    224          */
    225         public abstract void logState(Printer pw, String prefix);
    226     }
    227 
    228     /**
    229      * State for keeping track of long counting information.
    230      */
    231     public static abstract class LongCounter {
    232 
    233         /**
    234          * Returns the count associated with this Counter for the
    235          * selected type of statistics.
    236          *
    237          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
    238          */
    239         public abstract long getCountLocked(int which);
    240 
    241         /**
    242          * Temporary for debugging.
    243          */
    244         public abstract void logState(Printer pw, String prefix);
    245     }
    246 
    247     /**
    248      * State for keeping track of timing information.
    249      */
    250     public static abstract class Timer {
    251 
    252         /**
    253          * Returns the count associated with this Timer for the
    254          * selected type of statistics.
    255          *
    256          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
    257          */
    258         public abstract int getCountLocked(int which);
    259 
    260         /**
    261          * Returns the total time in microseconds associated with this Timer for the
    262          * selected type of statistics.
    263          *
    264          * @param elapsedRealtimeUs current elapsed realtime of system in microseconds
    265          * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT
    266          * @return a time in microseconds
    267          */
    268         public abstract long getTotalTimeLocked(long elapsedRealtimeUs, int which);
    269 
    270         /**
    271          * Temporary for debugging.
    272          */
    273         public abstract void logState(Printer pw, String prefix);
    274     }
    275 
    276     /**
    277      * The statistics associated with a particular uid.
    278      */
    279     public static abstract class Uid {
    280 
    281         /**
    282          * Returns a mapping containing wakelock statistics.
    283          *
    284          * @return a Map from Strings to Uid.Wakelock objects.
    285          */
    286         public abstract Map<String, ? extends Wakelock> getWakelockStats();
    287 
    288         /**
    289          * Returns a mapping containing sync statistics.
    290          *
    291          * @return a Map from Strings to Timer objects.
    292          */
    293         public abstract Map<String, ? extends Timer> getSyncStats();
    294 
    295         /**
    296          * Returns a mapping containing scheduled job statistics.
    297          *
    298          * @return a Map from Strings to Timer objects.
    299          */
    300         public abstract Map<String, ? extends Timer> getJobStats();
    301 
    302         /**
    303          * The statistics associated with a particular wake lock.
    304          */
    305         public static abstract class Wakelock {
    306             public abstract Timer getWakeTime(int type);
    307         }
    308 
    309         /**
    310          * Returns a mapping containing sensor statistics.
    311          *
    312          * @return a Map from Integer sensor ids to Uid.Sensor objects.
    313          */
    314         public abstract SparseArray<? extends Sensor> getSensorStats();
    315 
    316         /**
    317          * Returns a mapping containing active process data.
    318          */
    319         public abstract SparseArray<? extends Pid> getPidStats();
    320 
    321         /**
    322          * Returns a mapping containing process statistics.
    323          *
    324          * @return a Map from Strings to Uid.Proc objects.
    325          */
    326         public abstract Map<String, ? extends Proc> getProcessStats();
    327 
    328         /**
    329          * Returns a mapping containing package statistics.
    330          *
    331          * @return a Map from Strings to Uid.Pkg objects.
    332          */
    333         public abstract Map<String, ? extends Pkg> getPackageStats();
    334 
    335         /**
    336          * {@hide}
    337          */
    338         public abstract int getUid();
    339 
    340         public abstract void noteWifiRunningLocked(long elapsedRealtime);
    341         public abstract void noteWifiStoppedLocked(long elapsedRealtime);
    342         public abstract void noteFullWifiLockAcquiredLocked(long elapsedRealtime);
    343         public abstract void noteFullWifiLockReleasedLocked(long elapsedRealtime);
    344         public abstract void noteWifiScanStartedLocked(long elapsedRealtime);
    345         public abstract void noteWifiScanStoppedLocked(long elapsedRealtime);
    346         public abstract void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtime);
    347         public abstract void noteWifiBatchedScanStoppedLocked(long elapsedRealtime);
    348         public abstract void noteWifiMulticastEnabledLocked(long elapsedRealtime);
    349         public abstract void noteWifiMulticastDisabledLocked(long elapsedRealtime);
    350         public abstract void noteActivityResumedLocked(long elapsedRealtime);
    351         public abstract void noteActivityPausedLocked(long elapsedRealtime);
    352         public abstract long getWifiRunningTime(long elapsedRealtimeUs, int which);
    353         public abstract long getFullWifiLockTime(long elapsedRealtimeUs, int which);
    354         public abstract long getWifiScanTime(long elapsedRealtimeUs, int which);
    355         public abstract long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which);
    356         public abstract long getWifiMulticastTime(long elapsedRealtimeUs, int which);
    357         public abstract long getAudioTurnedOnTime(long elapsedRealtimeUs, int which);
    358         public abstract long getVideoTurnedOnTime(long elapsedRealtimeUs, int which);
    359         public abstract Timer getForegroundActivityTimer();
    360 
    361         // Time this uid has any processes in foreground state.
    362         public static final int PROCESS_STATE_FOREGROUND = 0;
    363         // Time this uid has any process in active state (not cached).
    364         public static final int PROCESS_STATE_ACTIVE = 1;
    365         // Time this uid has any processes running at all.
    366         public static final int PROCESS_STATE_RUNNING = 2;
    367         // Total number of process states we track.
    368         public static final int NUM_PROCESS_STATE = 3;
    369 
    370         static final String[] PROCESS_STATE_NAMES = {
    371             "Foreground", "Active", "Running"
    372         };
    373 
    374         public abstract long getProcessStateTime(int state, long elapsedRealtimeUs, int which);
    375 
    376         public abstract Timer getVibratorOnTimer();
    377 
    378         public static final int NUM_WIFI_BATCHED_SCAN_BINS = 5;
    379 
    380         /**
    381          * Note that these must match the constants in android.os.PowerManager.
    382          * Also, if the user activity types change, the BatteryStatsImpl.VERSION must
    383          * also be bumped.
    384          */
    385         static final String[] USER_ACTIVITY_TYPES = {
    386             "other", "button", "touch"
    387         };
    388 
    389         public static final int NUM_USER_ACTIVITY_TYPES = 3;
    390 
    391         public abstract void noteUserActivityLocked(int type);
    392         public abstract boolean hasUserActivity();
    393         public abstract int getUserActivityCount(int type, int which);
    394 
    395         public abstract boolean hasNetworkActivity();
    396         public abstract long getNetworkActivityBytes(int type, int which);
    397         public abstract long getNetworkActivityPackets(int type, int which);
    398         public abstract long getMobileRadioActiveTime(int which);
    399         public abstract int getMobileRadioActiveCount(int which);
    400 
    401         public static abstract class Sensor {
    402             /*
    403              * FIXME: it's not correct to use this magic value because it
    404              * could clash with a sensor handle (which are defined by
    405              * the sensor HAL, and therefore out of our control
    406              */
    407             // Magic sensor number for the GPS.
    408             public static final int GPS = -10000;
    409 
    410             public abstract int getHandle();
    411 
    412             public abstract Timer getSensorTime();
    413         }
    414 
    415         public class Pid {
    416             public int mWakeNesting;
    417             public long mWakeSumMs;
    418             public long mWakeStartMs;
    419         }
    420 
    421         /**
    422          * The statistics associated with a particular process.
    423          */
    424         public static abstract class Proc {
    425 
    426             public static class ExcessivePower {
    427                 public static final int TYPE_WAKE = 1;
    428                 public static final int TYPE_CPU = 2;
    429 
    430                 public int type;
    431                 public long overTime;
    432                 public long usedTime;
    433             }
    434 
    435             /**
    436              * Returns true if this process is still active in the battery stats.
    437              */
    438             public abstract boolean isActive();
    439 
    440             /**
    441              * Returns the total time (in 1/100 sec) spent executing in user code.
    442              *
    443              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    444              */
    445             public abstract long getUserTime(int which);
    446 
    447             /**
    448              * Returns the total time (in 1/100 sec) spent executing in system code.
    449              *
    450              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    451              */
    452             public abstract long getSystemTime(int which);
    453 
    454             /**
    455              * Returns the number of times the process has been started.
    456              *
    457              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    458              */
    459             public abstract int getStarts(int which);
    460 
    461             /**
    462              * Returns the number of times the process has crashed.
    463              *
    464              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    465              */
    466             public abstract int getNumCrashes(int which);
    467 
    468             /**
    469              * Returns the number of times the process has ANRed.
    470              *
    471              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    472              */
    473             public abstract int getNumAnrs(int which);
    474 
    475             /**
    476              * Returns the cpu time spent in microseconds while the process was in the foreground.
    477              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    478              * @return foreground cpu time in microseconds
    479              */
    480             public abstract long getForegroundTime(int which);
    481 
    482             /**
    483              * Returns the approximate cpu time spent in microseconds, at a certain CPU speed.
    484              * @param speedStep the index of the CPU speed. This is not the actual speed of the
    485              * CPU.
    486              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    487              * @see BatteryStats#getCpuSpeedSteps()
    488              */
    489             public abstract long getTimeAtCpuSpeedStep(int speedStep, int which);
    490 
    491             public abstract int countExcessivePowers();
    492 
    493             public abstract ExcessivePower getExcessivePower(int i);
    494         }
    495 
    496         /**
    497          * The statistics associated with a particular package.
    498          */
    499         public static abstract class Pkg {
    500 
    501             /**
    502              * Returns the number of times this package has done something that could wake up the
    503              * device from sleep.
    504              *
    505              * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    506              */
    507             public abstract int getWakeups(int which);
    508 
    509             /**
    510              * Returns a mapping containing service statistics.
    511              */
    512             public abstract Map<String, ? extends Serv> getServiceStats();
    513 
    514             /**
    515              * The statistics associated with a particular service.
    516              */
    517             public abstract class Serv {
    518 
    519                 /**
    520                  * Returns the amount of time spent started.
    521                  *
    522                  * @param batteryUptime elapsed uptime on battery in microseconds.
    523                  * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    524                  * @return
    525                  */
    526                 public abstract long getStartTime(long batteryUptime, int which);
    527 
    528                 /**
    529                  * Returns the total number of times startService() has been called.
    530                  *
    531                  * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    532                  */
    533                 public abstract int getStarts(int which);
    534 
    535                 /**
    536                  * Returns the total number times the service has been launched.
    537                  *
    538                  * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
    539                  */
    540                 public abstract int getLaunches(int which);
    541             }
    542         }
    543     }
    544 
    545     public final static class HistoryTag {
    546         public String string;
    547         public int uid;
    548 
    549         public int poolIdx;
    550 
    551         public void setTo(HistoryTag o) {
    552             string = o.string;
    553             uid = o.uid;
    554             poolIdx = o.poolIdx;
    555         }
    556 
    557         public void setTo(String _string, int _uid) {
    558             string = _string;
    559             uid = _uid;
    560             poolIdx = -1;
    561         }
    562 
    563         public void writeToParcel(Parcel dest, int flags) {
    564             dest.writeString(string);
    565             dest.writeInt(uid);
    566         }
    567 
    568         public void readFromParcel(Parcel src) {
    569             string = src.readString();
    570             uid = src.readInt();
    571             poolIdx = -1;
    572         }
    573 
    574         @Override
    575         public boolean equals(Object o) {
    576             if (this == o) return true;
    577             if (o == null || getClass() != o.getClass()) return false;
    578 
    579             HistoryTag that = (HistoryTag) o;
    580 
    581             if (uid != that.uid) return false;
    582             if (!string.equals(that.string)) return false;
    583 
    584             return true;
    585         }
    586 
    587         @Override
    588         public int hashCode() {
    589             int result = string.hashCode();
    590             result = 31 * result + uid;
    591             return result;
    592         }
    593     }
    594 
    595     public final static class HistoryItem implements Parcelable {
    596         public HistoryItem next;
    597 
    598         // The time of this event in milliseconds, as per SystemClock.elapsedRealtime().
    599         public long time;
    600 
    601         public static final byte CMD_UPDATE = 0;        // These can be written as deltas
    602         public static final byte CMD_NULL = -1;
    603         public static final byte CMD_START = 4;
    604         public static final byte CMD_CURRENT_TIME = 5;
    605         public static final byte CMD_OVERFLOW = 6;
    606         public static final byte CMD_RESET = 7;
    607         public static final byte CMD_SHUTDOWN = 8;
    608 
    609         public byte cmd = CMD_NULL;
    610 
    611         /**
    612          * Return whether the command code is a delta data update.
    613          */
    614         public boolean isDeltaData() {
    615             return cmd == CMD_UPDATE;
    616         }
    617 
    618         public byte batteryLevel;
    619         public byte batteryStatus;
    620         public byte batteryHealth;
    621         public byte batteryPlugType;
    622 
    623         public short batteryTemperature;
    624         public char batteryVoltage;
    625 
    626         // Constants from SCREEN_BRIGHTNESS_*
    627         public static final int STATE_BRIGHTNESS_SHIFT = 0;
    628         public static final int STATE_BRIGHTNESS_MASK = 0x7;
    629         // Constants from SIGNAL_STRENGTH_*
    630         public static final int STATE_PHONE_SIGNAL_STRENGTH_SHIFT = 3;
    631         public static final int STATE_PHONE_SIGNAL_STRENGTH_MASK = 0x7 << STATE_PHONE_SIGNAL_STRENGTH_SHIFT;
    632         // Constants from ServiceState.STATE_*
    633         public static final int STATE_PHONE_STATE_SHIFT = 6;
    634         public static final int STATE_PHONE_STATE_MASK = 0x7 << STATE_PHONE_STATE_SHIFT;
    635         // Constants from DATA_CONNECTION_*
    636         public static final int STATE_DATA_CONNECTION_SHIFT = 9;
    637         public static final int STATE_DATA_CONNECTION_MASK = 0x1f << STATE_DATA_CONNECTION_SHIFT;
    638 
    639         // These states always appear directly in the first int token
    640         // of a delta change; they should be ones that change relatively
    641         // frequently.
    642         public static final int STATE_CPU_RUNNING_FLAG = 1<<31;
    643         public static final int STATE_WAKE_LOCK_FLAG = 1<<30;
    644         public static final int STATE_GPS_ON_FLAG = 1<<29;
    645         public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<28;
    646         public static final int STATE_WIFI_SCAN_FLAG = 1<<27;
    647         public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<26;
    648         public static final int STATE_MOBILE_RADIO_ACTIVE_FLAG = 1<<25;
    649         // These are on the lower bits used for the command; if they change
    650         // we need to write another int of data.
    651         public static final int STATE_SENSOR_ON_FLAG = 1<<23;
    652         public static final int STATE_AUDIO_ON_FLAG = 1<<22;
    653         public static final int STATE_PHONE_SCANNING_FLAG = 1<<21;
    654         public static final int STATE_SCREEN_ON_FLAG = 1<<20;
    655         public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19;
    656         public static final int STATE_PHONE_IN_CALL_FLAG = 1<<18;
    657         public static final int STATE_BLUETOOTH_ON_FLAG = 1<<16;
    658 
    659         public static final int MOST_INTERESTING_STATES =
    660             STATE_BATTERY_PLUGGED_FLAG | STATE_SCREEN_ON_FLAG
    661             | STATE_PHONE_IN_CALL_FLAG | STATE_BLUETOOTH_ON_FLAG;
    662 
    663         public int states;
    664 
    665         // Constants from WIFI_SUPPL_STATE_*
    666         public static final int STATE2_WIFI_SUPPL_STATE_SHIFT = 0;
    667         public static final int STATE2_WIFI_SUPPL_STATE_MASK = 0xf;
    668         // Values for NUM_WIFI_SIGNAL_STRENGTH_BINS
    669         public static final int STATE2_WIFI_SIGNAL_STRENGTH_SHIFT = 4;
    670         public static final int STATE2_WIFI_SIGNAL_STRENGTH_MASK =
    671                 0x7 << STATE2_WIFI_SIGNAL_STRENGTH_SHIFT;
    672 
    673         public static final int STATE2_LOW_POWER_FLAG = 1<<31;
    674         public static final int STATE2_VIDEO_ON_FLAG = 1<<30;
    675         public static final int STATE2_WIFI_RUNNING_FLAG = 1<<29;
    676         public static final int STATE2_WIFI_ON_FLAG = 1<<28;
    677         public static final int STATE2_FLASHLIGHT_FLAG = 1<<27;
    678 
    679         public static final int MOST_INTERESTING_STATES2 =
    680             STATE2_LOW_POWER_FLAG | STATE2_WIFI_ON_FLAG;
    681 
    682         public int states2;
    683 
    684         // The wake lock that was acquired at this point.
    685         public HistoryTag wakelockTag;
    686 
    687         // Kernel wakeup reason at this point.
    688         public HistoryTag wakeReasonTag;
    689 
    690         public static final int EVENT_FLAG_START = 0x8000;
    691         public static final int EVENT_FLAG_FINISH = 0x4000;
    692 
    693         // No event in this item.
    694         public static final int EVENT_NONE = 0x0000;
    695         // Event is about a process that is running.
    696         public static final int EVENT_PROC = 0x0001;
    697         // Event is about an application package that is in the foreground.
    698         public static final int EVENT_FOREGROUND = 0x0002;
    699         // Event is about an application package that is at the top of the screen.
    700         public static final int EVENT_TOP = 0x0003;
    701         // Event is about active sync operations.
    702         public static final int EVENT_SYNC = 0x0004;
    703         // Events for all additional wake locks aquired/release within a wake block.
    704         // These are not generated by default.
    705         public static final int EVENT_WAKE_LOCK = 0x0005;
    706         // Event is about an application executing a scheduled job.
    707         public static final int EVENT_JOB = 0x0006;
    708         // Events for users running.
    709         public static final int EVENT_USER_RUNNING = 0x0007;
    710         // Events for foreground user.
    711         public static final int EVENT_USER_FOREGROUND = 0x0008;
    712         // Events for connectivity changed.
    713         public static final int EVENT_CONNECTIVITY_CHANGED = 0x0009;
    714         // Number of event types.
    715         public static final int EVENT_COUNT = 0x000a;
    716         // Mask to extract out only the type part of the event.
    717         public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH);
    718 
    719         public static final int EVENT_PROC_START = EVENT_PROC | EVENT_FLAG_START;
    720         public static final int EVENT_PROC_FINISH = EVENT_PROC | EVENT_FLAG_FINISH;
    721         public static final int EVENT_FOREGROUND_START = EVENT_FOREGROUND | EVENT_FLAG_START;
    722         public static final int EVENT_FOREGROUND_FINISH = EVENT_FOREGROUND | EVENT_FLAG_FINISH;
    723         public static final int EVENT_TOP_START = EVENT_TOP | EVENT_FLAG_START;
    724         public static final int EVENT_TOP_FINISH = EVENT_TOP | EVENT_FLAG_FINISH;
    725         public static final int EVENT_SYNC_START = EVENT_SYNC | EVENT_FLAG_START;
    726         public static final int EVENT_SYNC_FINISH = EVENT_SYNC | EVENT_FLAG_FINISH;
    727         public static final int EVENT_WAKE_LOCK_START = EVENT_WAKE_LOCK | EVENT_FLAG_START;
    728         public static final int EVENT_WAKE_LOCK_FINISH = EVENT_WAKE_LOCK | EVENT_FLAG_FINISH;
    729         public static final int EVENT_JOB_START = EVENT_JOB | EVENT_FLAG_START;
    730         public static final int EVENT_JOB_FINISH = EVENT_JOB | EVENT_FLAG_FINISH;
    731         public static final int EVENT_USER_RUNNING_START = EVENT_USER_RUNNING | EVENT_FLAG_START;
    732         public static final int EVENT_USER_RUNNING_FINISH = EVENT_USER_RUNNING | EVENT_FLAG_FINISH;
    733         public static final int EVENT_USER_FOREGROUND_START =
    734                 EVENT_USER_FOREGROUND | EVENT_FLAG_START;
    735         public static final int EVENT_USER_FOREGROUND_FINISH =
    736                 EVENT_USER_FOREGROUND | EVENT_FLAG_FINISH;
    737 
    738         // For CMD_EVENT.
    739         public int eventCode;
    740         public HistoryTag eventTag;
    741 
    742         // Only set for CMD_CURRENT_TIME or CMD_RESET, as per System.currentTimeMillis().
    743         public long currentTime;
    744 
    745         // Meta-data when reading.
    746         public int numReadInts;
    747 
    748         // Pre-allocated objects.
    749         public final HistoryTag localWakelockTag = new HistoryTag();
    750         public final HistoryTag localWakeReasonTag = new HistoryTag();
    751         public final HistoryTag localEventTag = new HistoryTag();
    752 
    753         public HistoryItem() {
    754         }
    755 
    756         public HistoryItem(long time, Parcel src) {
    757             this.time = time;
    758             numReadInts = 2;
    759             readFromParcel(src);
    760         }
    761 
    762         public int describeContents() {
    763             return 0;
    764         }
    765 
    766         public void writeToParcel(Parcel dest, int flags) {
    767             dest.writeLong(time);
    768             int bat = (((int)cmd)&0xff)
    769                     | ((((int)batteryLevel)<<8)&0xff00)
    770                     | ((((int)batteryStatus)<<16)&0xf0000)
    771                     | ((((int)batteryHealth)<<20)&0xf00000)
    772                     | ((((int)batteryPlugType)<<24)&0xf000000)
    773                     | (wakelockTag != null ? 0x10000000 : 0)
    774                     | (wakeReasonTag != null ? 0x20000000 : 0)
    775                     | (eventCode != EVENT_NONE ? 0x40000000 : 0);
    776             dest.writeInt(bat);
    777             bat = (((int)batteryTemperature)&0xffff)
    778                     | ((((int)batteryVoltage)<<16)&0xffff0000);
    779             dest.writeInt(bat);
    780             dest.writeInt(states);
    781             dest.writeInt(states2);
    782             if (wakelockTag != null) {
    783                 wakelockTag.writeToParcel(dest, flags);
    784             }
    785             if (wakeReasonTag != null) {
    786                 wakeReasonTag.writeToParcel(dest, flags);
    787             }
    788             if (eventCode != EVENT_NONE) {
    789                 dest.writeInt(eventCode);
    790                 eventTag.writeToParcel(dest, flags);
    791             }
    792             if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
    793                 dest.writeLong(currentTime);
    794             }
    795         }
    796 
    797         public void readFromParcel(Parcel src) {
    798             int start = src.dataPosition();
    799             int bat = src.readInt();
    800             cmd = (byte)(bat&0xff);
    801             batteryLevel = (byte)((bat>>8)&0xff);
    802             batteryStatus = (byte)((bat>>16)&0xf);
    803             batteryHealth = (byte)((bat>>20)&0xf);
    804             batteryPlugType = (byte)((bat>>24)&0xf);
    805             int bat2 = src.readInt();
    806             batteryTemperature = (short)(bat2&0xffff);
    807             batteryVoltage = (char)((bat2>>16)&0xffff);
    808             states = src.readInt();
    809             states2 = src.readInt();
    810             if ((bat&0x10000000) != 0) {
    811                 wakelockTag = localWakelockTag;
    812                 wakelockTag.readFromParcel(src);
    813             } else {
    814                 wakelockTag = null;
    815             }
    816             if ((bat&0x20000000) != 0) {
    817                 wakeReasonTag = localWakeReasonTag;
    818                 wakeReasonTag.readFromParcel(src);
    819             } else {
    820                 wakeReasonTag = null;
    821             }
    822             if ((bat&0x40000000) != 0) {
    823                 eventCode = src.readInt();
    824                 eventTag = localEventTag;
    825                 eventTag.readFromParcel(src);
    826             } else {
    827                 eventCode = EVENT_NONE;
    828                 eventTag = null;
    829             }
    830             if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
    831                 currentTime = src.readLong();
    832             } else {
    833                 currentTime = 0;
    834             }
    835             numReadInts += (src.dataPosition()-start)/4;
    836         }
    837 
    838         public void clear() {
    839             time = 0;
    840             cmd = CMD_NULL;
    841             batteryLevel = 0;
    842             batteryStatus = 0;
    843             batteryHealth = 0;
    844             batteryPlugType = 0;
    845             batteryTemperature = 0;
    846             batteryVoltage = 0;
    847             states = 0;
    848             states2 = 0;
    849             wakelockTag = null;
    850             wakeReasonTag = null;
    851             eventCode = EVENT_NONE;
    852             eventTag = null;
    853         }
    854 
    855         public void setTo(HistoryItem o) {
    856             time = o.time;
    857             cmd = o.cmd;
    858             setToCommon(o);
    859         }
    860 
    861         public void setTo(long time, byte cmd, HistoryItem o) {
    862             this.time = time;
    863             this.cmd = cmd;
    864             setToCommon(o);
    865         }
    866 
    867         private void setToCommon(HistoryItem o) {
    868             batteryLevel = o.batteryLevel;
    869             batteryStatus = o.batteryStatus;
    870             batteryHealth = o.batteryHealth;
    871             batteryPlugType = o.batteryPlugType;
    872             batteryTemperature = o.batteryTemperature;
    873             batteryVoltage = o.batteryVoltage;
    874             states = o.states;
    875             states2 = o.states2;
    876             if (o.wakelockTag != null) {
    877                 wakelockTag = localWakelockTag;
    878                 wakelockTag.setTo(o.wakelockTag);
    879             } else {
    880                 wakelockTag = null;
    881             }
    882             if (o.wakeReasonTag != null) {
    883                 wakeReasonTag = localWakeReasonTag;
    884                 wakeReasonTag.setTo(o.wakeReasonTag);
    885             } else {
    886                 wakeReasonTag = null;
    887             }
    888             eventCode = o.eventCode;
    889             if (o.eventTag != null) {
    890                 eventTag = localEventTag;
    891                 eventTag.setTo(o.eventTag);
    892             } else {
    893                 eventTag = null;
    894             }
    895             currentTime = o.currentTime;
    896         }
    897 
    898         public boolean sameNonEvent(HistoryItem o) {
    899             return batteryLevel == o.batteryLevel
    900                     && batteryStatus == o.batteryStatus
    901                     && batteryHealth == o.batteryHealth
    902                     && batteryPlugType == o.batteryPlugType
    903                     && batteryTemperature == o.batteryTemperature
    904                     && batteryVoltage == o.batteryVoltage
    905                     && states == o.states
    906                     && states2 == o.states2
    907                     && currentTime == o.currentTime;
    908         }
    909 
    910         public boolean same(HistoryItem o) {
    911             if (!sameNonEvent(o) || eventCode != o.eventCode) {
    912                 return false;
    913             }
    914             if (wakelockTag != o.wakelockTag) {
    915                 if (wakelockTag == null || o.wakelockTag == null) {
    916                     return false;
    917                 }
    918                 if (!wakelockTag.equals(o.wakelockTag)) {
    919                     return false;
    920                 }
    921             }
    922             if (wakeReasonTag != o.wakeReasonTag) {
    923                 if (wakeReasonTag == null || o.wakeReasonTag == null) {
    924                     return false;
    925                 }
    926                 if (!wakeReasonTag.equals(o.wakeReasonTag)) {
    927                     return false;
    928                 }
    929             }
    930             if (eventTag != o.eventTag) {
    931                 if (eventTag == null || o.eventTag == null) {
    932                     return false;
    933                 }
    934                 if (!eventTag.equals(o.eventTag)) {
    935                     return false;
    936                 }
    937             }
    938             return true;
    939         }
    940     }
    941 
    942     public final static class HistoryEventTracker {
    943         private final HashMap<String, SparseIntArray>[] mActiveEvents
    944                 = (HashMap<String, SparseIntArray>[]) new HashMap[HistoryItem.EVENT_COUNT];
    945 
    946         public boolean updateState(int code, String name, int uid, int poolIdx) {
    947             if ((code&HistoryItem.EVENT_FLAG_START) != 0) {
    948                 int idx = code&HistoryItem.EVENT_TYPE_MASK;
    949                 HashMap<String, SparseIntArray> active = mActiveEvents[idx];
    950                 if (active == null) {
    951                     active = new HashMap<String, SparseIntArray>();
    952                     mActiveEvents[idx] = active;
    953                 }
    954                 SparseIntArray uids = active.get(name);
    955                 if (uids == null) {
    956                     uids = new SparseIntArray();
    957                     active.put(name, uids);
    958                 }
    959                 if (uids.indexOfKey(uid) >= 0) {
    960                     // Already set, nothing to do!
    961                     return false;
    962                 }
    963                 uids.put(uid, poolIdx);
    964             } else if ((code&HistoryItem.EVENT_FLAG_FINISH) != 0) {
    965                 int idx = code&HistoryItem.EVENT_TYPE_MASK;
    966                 HashMap<String, SparseIntArray> active = mActiveEvents[idx];
    967                 if (active == null) {
    968                     // not currently active, nothing to do.
    969                     return false;
    970                 }
    971                 SparseIntArray uids = active.get(name);
    972                 if (uids == null) {
    973                     // not currently active, nothing to do.
    974                     return false;
    975                 }
    976                 idx = uids.indexOfKey(uid);
    977                 if (idx < 0) {
    978                     // not currently active, nothing to do.
    979                     return false;
    980                 }
    981                 uids.removeAt(idx);
    982                 if (uids.size() <= 0) {
    983                     active.remove(name);
    984                 }
    985             }
    986             return true;
    987         }
    988 
    989         public void removeEvents(int code) {
    990             int idx = code&HistoryItem.EVENT_TYPE_MASK;
    991             mActiveEvents[idx] = null;
    992         }
    993 
    994         public HashMap<String, SparseIntArray> getStateForEvent(int code) {
    995             return mActiveEvents[code];
    996         }
    997     }
    998 
    999     public static final class BitDescription {
   1000         public final int mask;
   1001         public final int shift;
   1002         public final String name;
   1003         public final String shortName;
   1004         public final String[] values;
   1005         public final String[] shortValues;
   1006 
   1007         public BitDescription(int mask, String name, String shortName) {
   1008             this.mask = mask;
   1009             this.shift = -1;
   1010             this.name = name;
   1011             this.shortName = shortName;
   1012             this.values = null;
   1013             this.shortValues = null;
   1014         }
   1015 
   1016         public BitDescription(int mask, int shift, String name, String shortName,
   1017                 String[] values, String[] shortValues) {
   1018             this.mask = mask;
   1019             this.shift = shift;
   1020             this.name = name;
   1021             this.shortName = shortName;
   1022             this.values = values;
   1023             this.shortValues = shortValues;
   1024         }
   1025     }
   1026 
   1027     /**
   1028      * Don't allow any more batching in to the current history event.  This
   1029      * is called when printing partial histories, so to ensure that the next
   1030      * history event will go in to a new batch after what was printed in the
   1031      * last partial history.
   1032      */
   1033     public abstract void commitCurrentHistoryBatchLocked();
   1034 
   1035     public abstract int getHistoryTotalSize();
   1036 
   1037     public abstract int getHistoryUsedSize();
   1038 
   1039     public abstract boolean startIteratingHistoryLocked();
   1040 
   1041     public abstract int getHistoryStringPoolSize();
   1042 
   1043     public abstract int getHistoryStringPoolBytes();
   1044 
   1045     public abstract String getHistoryTagPoolString(int index);
   1046 
   1047     public abstract int getHistoryTagPoolUid(int index);
   1048 
   1049     public abstract boolean getNextHistoryLocked(HistoryItem out);
   1050 
   1051     public abstract void finishIteratingHistoryLocked();
   1052 
   1053     public abstract boolean startIteratingOldHistoryLocked();
   1054 
   1055     public abstract boolean getNextOldHistoryLocked(HistoryItem out);
   1056 
   1057     public abstract void finishIteratingOldHistoryLocked();
   1058 
   1059     /**
   1060      * Return the base time offset for the battery history.
   1061      */
   1062     public abstract long getHistoryBaseTime();
   1063 
   1064     /**
   1065      * Returns the number of times the device has been started.
   1066      */
   1067     public abstract int getStartCount();
   1068 
   1069     /**
   1070      * Returns the time in microseconds that the screen has been on while the device was
   1071      * running on battery.
   1072      *
   1073      * {@hide}
   1074      */
   1075     public abstract long getScreenOnTime(long elapsedRealtimeUs, int which);
   1076 
   1077     /**
   1078      * Returns the number of times the screen was turned on.
   1079      *
   1080      * {@hide}
   1081      */
   1082     public abstract int getScreenOnCount(int which);
   1083 
   1084     public abstract long getInteractiveTime(long elapsedRealtimeUs, int which);
   1085 
   1086     public static final int SCREEN_BRIGHTNESS_DARK = 0;
   1087     public static final int SCREEN_BRIGHTNESS_DIM = 1;
   1088     public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
   1089     public static final int SCREEN_BRIGHTNESS_LIGHT = 3;
   1090     public static final int SCREEN_BRIGHTNESS_BRIGHT = 4;
   1091 
   1092     static final String[] SCREEN_BRIGHTNESS_NAMES = {
   1093         "dark", "dim", "medium", "light", "bright"
   1094     };
   1095 
   1096     static final String[] SCREEN_BRIGHTNESS_SHORT_NAMES = {
   1097         "0", "1", "2", "3", "4"
   1098     };
   1099 
   1100     public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
   1101 
   1102     /**
   1103      * Returns the time in microseconds that the screen has been on with
   1104      * the given brightness
   1105      *
   1106      * {@hide}
   1107      */
   1108     public abstract long getScreenBrightnessTime(int brightnessBin,
   1109             long elapsedRealtimeUs, int which);
   1110 
   1111     /**
   1112      * Returns the time in microseconds that low power mode has been enabled while the device was
   1113      * running on battery.
   1114      *
   1115      * {@hide}
   1116      */
   1117     public abstract long getLowPowerModeEnabledTime(long elapsedRealtimeUs, int which);
   1118 
   1119     /**
   1120      * Returns the number of times that low power mode was enabled.
   1121      *
   1122      * {@hide}
   1123      */
   1124     public abstract int getLowPowerModeEnabledCount(int which);
   1125 
   1126     /**
   1127      * Returns the number of times that connectivity state changed.
   1128      *
   1129      * {@hide}
   1130      */
   1131     public abstract int getNumConnectivityChange(int which);
   1132 
   1133     /**
   1134      * Returns the time in microseconds that the phone has been on while the device was
   1135      * running on battery.
   1136      *
   1137      * {@hide}
   1138      */
   1139     public abstract long getPhoneOnTime(long elapsedRealtimeUs, int which);
   1140 
   1141     /**
   1142      * Returns the number of times a phone call was activated.
   1143      *
   1144      * {@hide}
   1145      */
   1146     public abstract int getPhoneOnCount(int which);
   1147 
   1148     /**
   1149      * Returns the time in microseconds that the phone has been running with
   1150      * the given signal strength.
   1151      *
   1152      * {@hide}
   1153      */
   1154     public abstract long getPhoneSignalStrengthTime(int strengthBin,
   1155             long elapsedRealtimeUs, int which);
   1156 
   1157     /**
   1158      * Returns the time in microseconds that the phone has been trying to
   1159      * acquire a signal.
   1160      *
   1161      * {@hide}
   1162      */
   1163     public abstract long getPhoneSignalScanningTime(
   1164             long elapsedRealtimeUs, int which);
   1165 
   1166     /**
   1167      * Returns the number of times the phone has entered the given signal strength.
   1168      *
   1169      * {@hide}
   1170      */
   1171     public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
   1172 
   1173     /**
   1174      * Returns the time in microseconds that the mobile network has been active
   1175      * (in a high power state).
   1176      *
   1177      * {@hide}
   1178      */
   1179     public abstract long getMobileRadioActiveTime(long elapsedRealtimeUs, int which);
   1180 
   1181     /**
   1182      * Returns the number of times that the mobile network has transitioned to the
   1183      * active state.
   1184      *
   1185      * {@hide}
   1186      */
   1187     public abstract int getMobileRadioActiveCount(int which);
   1188 
   1189     /**
   1190      * Returns the time in microseconds that is the difference between the mobile radio
   1191      * time we saw based on the elapsed timestamp when going down vs. the given time stamp
   1192      * from the radio.
   1193      *
   1194      * {@hide}
   1195      */
   1196     public abstract long getMobileRadioActiveAdjustedTime(int which);
   1197 
   1198     /**
   1199      * Returns the time in microseconds that the mobile network has been active
   1200      * (in a high power state) but not being able to blame on an app.
   1201      *
   1202      * {@hide}
   1203      */
   1204     public abstract long getMobileRadioActiveUnknownTime(int which);
   1205 
   1206     /**
   1207      * Return count of number of times radio was up that could not be blamed on apps.
   1208      *
   1209      * {@hide}
   1210      */
   1211     public abstract int getMobileRadioActiveUnknownCount(int which);
   1212 
   1213     public static final int DATA_CONNECTION_NONE = 0;
   1214     public static final int DATA_CONNECTION_GPRS = 1;
   1215     public static final int DATA_CONNECTION_EDGE = 2;
   1216     public static final int DATA_CONNECTION_UMTS = 3;
   1217     public static final int DATA_CONNECTION_CDMA = 4;
   1218     public static final int DATA_CONNECTION_EVDO_0 = 5;
   1219     public static final int DATA_CONNECTION_EVDO_A = 6;
   1220     public static final int DATA_CONNECTION_1xRTT = 7;
   1221     public static final int DATA_CONNECTION_HSDPA = 8;
   1222     public static final int DATA_CONNECTION_HSUPA = 9;
   1223     public static final int DATA_CONNECTION_HSPA = 10;
   1224     public static final int DATA_CONNECTION_IDEN = 11;
   1225     public static final int DATA_CONNECTION_EVDO_B = 12;
   1226     public static final int DATA_CONNECTION_LTE = 13;
   1227     public static final int DATA_CONNECTION_EHRPD = 14;
   1228     public static final int DATA_CONNECTION_HSPAP = 15;
   1229     public static final int DATA_CONNECTION_OTHER = 16;
   1230 
   1231     static final String[] DATA_CONNECTION_NAMES = {
   1232         "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A",
   1233         "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte",
   1234         "ehrpd", "hspap", "other"
   1235     };
   1236 
   1237     public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1;
   1238 
   1239     /**
   1240      * Returns the time in microseconds that the phone has been running with
   1241      * the given data connection.
   1242      *
   1243      * {@hide}
   1244      */
   1245     public abstract long getPhoneDataConnectionTime(int dataType,
   1246             long elapsedRealtimeUs, int which);
   1247 
   1248     /**
   1249      * Returns the number of times the phone has entered the given data
   1250      * connection type.
   1251      *
   1252      * {@hide}
   1253      */
   1254     public abstract int getPhoneDataConnectionCount(int dataType, int which);
   1255 
   1256     public static final int WIFI_SUPPL_STATE_INVALID = 0;
   1257     public static final int WIFI_SUPPL_STATE_DISCONNECTED = 1;
   1258     public static final int WIFI_SUPPL_STATE_INTERFACE_DISABLED = 2;
   1259     public static final int WIFI_SUPPL_STATE_INACTIVE = 3;
   1260     public static final int WIFI_SUPPL_STATE_SCANNING = 4;
   1261     public static final int WIFI_SUPPL_STATE_AUTHENTICATING = 5;
   1262     public static final int WIFI_SUPPL_STATE_ASSOCIATING = 6;
   1263     public static final int WIFI_SUPPL_STATE_ASSOCIATED = 7;
   1264     public static final int WIFI_SUPPL_STATE_FOUR_WAY_HANDSHAKE = 8;
   1265     public static final int WIFI_SUPPL_STATE_GROUP_HANDSHAKE = 9;
   1266     public static final int WIFI_SUPPL_STATE_COMPLETED = 10;
   1267     public static final int WIFI_SUPPL_STATE_DORMANT = 11;
   1268     public static final int WIFI_SUPPL_STATE_UNINITIALIZED = 12;
   1269 
   1270     public static final int NUM_WIFI_SUPPL_STATES = WIFI_SUPPL_STATE_UNINITIALIZED+1;
   1271 
   1272     static final String[] WIFI_SUPPL_STATE_NAMES = {
   1273         "invalid", "disconn", "disabled", "inactive", "scanning",
   1274         "authenticating", "associating", "associated", "4-way-handshake",
   1275         "group-handshake", "completed", "dormant", "uninit"
   1276     };
   1277 
   1278     static final String[] WIFI_SUPPL_STATE_SHORT_NAMES = {
   1279         "inv", "dsc", "dis", "inact", "scan",
   1280         "auth", "ascing", "asced", "4-way",
   1281         "group", "compl", "dorm", "uninit"
   1282     };
   1283 
   1284     public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS
   1285             = new BitDescription[] {
   1286         new BitDescription(HistoryItem.STATE_CPU_RUNNING_FLAG, "running", "r"),
   1287         new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock", "w"),
   1288         new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor", "s"),
   1289         new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps", "g"),
   1290         new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock", "Wl"),
   1291         new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan", "Ws"),
   1292         new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast", "Wm"),
   1293         new BitDescription(HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG, "mobile_radio", "Pr"),
   1294         new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning", "Psc"),
   1295         new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio", "a"),
   1296         new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen", "S"),
   1297         new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged", "BP"),
   1298         new BitDescription(HistoryItem.STATE_PHONE_IN_CALL_FLAG, "phone_in_call", "Pcl"),
   1299         new BitDescription(HistoryItem.STATE_BLUETOOTH_ON_FLAG, "bluetooth", "b"),
   1300         new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK,
   1301                 HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", "Pcn",
   1302                 DATA_CONNECTION_NAMES, DATA_CONNECTION_NAMES),
   1303         new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK,
   1304                 HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state", "Pst",
   1305                 new String[] {"in", "out", "emergency", "off"},
   1306                 new String[] {"in", "out", "em", "off"}),
   1307         new BitDescription(HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK,
   1308                 HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT, "phone_signal_strength", "Pss",
   1309                 SignalStrength.SIGNAL_STRENGTH_NAMES,
   1310                 new String[] { "0", "1", "2", "3", "4" }),
   1311         new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK,
   1312                 HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness", "Sb",
   1313                 SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES),
   1314     };
   1315 
   1316     public static final BitDescription[] HISTORY_STATE2_DESCRIPTIONS
   1317             = new BitDescription[] {
   1318         new BitDescription(HistoryItem.STATE2_LOW_POWER_FLAG, "low_power", "lp"),
   1319         new BitDescription(HistoryItem.STATE2_VIDEO_ON_FLAG, "video", "v"),
   1320         new BitDescription(HistoryItem.STATE2_WIFI_RUNNING_FLAG, "wifi_running", "Wr"),
   1321         new BitDescription(HistoryItem.STATE2_WIFI_ON_FLAG, "wifi", "W"),
   1322         new BitDescription(HistoryItem.STATE2_FLASHLIGHT_FLAG, "flashlight", "fl"),
   1323         new BitDescription(HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK,
   1324                 HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT, "wifi_signal_strength", "Wss",
   1325                 new String[] { "0", "1", "2", "3", "4" },
   1326                 new String[] { "0", "1", "2", "3", "4" }),
   1327         new BitDescription(HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK,
   1328                 HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT, "wifi_suppl", "Wsp",
   1329                 WIFI_SUPPL_STATE_NAMES, WIFI_SUPPL_STATE_SHORT_NAMES),
   1330     };
   1331 
   1332     public static final String[] HISTORY_EVENT_NAMES = new String[] {
   1333             "null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg", "conn"
   1334     };
   1335 
   1336     public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
   1337             "Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf", "Ecn"
   1338     };
   1339 
   1340     /**
   1341      * Returns the time in microseconds that wifi has been on while the device was
   1342      * running on battery.
   1343      *
   1344      * {@hide}
   1345      */
   1346     public abstract long getWifiOnTime(long elapsedRealtimeUs, int which);
   1347 
   1348     /**
   1349      * Returns the time in microseconds that wifi has been on and the driver has
   1350      * been in the running state while the device was running on battery.
   1351      *
   1352      * {@hide}
   1353      */
   1354     public abstract long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which);
   1355 
   1356     public static final int WIFI_STATE_OFF = 0;
   1357     public static final int WIFI_STATE_OFF_SCANNING = 1;
   1358     public static final int WIFI_STATE_ON_NO_NETWORKS = 2;
   1359     public static final int WIFI_STATE_ON_DISCONNECTED = 3;
   1360     public static final int WIFI_STATE_ON_CONNECTED_STA = 4;
   1361     public static final int WIFI_STATE_ON_CONNECTED_P2P = 5;
   1362     public static final int WIFI_STATE_ON_CONNECTED_STA_P2P = 6;
   1363     public static final int WIFI_STATE_SOFT_AP = 7;
   1364 
   1365     static final String[] WIFI_STATE_NAMES = {
   1366         "off", "scanning", "no_net", "disconn",
   1367         "sta", "p2p", "sta_p2p", "soft_ap"
   1368     };
   1369 
   1370     public static final int NUM_WIFI_STATES = WIFI_STATE_SOFT_AP+1;
   1371 
   1372     /**
   1373      * Returns the time in microseconds that WiFi has been running in the given state.
   1374      *
   1375      * {@hide}
   1376      */
   1377     public abstract long getWifiStateTime(int wifiState,
   1378             long elapsedRealtimeUs, int which);
   1379 
   1380     /**
   1381      * Returns the number of times that WiFi has entered the given state.
   1382      *
   1383      * {@hide}
   1384      */
   1385     public abstract int getWifiStateCount(int wifiState, int which);
   1386 
   1387     /**
   1388      * Returns the time in microseconds that the wifi supplicant has been
   1389      * in a given state.
   1390      *
   1391      * {@hide}
   1392      */
   1393     public abstract long getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which);
   1394 
   1395     /**
   1396      * Returns the number of times that the wifi supplicant has transitioned
   1397      * to a given state.
   1398      *
   1399      * {@hide}
   1400      */
   1401     public abstract int getWifiSupplStateCount(int state, int which);
   1402 
   1403     public static final int NUM_WIFI_SIGNAL_STRENGTH_BINS = 5;
   1404 
   1405     /**
   1406      * Returns the time in microseconds that WIFI has been running with
   1407      * the given signal strength.
   1408      *
   1409      * {@hide}
   1410      */
   1411     public abstract long getWifiSignalStrengthTime(int strengthBin,
   1412             long elapsedRealtimeUs, int which);
   1413 
   1414     /**
   1415      * Returns the number of times WIFI has entered the given signal strength.
   1416      *
   1417      * {@hide}
   1418      */
   1419     public abstract int getWifiSignalStrengthCount(int strengthBin, int which);
   1420 
   1421     /**
   1422      * Returns the time in microseconds that bluetooth has been on while the device was
   1423      * running on battery.
   1424      *
   1425      * {@hide}
   1426      */
   1427     public abstract long getBluetoothOnTime(long elapsedRealtimeUs, int which);
   1428 
   1429     public abstract int getBluetoothPingCount();
   1430 
   1431     public static final int BLUETOOTH_STATE_INACTIVE = 0;
   1432     public static final int BLUETOOTH_STATE_LOW = 1;
   1433     public static final int BLUETOOTH_STATE_MEDIUM = 2;
   1434     public static final int BLUETOOTH_STATE_HIGH = 3;
   1435 
   1436     static final String[] BLUETOOTH_STATE_NAMES = {
   1437         "inactive", "low", "med", "high"
   1438     };
   1439 
   1440     public static final int NUM_BLUETOOTH_STATES = BLUETOOTH_STATE_HIGH +1;
   1441 
   1442     /**
   1443      * Returns the time in microseconds that Bluetooth has been running in the
   1444      * given active state.
   1445      *
   1446      * {@hide}
   1447      */
   1448     public abstract long getBluetoothStateTime(int bluetoothState,
   1449             long elapsedRealtimeUs, int which);
   1450 
   1451     /**
   1452      * Returns the number of times that Bluetooth has entered the given active state.
   1453      *
   1454      * {@hide}
   1455      */
   1456     public abstract int getBluetoothStateCount(int bluetoothState, int which);
   1457 
   1458     /**
   1459      * Returns the time in microseconds that the flashlight has been on while the device was
   1460      * running on battery.
   1461      *
   1462      * {@hide}
   1463      */
   1464     public abstract long getFlashlightOnTime(long elapsedRealtimeUs, int which);
   1465 
   1466     /**
   1467      * Returns the number of times that the flashlight has been turned on while the device was
   1468      * running on battery.
   1469      *
   1470      * {@hide}
   1471      */
   1472     public abstract long getFlashlightOnCount(int which);
   1473 
   1474     public static final int NETWORK_MOBILE_RX_DATA = 0;
   1475     public static final int NETWORK_MOBILE_TX_DATA = 1;
   1476     public static final int NETWORK_WIFI_RX_DATA = 2;
   1477     public static final int NETWORK_WIFI_TX_DATA = 3;
   1478 
   1479     public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_TX_DATA + 1;
   1480 
   1481     public abstract long getNetworkActivityBytes(int type, int which);
   1482     public abstract long getNetworkActivityPackets(int type, int which);
   1483 
   1484     /**
   1485      * Return the wall clock time when battery stats data collection started.
   1486      */
   1487     public abstract long getStartClockTime();
   1488 
   1489     /**
   1490      * Return platform version tag that we were running in when the battery stats started.
   1491      */
   1492     public abstract String getStartPlatformVersion();
   1493 
   1494     /**
   1495      * Return platform version tag that we were running in when the battery stats ended.
   1496      */
   1497     public abstract String getEndPlatformVersion();
   1498 
   1499     /**
   1500      * Return the internal version code of the parcelled format.
   1501      */
   1502     public abstract int getParcelVersion();
   1503 
   1504     /**
   1505      * Return whether we are currently running on battery.
   1506      */
   1507     public abstract boolean getIsOnBattery();
   1508 
   1509     /**
   1510      * Returns a SparseArray containing the statistics for each uid.
   1511      */
   1512     public abstract SparseArray<? extends Uid> getUidStats();
   1513 
   1514     /**
   1515      * Returns the current battery uptime in microseconds.
   1516      *
   1517      * @param curTime the amount of elapsed realtime in microseconds.
   1518      */
   1519     public abstract long getBatteryUptime(long curTime);
   1520 
   1521     /**
   1522      * Returns the current battery realtime in microseconds.
   1523      *
   1524      * @param curTime the amount of elapsed realtime in microseconds.
   1525      */
   1526     public abstract long getBatteryRealtime(long curTime);
   1527 
   1528     /**
   1529      * Returns the battery percentage level at the last time the device was unplugged from power, or
   1530      * the last time it booted on battery power.
   1531      */
   1532     public abstract int getDischargeStartLevel();
   1533 
   1534     /**
   1535      * Returns the current battery percentage level if we are in a discharge cycle, otherwise
   1536      * returns the level at the last plug event.
   1537      */
   1538     public abstract int getDischargeCurrentLevel();
   1539 
   1540     /**
   1541      * Get the amount the battery has discharged since the stats were
   1542      * last reset after charging, as a lower-end approximation.
   1543      */
   1544     public abstract int getLowDischargeAmountSinceCharge();
   1545 
   1546     /**
   1547      * Get the amount the battery has discharged since the stats were
   1548      * last reset after charging, as an upper-end approximation.
   1549      */
   1550     public abstract int getHighDischargeAmountSinceCharge();
   1551 
   1552     /**
   1553      * Retrieve the discharge amount over the selected discharge period <var>which</var>.
   1554      */
   1555     public abstract int getDischargeAmount(int which);
   1556 
   1557     /**
   1558      * Get the amount the battery has discharged while the screen was on,
   1559      * since the last time power was unplugged.
   1560      */
   1561     public abstract int getDischargeAmountScreenOn();
   1562 
   1563     /**
   1564      * Get the amount the battery has discharged while the screen was on,
   1565      * since the last time the device was charged.
   1566      */
   1567     public abstract int getDischargeAmountScreenOnSinceCharge();
   1568 
   1569     /**
   1570      * Get the amount the battery has discharged while the screen was off,
   1571      * since the last time power was unplugged.
   1572      */
   1573     public abstract int getDischargeAmountScreenOff();
   1574 
   1575     /**
   1576      * Get the amount the battery has discharged while the screen was off,
   1577      * since the last time the device was charged.
   1578      */
   1579     public abstract int getDischargeAmountScreenOffSinceCharge();
   1580 
   1581     /**
   1582      * Returns the total, last, or current battery uptime in microseconds.
   1583      *
   1584      * @param curTime the elapsed realtime in microseconds.
   1585      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
   1586      */
   1587     public abstract long computeBatteryUptime(long curTime, int which);
   1588 
   1589     /**
   1590      * Returns the total, last, or current battery realtime in microseconds.
   1591      *
   1592      * @param curTime the current elapsed realtime in microseconds.
   1593      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
   1594      */
   1595     public abstract long computeBatteryRealtime(long curTime, int which);
   1596 
   1597     /**
   1598      * Returns the total, last, or current battery screen off uptime in microseconds.
   1599      *
   1600      * @param curTime the elapsed realtime in microseconds.
   1601      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
   1602      */
   1603     public abstract long computeBatteryScreenOffUptime(long curTime, int which);
   1604 
   1605     /**
   1606      * Returns the total, last, or current battery screen off realtime in microseconds.
   1607      *
   1608      * @param curTime the current elapsed realtime in microseconds.
   1609      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
   1610      */
   1611     public abstract long computeBatteryScreenOffRealtime(long curTime, int which);
   1612 
   1613     /**
   1614      * Returns the total, last, or current uptime in microseconds.
   1615      *
   1616      * @param curTime the current elapsed realtime in microseconds.
   1617      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
   1618      */
   1619     public abstract long computeUptime(long curTime, int which);
   1620 
   1621     /**
   1622      * Returns the total, last, or current realtime in microseconds.
   1623      *
   1624      * @param curTime the current elapsed realtime in microseconds.
   1625      * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
   1626      */
   1627     public abstract long computeRealtime(long curTime, int which);
   1628 
   1629     /**
   1630      * Compute an approximation for how much run time (in microseconds) is remaining on
   1631      * the battery.  Returns -1 if no time can be computed: either there is not
   1632      * enough current data to make a decision, or the battery is currently
   1633      * charging.
   1634      *
   1635      * @param curTime The current elepsed realtime in microseconds.
   1636      */
   1637     public abstract long computeBatteryTimeRemaining(long curTime);
   1638 
   1639     // The part of a step duration that is the actual time.
   1640     public static final long STEP_LEVEL_TIME_MASK = 0x000000ffffffffffL;
   1641 
   1642     // Bits in a step duration that are the new battery level we are at.
   1643     public static final long STEP_LEVEL_LEVEL_MASK = 0x0000ff0000000000L;
   1644     public static final long STEP_LEVEL_LEVEL_SHIFT = 40;
   1645 
   1646     // Bits in a step duration that are the initial mode we were in at that step.
   1647     public static final long STEP_LEVEL_INITIAL_MODE_MASK = 0x00ff000000000000L;
   1648     public static final long STEP_LEVEL_INITIAL_MODE_SHIFT = 48;
   1649 
   1650     // Bits in a step duration that indicate which modes changed during that step.
   1651     public static final long STEP_LEVEL_MODIFIED_MODE_MASK = 0xff00000000000000L;
   1652     public static final long STEP_LEVEL_MODIFIED_MODE_SHIFT = 56;
   1653 
   1654     // Step duration mode: the screen is on, off, dozed, etc; value is Display.STATE_* - 1.
   1655     public static final int STEP_LEVEL_MODE_SCREEN_STATE = 0x03;
   1656 
   1657     // Step duration mode: power save is on.
   1658     public static final int STEP_LEVEL_MODE_POWER_SAVE = 0x04;
   1659 
   1660     /**
   1661      * Return the historical number of discharge steps we currently have.
   1662      */
   1663     public abstract int getNumDischargeStepDurations();
   1664 
   1665     /**
   1666      * Return the array of discharge step durations; the number of valid
   1667      * items in it is returned by {@link #getNumDischargeStepDurations()}.
   1668      * These values are in milliseconds.
   1669      */
   1670     public abstract long[] getDischargeStepDurationsArray();
   1671 
   1672     /**
   1673      * Compute an approximation for how much time (in microseconds) remains until the battery
   1674      * is fully charged.  Returns -1 if no time can be computed: either there is not
   1675      * enough current data to make a decision, or the battery is currently
   1676      * discharging.
   1677      *
   1678      * @param curTime The current elepsed realtime in microseconds.
   1679      */
   1680     public abstract long computeChargeTimeRemaining(long curTime);
   1681 
   1682     /**
   1683      * Return the historical number of charge steps we currently have.
   1684      */
   1685     public abstract int getNumChargeStepDurations();
   1686 
   1687     /**
   1688      * Return the array of charge step durations; the number of valid
   1689      * items in it is returned by {@link #getNumChargeStepDurations()}.
   1690      * These values are in milliseconds.
   1691      */
   1692     public abstract long[] getChargeStepDurationsArray();
   1693 
   1694     public abstract Map<String, ? extends Timer> getWakeupReasonStats();
   1695 
   1696     public abstract Map<String, ? extends Timer> getKernelWakelockStats();
   1697 
   1698     /** Returns the number of different speeds that the CPU can run at */
   1699     public abstract int getCpuSpeedSteps();
   1700 
   1701     public abstract void writeToParcelWithoutUids(Parcel out, int flags);
   1702 
   1703     private final static void formatTimeRaw(StringBuilder out, long seconds) {
   1704         long days = seconds / (60 * 60 * 24);
   1705         if (days != 0) {
   1706             out.append(days);
   1707             out.append("d ");
   1708         }
   1709         long used = days * 60 * 60 * 24;
   1710 
   1711         long hours = (seconds - used) / (60 * 60);
   1712         if (hours != 0 || used != 0) {
   1713             out.append(hours);
   1714             out.append("h ");
   1715         }
   1716         used += hours * 60 * 60;
   1717 
   1718         long mins = (seconds-used) / 60;
   1719         if (mins != 0 || used != 0) {
   1720             out.append(mins);
   1721             out.append("m ");
   1722         }
   1723         used += mins * 60;
   1724 
   1725         if (seconds != 0 || used != 0) {
   1726             out.append(seconds-used);
   1727             out.append("s ");
   1728         }
   1729     }
   1730 
   1731     public final static void formatTime(StringBuilder sb, long time) {
   1732         long sec = time / 100;
   1733         formatTimeRaw(sb, sec);
   1734         sb.append((time - (sec * 100)) * 10);
   1735         sb.append("ms ");
   1736     }
   1737 
   1738     public final static void formatTimeMs(StringBuilder sb, long time) {
   1739         long sec = time / 1000;
   1740         formatTimeRaw(sb, sec);
   1741         sb.append(time - (sec * 1000));
   1742         sb.append("ms ");
   1743     }
   1744 
   1745     public final static void formatTimeMsNoSpace(StringBuilder sb, long time) {
   1746         long sec = time / 1000;
   1747         formatTimeRaw(sb, sec);
   1748         sb.append(time - (sec * 1000));
   1749         sb.append("ms");
   1750     }
   1751 
   1752     public final String formatRatioLocked(long num, long den) {
   1753         if (den == 0L) {
   1754             return "--%";
   1755         }
   1756         float perc = ((float)num) / ((float)den) * 100;
   1757         mFormatBuilder.setLength(0);
   1758         mFormatter.format("%.1f%%", perc);
   1759         return mFormatBuilder.toString();
   1760     }
   1761 
   1762     final String formatBytesLocked(long bytes) {
   1763         mFormatBuilder.setLength(0);
   1764 
   1765         if (bytes < BYTES_PER_KB) {
   1766             return bytes + "B";
   1767         } else if (bytes < BYTES_PER_MB) {
   1768             mFormatter.format("%.2fKB", bytes / (double) BYTES_PER_KB);
   1769             return mFormatBuilder.toString();
   1770         } else if (bytes < BYTES_PER_GB){
   1771             mFormatter.format("%.2fMB", bytes / (double) BYTES_PER_MB);
   1772             return mFormatBuilder.toString();
   1773         } else {
   1774             mFormatter.format("%.2fGB", bytes / (double) BYTES_PER_GB);
   1775             return mFormatBuilder.toString();
   1776         }
   1777     }
   1778 
   1779     private static long computeWakeLock(Timer timer, long elapsedRealtimeUs, int which) {
   1780         if (timer != null) {
   1781             // Convert from microseconds to milliseconds with rounding
   1782             long totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
   1783             long totalTimeMillis = (totalTimeMicros + 500) / 1000;
   1784             return totalTimeMillis;
   1785         }
   1786         return 0;
   1787     }
   1788 
   1789     /**
   1790      *
   1791      * @param sb a StringBuilder object.
   1792      * @param timer a Timer object contining the wakelock times.
   1793      * @param elapsedRealtimeUs the current on-battery time in microseconds.
   1794      * @param name the name of the wakelock.
   1795      * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
   1796      * @param linePrefix a String to be prepended to each line of output.
   1797      * @return the line prefix
   1798      */
   1799     private static final String printWakeLock(StringBuilder sb, Timer timer,
   1800             long elapsedRealtimeUs, String name, int which, String linePrefix) {
   1801 
   1802         if (timer != null) {
   1803             long totalTimeMillis = computeWakeLock(timer, elapsedRealtimeUs, which);
   1804 
   1805             int count = timer.getCountLocked(which);
   1806             if (totalTimeMillis != 0) {
   1807                 sb.append(linePrefix);
   1808                 formatTimeMs(sb, totalTimeMillis);
   1809                 if (name != null) {
   1810                     sb.append(name);
   1811                     sb.append(' ');
   1812                 }
   1813                 sb.append('(');
   1814                 sb.append(count);
   1815                 sb.append(" times)");
   1816                 return ", ";
   1817             }
   1818         }
   1819         return linePrefix;
   1820     }
   1821 
   1822     /**
   1823      * Checkin version of wakelock printer. Prints simple comma-separated list.
   1824      *
   1825      * @param sb a StringBuilder object.
   1826      * @param timer a Timer object contining the wakelock times.
   1827      * @param elapsedRealtimeUs the current time in microseconds.
   1828      * @param name the name of the wakelock.
   1829      * @param which which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
   1830      * @param linePrefix a String to be prepended to each line of output.
   1831      * @return the line prefix
   1832      */
   1833     private static final String printWakeLockCheckin(StringBuilder sb, Timer timer,
   1834             long elapsedRealtimeUs, String name, int which, String linePrefix) {
   1835         long totalTimeMicros = 0;
   1836         int count = 0;
   1837         if (timer != null) {
   1838             totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
   1839             count = timer.getCountLocked(which);
   1840         }
   1841         sb.append(linePrefix);
   1842         sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
   1843         sb.append(',');
   1844         sb.append(name != null ? name + "," : "");
   1845         sb.append(count);
   1846         return ",";
   1847     }
   1848 
   1849     /**
   1850      * Dump a comma-separated line of values for terse checkin mode.
   1851      *
   1852      * @param pw the PageWriter to dump log to
   1853      * @param category category of data (e.g. "total", "last", "unplugged", "current" )
   1854      * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
   1855      * @param args type-dependent data arguments
   1856      */
   1857     private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
   1858            Object... args ) {
   1859         pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
   1860         pw.print(uid); pw.print(',');
   1861         pw.print(category); pw.print(',');
   1862         pw.print(type);
   1863 
   1864         for (Object arg : args) {
   1865             pw.print(',');
   1866             pw.print(arg);
   1867         }
   1868         pw.println();
   1869     }
   1870 
   1871     /**
   1872      * Temporary for settings.
   1873      */
   1874     public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid) {
   1875         dumpCheckinLocked(context, pw, which, reqUid, BatteryStatsHelper.checkWifiOnly(context));
   1876     }
   1877 
   1878     /**
   1879      * Checkin server version of dump to produce more compact, computer-readable log.
   1880      *
   1881      * NOTE: all times are expressed in 'ms'.
   1882      */
   1883     public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid,
   1884             boolean wifiOnly) {
   1885         final long rawUptime = SystemClock.uptimeMillis() * 1000;
   1886         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
   1887         final long batteryUptime = getBatteryUptime(rawUptime);
   1888         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
   1889         final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
   1890         final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
   1891         final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime,
   1892                 which);
   1893         final long totalRealtime = computeRealtime(rawRealtime, which);
   1894         final long totalUptime = computeUptime(rawUptime, which);
   1895         final long screenOnTime = getScreenOnTime(rawRealtime, which);
   1896         final long interactiveTime = getInteractiveTime(rawRealtime, which);
   1897         final long lowPowerModeEnabledTime = getLowPowerModeEnabledTime(rawRealtime, which);
   1898         final int connChanges = getNumConnectivityChange(which);
   1899         final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
   1900         final long wifiOnTime = getWifiOnTime(rawRealtime, which);
   1901         final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
   1902         final long bluetoothOnTime = getBluetoothOnTime(rawRealtime, which);
   1903 
   1904         StringBuilder sb = new StringBuilder(128);
   1905 
   1906         SparseArray<? extends Uid> uidStats = getUidStats();
   1907         final int NU = uidStats.size();
   1908 
   1909         String category = STAT_NAMES[which];
   1910 
   1911         // Dump "battery" stat
   1912         dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
   1913                 which == STATS_SINCE_CHARGED ? getStartCount() : "N/A",
   1914                 whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
   1915                 totalRealtime / 1000, totalUptime / 1000,
   1916                 getStartClockTime(),
   1917                 whichBatteryScreenOffRealtime / 1000, whichBatteryScreenOffUptime / 1000);
   1918 
   1919         // Calculate wakelock times across all uids.
   1920         long fullWakeLockTimeTotal = 0;
   1921         long partialWakeLockTimeTotal = 0;
   1922 
   1923         for (int iu = 0; iu < NU; iu++) {
   1924             Uid u = uidStats.valueAt(iu);
   1925 
   1926             Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
   1927             if (wakelocks.size() > 0) {
   1928                 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
   1929                         : wakelocks.entrySet()) {
   1930                     Uid.Wakelock wl = ent.getValue();
   1931 
   1932                     Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
   1933                     if (fullWakeTimer != null) {
   1934                         fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(rawRealtime,
   1935                                 which);
   1936                     }
   1937 
   1938                     Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
   1939                     if (partialWakeTimer != null) {
   1940                         partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
   1941                             rawRealtime, which);
   1942                     }
   1943                 }
   1944             }
   1945         }
   1946 
   1947         long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
   1948         long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
   1949         long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
   1950         long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
   1951         long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
   1952         long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
   1953         long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
   1954         long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
   1955 
   1956         // Dump network stats
   1957         dumpLine(pw, 0 /* uid */, category, GLOBAL_NETWORK_DATA,
   1958                 mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes,
   1959                 mobileRxTotalPackets, mobileTxTotalPackets, wifiRxTotalPackets, wifiTxTotalPackets);
   1960 
   1961         // Dump misc stats
   1962         dumpLine(pw, 0 /* uid */, category, MISC_DATA,
   1963                 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
   1964                 wifiRunningTime / 1000, bluetoothOnTime / 1000,
   1965                 mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes,
   1966                 fullWakeLockTimeTotal / 1000, partialWakeLockTimeTotal / 1000,
   1967                 0 /*legacy input event count*/, getMobileRadioActiveTime(rawRealtime, which) / 1000,
   1968                 getMobileRadioActiveAdjustedTime(which) / 1000, interactiveTime / 1000,
   1969                 lowPowerModeEnabledTime / 1000, connChanges);
   1970 
   1971         // Dump screen brightness stats
   1972         Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
   1973         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
   1974             args[i] = getScreenBrightnessTime(i, rawRealtime, which) / 1000;
   1975         }
   1976         dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
   1977 
   1978         // Dump signal strength stats
   1979         args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
   1980         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
   1981             args[i] = getPhoneSignalStrengthTime(i, rawRealtime, which) / 1000;
   1982         }
   1983         dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
   1984         dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA,
   1985                 getPhoneSignalScanningTime(rawRealtime, which) / 1000);
   1986         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
   1987             args[i] = getPhoneSignalStrengthCount(i, which);
   1988         }
   1989         dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
   1990 
   1991         // Dump network type stats
   1992         args = new Object[NUM_DATA_CONNECTION_TYPES];
   1993         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
   1994             args[i] = getPhoneDataConnectionTime(i, rawRealtime, which) / 1000;
   1995         }
   1996         dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args);
   1997         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
   1998             args[i] = getPhoneDataConnectionCount(i, which);
   1999         }
   2000         dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
   2001 
   2002         // Dump wifi state stats
   2003         args = new Object[NUM_WIFI_STATES];
   2004         for (int i=0; i<NUM_WIFI_STATES; i++) {
   2005             args[i] = getWifiStateTime(i, rawRealtime, which) / 1000;
   2006         }
   2007         dumpLine(pw, 0 /* uid */, category, WIFI_STATE_TIME_DATA, args);
   2008         for (int i=0; i<NUM_WIFI_STATES; i++) {
   2009             args[i] = getWifiStateCount(i, which);
   2010         }
   2011         dumpLine(pw, 0 /* uid */, category, WIFI_STATE_COUNT_DATA, args);
   2012 
   2013         // Dump wifi suppl state stats
   2014         args = new Object[NUM_WIFI_SUPPL_STATES];
   2015         for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
   2016             args[i] = getWifiSupplStateTime(i, rawRealtime, which) / 1000;
   2017         }
   2018         dumpLine(pw, 0 /* uid */, category, WIFI_SUPPL_STATE_TIME_DATA, args);
   2019         for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
   2020             args[i] = getWifiSupplStateCount(i, which);
   2021         }
   2022         dumpLine(pw, 0 /* uid */, category, WIFI_SUPPL_STATE_COUNT_DATA, args);
   2023 
   2024         // Dump wifi signal strength stats
   2025         args = new Object[NUM_WIFI_SIGNAL_STRENGTH_BINS];
   2026         for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
   2027             args[i] = getWifiSignalStrengthTime(i, rawRealtime, which) / 1000;
   2028         }
   2029         dumpLine(pw, 0 /* uid */, category, WIFI_SIGNAL_STRENGTH_TIME_DATA, args);
   2030         for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
   2031             args[i] = getWifiSignalStrengthCount(i, which);
   2032         }
   2033         dumpLine(pw, 0 /* uid */, category, WIFI_SIGNAL_STRENGTH_COUNT_DATA, args);
   2034 
   2035         // Dump bluetooth state stats
   2036         args = new Object[NUM_BLUETOOTH_STATES];
   2037         for (int i=0; i<NUM_BLUETOOTH_STATES; i++) {
   2038             args[i] = getBluetoothStateTime(i, rawRealtime, which) / 1000;
   2039         }
   2040         dumpLine(pw, 0 /* uid */, category, BLUETOOTH_STATE_TIME_DATA, args);
   2041         for (int i=0; i<NUM_BLUETOOTH_STATES; i++) {
   2042             args[i] = getBluetoothStateCount(i, which);
   2043         }
   2044         dumpLine(pw, 0 /* uid */, category, BLUETOOTH_STATE_COUNT_DATA, args);
   2045 
   2046         if (which == STATS_SINCE_UNPLUGGED) {
   2047             dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
   2048                     getDischargeCurrentLevel());
   2049         }
   2050 
   2051         if (which == STATS_SINCE_UNPLUGGED) {
   2052             dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
   2053                     getDischargeStartLevel()-getDischargeCurrentLevel(),
   2054                     getDischargeStartLevel()-getDischargeCurrentLevel(),
   2055                     getDischargeAmountScreenOn(), getDischargeAmountScreenOff());
   2056         } else {
   2057             dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
   2058                     getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(),
   2059                     getDischargeAmountScreenOnSinceCharge(),
   2060                     getDischargeAmountScreenOffSinceCharge());
   2061         }
   2062 
   2063         if (reqUid < 0) {
   2064             Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
   2065             if (kernelWakelocks.size() > 0) {
   2066                 for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) {
   2067                     sb.setLength(0);
   2068                     printWakeLockCheckin(sb, ent.getValue(), rawRealtime, null, which, "");
   2069                     dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
   2070                             sb.toString());
   2071                 }
   2072             }
   2073             Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
   2074             if (wakeupReasons.size() > 0) {
   2075                 for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
   2076                     // Not doing the regular wake lock formatting to remain compatible
   2077                     // with the old checkin format.
   2078                     long totalTimeMicros = ent.getValue().getTotalTimeLocked(rawRealtime, which);
   2079                     int count = ent.getValue().getCountLocked(which);
   2080                     dumpLine(pw, 0 /* uid */, category, WAKEUP_REASON_DATA,
   2081                             "\"" + ent.getKey() + "\"", (totalTimeMicros + 500) / 1000, count);
   2082                 }
   2083             }
   2084         }
   2085 
   2086         BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
   2087         helper.create(this);
   2088         helper.refreshStats(which, UserHandle.USER_ALL);
   2089         List<BatterySipper> sippers = helper.getUsageList();
   2090         if (sippers != null && sippers.size() > 0) {
   2091             dumpLine(pw, 0 /* uid */, category, POWER_USE_SUMMARY_DATA,
   2092                     BatteryStatsHelper.makemAh(helper.getPowerProfile().getBatteryCapacity()),
   2093                     BatteryStatsHelper.makemAh(helper.getComputedPower()),
   2094                     BatteryStatsHelper.makemAh(helper.getMinDrainedPower()),
   2095                     BatteryStatsHelper.makemAh(helper.getMaxDrainedPower()));
   2096             for (int i=0; i<sippers.size(); i++) {
   2097                 BatterySipper bs = sippers.get(i);
   2098                 int uid = 0;
   2099                 String label;
   2100                 switch (bs.drainType) {
   2101                     case IDLE:
   2102                         label="idle";
   2103                         break;
   2104                     case CELL:
   2105                         label="cell";
   2106                         break;
   2107                     case PHONE:
   2108                         label="phone";
   2109                         break;
   2110                     case WIFI:
   2111                         label="wifi";
   2112                         break;
   2113                     case BLUETOOTH:
   2114                         label="blue";
   2115                         break;
   2116                     case SCREEN:
   2117                         label="scrn";
   2118                         break;
   2119                     case FLASHLIGHT:
   2120                         label="flashlight";
   2121                         break;
   2122                     case APP:
   2123                         uid = bs.uidObj.getUid();
   2124                         label = "uid";
   2125                         break;
   2126                     case USER:
   2127                         uid = UserHandle.getUid(bs.userId, 0);
   2128                         label = "user";
   2129                         break;
   2130                     case UNACCOUNTED:
   2131                         label = "unacc";
   2132                         break;
   2133                     case OVERCOUNTED:
   2134                         label = "over";
   2135                         break;
   2136                     default:
   2137                         label = "???";
   2138                 }
   2139                 dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label,
   2140                         BatteryStatsHelper.makemAh(bs.value));
   2141             }
   2142         }
   2143 
   2144         for (int iu = 0; iu < NU; iu++) {
   2145             final int uid = uidStats.keyAt(iu);
   2146             if (reqUid >= 0 && uid != reqUid) {
   2147                 continue;
   2148             }
   2149             Uid u = uidStats.valueAt(iu);
   2150             // Dump Network stats per uid, if any
   2151             long mobileBytesRx = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
   2152             long mobileBytesTx = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
   2153             long wifiBytesRx = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
   2154             long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
   2155             long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
   2156             long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
   2157             long mobileActiveTime = u.getMobileRadioActiveTime(which);
   2158             int mobileActiveCount = u.getMobileRadioActiveCount(which);
   2159             long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
   2160             long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
   2161             long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
   2162             long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
   2163             long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
   2164 
   2165             if (mobileBytesRx > 0 || mobileBytesTx > 0 || wifiBytesRx > 0 || wifiBytesTx > 0
   2166                     || mobilePacketsRx > 0 || mobilePacketsTx > 0 || wifiPacketsRx > 0
   2167                     || wifiPacketsTx > 0 || mobileActiveTime > 0 || mobileActiveCount > 0) {
   2168                 dumpLine(pw, uid, category, NETWORK_DATA, mobileBytesRx, mobileBytesTx,
   2169                         wifiBytesRx, wifiBytesTx,
   2170                         mobilePacketsRx, mobilePacketsTx,
   2171                         wifiPacketsRx, wifiPacketsTx,
   2172                         mobileActiveTime, mobileActiveCount);
   2173             }
   2174 
   2175             if (fullWifiLockOnTime != 0 || wifiScanTime != 0
   2176                     || uidWifiRunningTime != 0) {
   2177                 dumpLine(pw, uid, category, WIFI_DATA,
   2178                         fullWifiLockOnTime, wifiScanTime, uidWifiRunningTime);
   2179             }
   2180 
   2181             if (u.hasUserActivity()) {
   2182                 args = new Object[Uid.NUM_USER_ACTIVITY_TYPES];
   2183                 boolean hasData = false;
   2184                 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
   2185                     int val = u.getUserActivityCount(i, which);
   2186                     args[i] = val;
   2187                     if (val != 0) hasData = true;
   2188                 }
   2189                 if (hasData) {
   2190                     dumpLine(pw, uid /* uid */, category, USER_ACTIVITY_DATA, args);
   2191                 }
   2192             }
   2193 
   2194             Map<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
   2195             if (wakelocks.size() > 0) {
   2196                 for (Map.Entry<String, ? extends Uid.Wakelock> ent : wakelocks.entrySet()) {
   2197                     Uid.Wakelock wl = ent.getValue();
   2198                     String linePrefix = "";
   2199                     sb.setLength(0);
   2200                     linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
   2201                             rawRealtime, "f", which, linePrefix);
   2202                     linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL),
   2203                             rawRealtime, "p", which, linePrefix);
   2204                     linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
   2205                             rawRealtime, "w", which, linePrefix);
   2206 
   2207                     // Only log if we had at lease one wakelock...
   2208                     if (sb.length() > 0) {
   2209                         String name = ent.getKey();
   2210                         if (name.indexOf(',') >= 0) {
   2211                             name = name.replace(',', '_');
   2212                         }
   2213                         dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString());
   2214                     }
   2215                 }
   2216             }
   2217 
   2218             Map<String, ? extends Timer> syncs = u.getSyncStats();
   2219             if (syncs.size() > 0) {
   2220                 for (Map.Entry<String, ? extends Timer> ent : syncs.entrySet()) {
   2221                     Timer timer = ent.getValue();
   2222                     // Convert from microseconds to milliseconds with rounding
   2223                     long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
   2224                     int count = timer.getCountLocked(which);
   2225                     if (totalTime != 0) {
   2226                         dumpLine(pw, uid, category, SYNC_DATA, ent.getKey(), totalTime, count);
   2227                     }
   2228                 }
   2229             }
   2230 
   2231             Map<String, ? extends Timer> jobs = u.getJobStats();
   2232             if (jobs.size() > 0) {
   2233                 for (Map.Entry<String, ? extends Timer> ent : jobs.entrySet()) {
   2234                     Timer timer = ent.getValue();
   2235                     // Convert from microseconds to milliseconds with rounding
   2236                     long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
   2237                     int count = timer.getCountLocked(which);
   2238                     if (totalTime != 0) {
   2239                         dumpLine(pw, uid, category, JOB_DATA, ent.getKey(), totalTime, count);
   2240                     }
   2241                 }
   2242             }
   2243 
   2244             SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
   2245             int NSE = sensors.size();
   2246             for (int ise=0; ise<NSE; ise++) {
   2247                 Uid.Sensor se = sensors.valueAt(ise);
   2248                 int sensorNumber = sensors.keyAt(ise);
   2249                 Timer timer = se.getSensorTime();
   2250                 if (timer != null) {
   2251                     // Convert from microseconds to milliseconds with rounding
   2252                     long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
   2253                     int count = timer.getCountLocked(which);
   2254                     if (totalTime != 0) {
   2255                         dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
   2256                     }
   2257                 }
   2258             }
   2259 
   2260             Timer vibTimer = u.getVibratorOnTimer();
   2261             if (vibTimer != null) {
   2262                 // Convert from microseconds to milliseconds with rounding
   2263                 long totalTime = (vibTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
   2264                 int count = vibTimer.getCountLocked(which);
   2265                 if (totalTime != 0) {
   2266                     dumpLine(pw, uid, category, VIBRATOR_DATA, totalTime, count);
   2267                 }
   2268             }
   2269 
   2270             Timer fgTimer = u.getForegroundActivityTimer();
   2271             if (fgTimer != null) {
   2272                 // Convert from microseconds to milliseconds with rounding
   2273                 long totalTime = (fgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
   2274                 int count = fgTimer.getCountLocked(which);
   2275                 if (totalTime != 0) {
   2276                     dumpLine(pw, uid, category, FOREGROUND_DATA, totalTime, count);
   2277                 }
   2278             }
   2279 
   2280             Object[] stateTimes = new Object[Uid.NUM_PROCESS_STATE];
   2281             long totalStateTime = 0;
   2282             for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
   2283                 totalStateTime += u.getProcessStateTime(ips, rawRealtime, which);
   2284                 stateTimes[ips] = (totalStateTime + 500) / 1000;
   2285             }
   2286             if (totalStateTime > 0) {
   2287                 dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes);
   2288             }
   2289 
   2290             Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
   2291             if (processStats.size() > 0) {
   2292                 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
   2293                         : processStats.entrySet()) {
   2294                     Uid.Proc ps = ent.getValue();
   2295 
   2296                     final long userMillis = ps.getUserTime(which) * 10;
   2297                     final long systemMillis = ps.getSystemTime(which) * 10;
   2298                     final long foregroundMillis = ps.getForegroundTime(which) * 10;
   2299                     final int starts = ps.getStarts(which);
   2300                     final int numCrashes = ps.getNumCrashes(which);
   2301                     final int numAnrs = ps.getNumAnrs(which);
   2302 
   2303                     if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0
   2304                             || starts != 0 || numAnrs != 0 || numCrashes != 0) {
   2305                         dumpLine(pw, uid, category, PROCESS_DATA, ent.getKey(), userMillis,
   2306                                 systemMillis, foregroundMillis, starts, numAnrs, numCrashes);
   2307                     }
   2308                 }
   2309             }
   2310 
   2311             Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
   2312             if (packageStats.size() > 0) {
   2313                 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
   2314                         : packageStats.entrySet()) {
   2315 
   2316                     Uid.Pkg ps = ent.getValue();
   2317                     int wakeups = ps.getWakeups(which);
   2318                     Map<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
   2319                     for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
   2320                             : serviceStats.entrySet()) {
   2321                         BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
   2322                         long startTime = ss.getStartTime(batteryUptime, which);
   2323                         int starts = ss.getStarts(which);
   2324                         int launches = ss.getLaunches(which);
   2325                         if (startTime != 0 || starts != 0 || launches != 0) {
   2326                             dumpLine(pw, uid, category, APK_DATA,
   2327                                     wakeups, // wakeup alarms
   2328                                     ent.getKey(), // Apk
   2329                                     sent.getKey(), // service
   2330                                     startTime / 1000, // time spent started, in ms
   2331                                     starts,
   2332                                     launches);
   2333                         }
   2334                     }
   2335                 }
   2336             }
   2337         }
   2338     }
   2339 
   2340     static final class TimerEntry {
   2341         final String mName;
   2342         final int mId;
   2343         final BatteryStats.Timer mTimer;
   2344         final long mTime;
   2345         TimerEntry(String name, int id, BatteryStats.Timer timer, long time) {
   2346             mName = name;
   2347             mId = id;
   2348             mTimer = timer;
   2349             mTime = time;
   2350         }
   2351     }
   2352 
   2353     private void printmAh(PrintWriter printer, double power) {
   2354         printer.print(BatteryStatsHelper.makemAh(power));
   2355     }
   2356 
   2357     /**
   2358      * Temporary for settings.
   2359      */
   2360     public final void dumpLocked(Context context, PrintWriter pw, String prefix, int which,
   2361             int reqUid) {
   2362         dumpLocked(context, pw, prefix, which, reqUid, BatteryStatsHelper.checkWifiOnly(context));
   2363     }
   2364 
   2365     @SuppressWarnings("unused")
   2366     public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which,
   2367             int reqUid, boolean wifiOnly) {
   2368         final long rawUptime = SystemClock.uptimeMillis() * 1000;
   2369         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
   2370         final long batteryUptime = getBatteryUptime(rawUptime);
   2371 
   2372         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
   2373         final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
   2374         final long totalRealtime = computeRealtime(rawRealtime, which);
   2375         final long totalUptime = computeUptime(rawUptime, which);
   2376         final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
   2377         final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime,
   2378                 which);
   2379         final long batteryTimeRemaining = computeBatteryTimeRemaining(rawRealtime);
   2380         final long chargeTimeRemaining = computeChargeTimeRemaining(rawRealtime);
   2381 
   2382         StringBuilder sb = new StringBuilder(128);
   2383 
   2384         SparseArray<? extends Uid> uidStats = getUidStats();
   2385         final int NU = uidStats.size();
   2386 
   2387         sb.setLength(0);
   2388         sb.append(prefix);
   2389                 sb.append("  Time on battery: ");
   2390                 formatTimeMs(sb, whichBatteryRealtime / 1000); sb.append("(");
   2391                 sb.append(formatRatioLocked(whichBatteryRealtime, totalRealtime));
   2392                 sb.append(") realtime, ");
   2393                 formatTimeMs(sb, whichBatteryUptime / 1000);
   2394                 sb.append("("); sb.append(formatRatioLocked(whichBatteryUptime, totalRealtime));
   2395                 sb.append(") uptime");
   2396         pw.println(sb.toString());
   2397         sb.setLength(0);
   2398         sb.append(prefix);
   2399                 sb.append("  Time on battery screen off: ");
   2400                 formatTimeMs(sb, whichBatteryScreenOffRealtime / 1000); sb.append("(");
   2401                 sb.append(formatRatioLocked(whichBatteryScreenOffRealtime, totalRealtime));
   2402                 sb.append(") realtime, ");
   2403                 formatTimeMs(sb, whichBatteryScreenOffUptime / 1000);
   2404                 sb.append("(");
   2405                 sb.append(formatRatioLocked(whichBatteryScreenOffUptime, totalRealtime));
   2406                 sb.append(") uptime");
   2407         pw.println(sb.toString());
   2408         sb.setLength(0);
   2409         sb.append(prefix);
   2410                 sb.append("  Total run time: ");
   2411                 formatTimeMs(sb, totalRealtime / 1000);
   2412                 sb.append("realtime, ");
   2413                 formatTimeMs(sb, totalUptime / 1000);
   2414                 sb.append("uptime");
   2415         pw.println(sb.toString());
   2416         if (batteryTimeRemaining >= 0) {
   2417             sb.setLength(0);
   2418             sb.append(prefix);
   2419                     sb.append("  Battery time remaining: ");
   2420                     formatTimeMs(sb, batteryTimeRemaining / 1000);
   2421             pw.println(sb.toString());
   2422         }
   2423         if (chargeTimeRemaining >= 0) {
   2424             sb.setLength(0);
   2425             sb.append(prefix);
   2426                     sb.append("  Charge time remaining: ");
   2427                     formatTimeMs(sb, chargeTimeRemaining / 1000);
   2428             pw.println(sb.toString());
   2429         }
   2430         pw.print("  Start clock time: ");
   2431         pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", getStartClockTime()).toString());
   2432 
   2433         final long screenOnTime = getScreenOnTime(rawRealtime, which);
   2434         final long interactiveTime = getInteractiveTime(rawRealtime, which);
   2435         final long lowPowerModeEnabledTime = getLowPowerModeEnabledTime(rawRealtime, which);
   2436         final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
   2437         final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
   2438         final long wifiOnTime = getWifiOnTime(rawRealtime, which);
   2439         final long bluetoothOnTime = getBluetoothOnTime(rawRealtime, which);
   2440         sb.setLength(0);
   2441         sb.append(prefix);
   2442                 sb.append("  Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
   2443                 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
   2444                 sb.append(") "); sb.append(getScreenOnCount(which));
   2445                 sb.append("x, Interactive: "); formatTimeMs(sb, interactiveTime / 1000);
   2446                 sb.append("("); sb.append(formatRatioLocked(interactiveTime, whichBatteryRealtime));
   2447                 sb.append(")");
   2448         pw.println(sb.toString());
   2449         sb.setLength(0);
   2450         sb.append(prefix);
   2451         sb.append("  Screen brightnesses:");
   2452         boolean didOne = false;
   2453         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
   2454             final long time = getScreenBrightnessTime(i, rawRealtime, which);
   2455             if (time == 0) {
   2456                 continue;
   2457             }
   2458             sb.append("\n    ");
   2459             sb.append(prefix);
   2460             didOne = true;
   2461             sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
   2462             sb.append(" ");
   2463             formatTimeMs(sb, time/1000);
   2464             sb.append("(");
   2465             sb.append(formatRatioLocked(time, screenOnTime));
   2466             sb.append(")");
   2467         }
   2468         if (!didOne) sb.append(" (no activity)");
   2469         pw.println(sb.toString());
   2470         if (lowPowerModeEnabledTime != 0) {
   2471             sb.setLength(0);
   2472             sb.append(prefix);
   2473                     sb.append("  Low power mode enabled: ");
   2474                     formatTimeMs(sb, lowPowerModeEnabledTime / 1000);
   2475                     sb.append("(");
   2476                     sb.append(formatRatioLocked(lowPowerModeEnabledTime, whichBatteryRealtime));
   2477                     sb.append(")");
   2478             pw.println(sb.toString());
   2479         }
   2480         if (phoneOnTime != 0) {
   2481             sb.setLength(0);
   2482             sb.append(prefix);
   2483                     sb.append("  Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
   2484                     sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
   2485                     sb.append(") "); sb.append(getPhoneOnCount(which));
   2486         }
   2487         int connChanges = getNumConnectivityChange(which);
   2488         if (connChanges != 0) {
   2489             pw.print(prefix);
   2490             pw.print("  Connectivity changes: "); pw.println(connChanges);
   2491         }
   2492 
   2493         // Calculate wakelock times across all uids.
   2494         long fullWakeLockTimeTotalMicros = 0;
   2495         long partialWakeLockTimeTotalMicros = 0;
   2496 
   2497         final ArrayList<TimerEntry> timers = new ArrayList<TimerEntry>();
   2498 
   2499         for (int iu = 0; iu < NU; iu++) {
   2500             Uid u = uidStats.valueAt(iu);
   2501 
   2502             Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
   2503             if (wakelocks.size() > 0) {
   2504                 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
   2505                         : wakelocks.entrySet()) {
   2506                     Uid.Wakelock wl = ent.getValue();
   2507 
   2508                     Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
   2509                     if (fullWakeTimer != null) {
   2510                         fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
   2511                                 rawRealtime, which);
   2512                     }
   2513 
   2514                     Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
   2515                     if (partialWakeTimer != null) {
   2516                         long totalTimeMicros = partialWakeTimer.getTotalTimeLocked(
   2517                                 rawRealtime, which);
   2518                         if (totalTimeMicros > 0) {
   2519                             if (reqUid < 0) {
   2520                                 // Only show the ordered list of all wake
   2521                                 // locks if the caller is not asking for data
   2522                                 // about a specific uid.
   2523                                 timers.add(new TimerEntry(ent.getKey(), u.getUid(),
   2524                                         partialWakeTimer, totalTimeMicros));
   2525                             }
   2526                             partialWakeLockTimeTotalMicros += totalTimeMicros;
   2527                         }
   2528                     }
   2529                 }
   2530             }
   2531         }
   2532 
   2533         long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
   2534         long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
   2535         long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
   2536         long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
   2537         long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
   2538         long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
   2539         long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
   2540         long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
   2541 
   2542         if (fullWakeLockTimeTotalMicros != 0) {
   2543             sb.setLength(0);
   2544             sb.append(prefix);
   2545                     sb.append("  Total full wakelock time: "); formatTimeMsNoSpace(sb,
   2546                             (fullWakeLockTimeTotalMicros + 500) / 1000);
   2547             pw.println(sb.toString());
   2548         }
   2549 
   2550         if (partialWakeLockTimeTotalMicros != 0) {
   2551             sb.setLength(0);
   2552             sb.append(prefix);
   2553                     sb.append("  Total partial wakelock time: "); formatTimeMsNoSpace(sb,
   2554                             (partialWakeLockTimeTotalMicros + 500) / 1000);
   2555             pw.println(sb.toString());
   2556         }
   2557 
   2558         pw.print(prefix);
   2559                 pw.print("  Mobile total received: "); pw.print(formatBytesLocked(mobileRxTotalBytes));
   2560                 pw.print(", sent: "); pw.print(formatBytesLocked(mobileTxTotalBytes));
   2561                 pw.print(" (packets received "); pw.print(mobileRxTotalPackets);
   2562                 pw.print(", sent "); pw.print(mobileTxTotalPackets); pw.println(")");
   2563         sb.setLength(0);
   2564         sb.append(prefix);
   2565         sb.append("  Phone signal levels:");
   2566         didOne = false;
   2567         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
   2568             final long time = getPhoneSignalStrengthTime(i, rawRealtime, which);
   2569             if (time == 0) {
   2570                 continue;
   2571             }
   2572             sb.append("\n    ");
   2573             sb.append(prefix);
   2574             didOne = true;
   2575             sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]);
   2576             sb.append(" ");
   2577             formatTimeMs(sb, time/1000);
   2578             sb.append("(");
   2579             sb.append(formatRatioLocked(time, whichBatteryRealtime));
   2580             sb.append(") ");
   2581             sb.append(getPhoneSignalStrengthCount(i, which));
   2582             sb.append("x");
   2583         }
   2584         if (!didOne) sb.append(" (no activity)");
   2585         pw.println(sb.toString());
   2586 
   2587         sb.setLength(0);
   2588         sb.append(prefix);
   2589         sb.append("  Signal scanning time: ");
   2590         formatTimeMsNoSpace(sb, getPhoneSignalScanningTime(rawRealtime, which) / 1000);
   2591         pw.println(sb.toString());
   2592 
   2593         sb.setLength(0);
   2594         sb.append(prefix);
   2595         sb.append("  Radio types:");
   2596         didOne = false;
   2597         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
   2598             final long time = getPhoneDataConnectionTime(i, rawRealtime, which);
   2599             if (time == 0) {
   2600                 continue;
   2601             }
   2602             sb.append("\n    ");
   2603             sb.append(prefix);
   2604             didOne = true;
   2605             sb.append(DATA_CONNECTION_NAMES[i]);
   2606             sb.append(" ");
   2607             formatTimeMs(sb, time/1000);
   2608             sb.append("(");
   2609             sb.append(formatRatioLocked(time, whichBatteryRealtime));
   2610             sb.append(") ");
   2611             sb.append(getPhoneDataConnectionCount(i, which));
   2612             sb.append("x");
   2613         }
   2614         if (!didOne) sb.append(" (no activity)");
   2615         pw.println(sb.toString());
   2616 
   2617         sb.setLength(0);
   2618         sb.append(prefix);
   2619         sb.append("  Mobile radio active time: ");
   2620         final long mobileActiveTime = getMobileRadioActiveTime(rawRealtime, which);
   2621         formatTimeMs(sb, mobileActiveTime / 1000);
   2622         sb.append("("); sb.append(formatRatioLocked(mobileActiveTime, whichBatteryRealtime));
   2623         sb.append(") "); sb.append(getMobileRadioActiveCount(which));
   2624         sb.append("x");
   2625         pw.println(sb.toString());
   2626 
   2627         final long mobileActiveUnknownTime = getMobileRadioActiveUnknownTime(which);
   2628         if (mobileActiveUnknownTime != 0) {
   2629             sb.setLength(0);
   2630             sb.append(prefix);
   2631             sb.append("  Mobile radio active unknown time: ");
   2632             formatTimeMs(sb, mobileActiveUnknownTime / 1000);
   2633             sb.append("(");
   2634             sb.append(formatRatioLocked(mobileActiveUnknownTime, whichBatteryRealtime));
   2635             sb.append(") "); sb.append(getMobileRadioActiveUnknownCount(which));
   2636             sb.append("x");
   2637             pw.println(sb.toString());
   2638         }
   2639 
   2640         final long mobileActiveAdjustedTime = getMobileRadioActiveAdjustedTime(which);
   2641         if (mobileActiveAdjustedTime != 0) {
   2642             sb.setLength(0);
   2643             sb.append(prefix);
   2644             sb.append("  Mobile radio active adjusted time: ");
   2645             formatTimeMs(sb, mobileActiveAdjustedTime / 1000);
   2646             sb.append("(");
   2647             sb.append(formatRatioLocked(mobileActiveAdjustedTime, whichBatteryRealtime));
   2648             sb.append(")");
   2649             pw.println(sb.toString());
   2650         }
   2651 
   2652         pw.print(prefix);
   2653                 pw.print("  Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotalBytes));
   2654                 pw.print(", sent: "); pw.print(formatBytesLocked(wifiTxTotalBytes));
   2655                 pw.print(" (packets received "); pw.print(wifiRxTotalPackets);
   2656                 pw.print(", sent "); pw.print(wifiTxTotalPackets); pw.println(")");
   2657         sb.setLength(0);
   2658         sb.append(prefix);
   2659                 sb.append("  Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
   2660                 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
   2661                 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000);
   2662                 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
   2663                 sb.append(")");
   2664         pw.println(sb.toString());
   2665 
   2666         sb.setLength(0);
   2667         sb.append(prefix);
   2668         sb.append("  Wifi states:");
   2669         didOne = false;
   2670         for (int i=0; i<NUM_WIFI_STATES; i++) {
   2671             final long time = getWifiStateTime(i, rawRealtime, which);
   2672             if (time == 0) {
   2673                 continue;
   2674             }
   2675             sb.append("\n    ");
   2676             didOne = true;
   2677             sb.append(WIFI_STATE_NAMES[i]);
   2678             sb.append(" ");
   2679             formatTimeMs(sb, time/1000);
   2680             sb.append("(");
   2681             sb.append(formatRatioLocked(time, whichBatteryRealtime));
   2682             sb.append(") ");
   2683             sb.append(getWifiStateCount(i, which));
   2684             sb.append("x");
   2685         }
   2686         if (!didOne) sb.append(" (no activity)");
   2687         pw.println(sb.toString());
   2688 
   2689         sb.setLength(0);
   2690         sb.append(prefix);
   2691         sb.append("  Wifi supplicant states:");
   2692         didOne = false;
   2693         for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
   2694             final long time = getWifiSupplStateTime(i, rawRealtime, which);
   2695             if (time == 0) {
   2696                 continue;
   2697             }
   2698             sb.append("\n    ");
   2699             didOne = true;
   2700             sb.append(WIFI_SUPPL_STATE_NAMES[i]);
   2701             sb.append(" ");
   2702             formatTimeMs(sb, time/1000);
   2703             sb.append("(");
   2704             sb.append(formatRatioLocked(time, whichBatteryRealtime));
   2705             sb.append(") ");
   2706             sb.append(getWifiSupplStateCount(i, which));
   2707             sb.append("x");
   2708         }
   2709         if (!didOne) sb.append(" (no activity)");
   2710         pw.println(sb.toString());
   2711 
   2712         sb.setLength(0);
   2713         sb.append(prefix);
   2714         sb.append("  Wifi signal levels:");
   2715         didOne = false;
   2716         for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
   2717             final long time = getWifiSignalStrengthTime(i, rawRealtime, which);
   2718             if (time == 0) {
   2719                 continue;
   2720             }
   2721             sb.append("\n    ");
   2722             sb.append(prefix);
   2723             didOne = true;
   2724             sb.append("level(");
   2725             sb.append(i);
   2726             sb.append(") ");
   2727             formatTimeMs(sb, time/1000);
   2728             sb.append("(");
   2729             sb.append(formatRatioLocked(time, whichBatteryRealtime));
   2730             sb.append(") ");
   2731             sb.append(getWifiSignalStrengthCount(i, which));
   2732             sb.append("x");
   2733         }
   2734         if (!didOne) sb.append(" (no activity)");
   2735         pw.println(sb.toString());
   2736 
   2737         sb.setLength(0);
   2738         sb.append(prefix);
   2739                 sb.append("  Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000);
   2740                 sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime));
   2741                 sb.append(")");
   2742         pw.println(sb.toString());
   2743 
   2744         sb.setLength(0);
   2745         sb.append(prefix);
   2746         sb.append("  Bluetooth states:");
   2747         didOne = false;
   2748         for (int i=0; i<NUM_BLUETOOTH_STATES; i++) {
   2749             final long time = getBluetoothStateTime(i, rawRealtime, which);
   2750             if (time == 0) {
   2751                 continue;
   2752             }
   2753             sb.append("\n    ");
   2754             didOne = true;
   2755             sb.append(BLUETOOTH_STATE_NAMES[i]);
   2756             sb.append(" ");
   2757             formatTimeMs(sb, time/1000);
   2758             sb.append("(");
   2759             sb.append(formatRatioLocked(time, whichBatteryRealtime));
   2760             sb.append(") ");
   2761             sb.append(getPhoneDataConnectionCount(i, which));
   2762             sb.append("x");
   2763         }
   2764         if (!didOne) sb.append(" (no activity)");
   2765         pw.println(sb.toString());
   2766 
   2767         pw.println();
   2768 
   2769         if (which == STATS_SINCE_UNPLUGGED) {
   2770             if (getIsOnBattery()) {
   2771                 pw.print(prefix); pw.println("  Device is currently unplugged");
   2772                 pw.print(prefix); pw.print("    Discharge cycle start level: ");
   2773                         pw.println(getDischargeStartLevel());
   2774                 pw.print(prefix); pw.print("    Discharge cycle current level: ");
   2775                         pw.println(getDischargeCurrentLevel());
   2776             } else {
   2777                 pw.print(prefix); pw.println("  Device is currently plugged into power");
   2778                 pw.print(prefix); pw.print("    Last discharge cycle start level: ");
   2779                         pw.println(getDischargeStartLevel());
   2780                 pw.print(prefix); pw.print("    Last discharge cycle end level: ");
   2781                         pw.println(getDischargeCurrentLevel());
   2782             }
   2783             pw.print(prefix); pw.print("    Amount discharged while screen on: ");
   2784                     pw.println(getDischargeAmountScreenOn());
   2785             pw.print(prefix); pw.print("    Amount discharged while screen off: ");
   2786                     pw.println(getDischargeAmountScreenOff());
   2787             pw.println(" ");
   2788         } else {
   2789             pw.print(prefix); pw.println("  Device battery use since last full charge");
   2790             pw.print(prefix); pw.print("    Amount discharged (lower bound): ");
   2791                     pw.println(getLowDischargeAmountSinceCharge());
   2792             pw.print(prefix); pw.print("    Amount discharged (upper bound): ");
   2793                     pw.println(getHighDischargeAmountSinceCharge());
   2794             pw.print(prefix); pw.print("    Amount discharged while screen on: ");
   2795                     pw.println(getDischargeAmountScreenOnSinceCharge());
   2796             pw.print(prefix); pw.print("    Amount discharged while screen off: ");
   2797                     pw.println(getDischargeAmountScreenOffSinceCharge());
   2798             pw.println();
   2799         }
   2800 
   2801         BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
   2802         helper.create(this);
   2803         helper.refreshStats(which, UserHandle.USER_ALL);
   2804         List<BatterySipper> sippers = helper.getUsageList();
   2805         if (sippers != null && sippers.size() > 0) {
   2806             pw.print(prefix); pw.println("  Estimated power use (mAh):");
   2807             pw.print(prefix); pw.print("    Capacity: ");
   2808                     printmAh(pw, helper.getPowerProfile().getBatteryCapacity());
   2809                     pw.print(", Computed drain: "); printmAh(pw, helper.getComputedPower());
   2810                     pw.print(", actual drain: "); printmAh(pw, helper.getMinDrainedPower());
   2811                     if (helper.getMinDrainedPower() != helper.getMaxDrainedPower()) {
   2812                         pw.print("-"); printmAh(pw, helper.getMaxDrainedPower());
   2813                     }
   2814                     pw.println();
   2815             for (int i=0; i<sippers.size(); i++) {
   2816                 BatterySipper bs = sippers.get(i);
   2817                 switch (bs.drainType) {
   2818                     case IDLE:
   2819                         pw.print(prefix); pw.print("    Idle: "); printmAh(pw, bs.value);
   2820                         pw.println();
   2821                         break;
   2822                     case CELL:
   2823                         pw.print(prefix); pw.print("    Cell standby: "); printmAh(pw, bs.value);
   2824                         pw.println();
   2825                         break;
   2826                     case PHONE:
   2827                         pw.print(prefix); pw.print("    Phone calls: "); printmAh(pw, bs.value);
   2828                         pw.println();
   2829                         break;
   2830                     case WIFI:
   2831                         pw.print(prefix); pw.print("    Wifi: "); printmAh(pw, bs.value);
   2832                         pw.println();
   2833                         break;
   2834                     case BLUETOOTH:
   2835                         pw.print(prefix); pw.print("    Bluetooth: "); printmAh(pw, bs.value);
   2836                         pw.println();
   2837                         break;
   2838                     case SCREEN:
   2839                         pw.print(prefix); pw.print("    Screen: "); printmAh(pw, bs.value);
   2840                         pw.println();
   2841                         break;
   2842                     case FLASHLIGHT:
   2843                         pw.print(prefix); pw.print("    Flashlight: "); printmAh(pw, bs.value);
   2844                         pw.println();
   2845                         break;
   2846                     case APP:
   2847                         pw.print(prefix); pw.print("    Uid ");
   2848                         UserHandle.formatUid(pw, bs.uidObj.getUid());
   2849                         pw.print(": "); printmAh(pw, bs.value); pw.println();
   2850                         break;
   2851                     case USER:
   2852                         pw.print(prefix); pw.print("    User "); pw.print(bs.userId);
   2853                         pw.print(": "); printmAh(pw, bs.value); pw.println();
   2854                         break;
   2855                     case UNACCOUNTED:
   2856                         pw.print(prefix); pw.print("    Unaccounted: "); printmAh(pw, bs.value);
   2857                         pw.println();
   2858                         break;
   2859                     case OVERCOUNTED:
   2860                         pw.print(prefix); pw.print("    Over-counted: "); printmAh(pw, bs.value);
   2861                         pw.println();
   2862                         break;
   2863                 }
   2864             }
   2865             pw.println();
   2866         }
   2867 
   2868         sippers = helper.getMobilemsppList();
   2869         if (sippers != null && sippers.size() > 0) {
   2870             pw.print(prefix); pw.println("  Per-app mobile ms per packet:");
   2871             long totalTime = 0;
   2872             for (int i=0; i<sippers.size(); i++) {
   2873                 BatterySipper bs = sippers.get(i);
   2874                 sb.setLength(0);
   2875                 sb.append(prefix); sb.append("    Uid ");
   2876                 UserHandle.formatUid(sb, bs.uidObj.getUid());
   2877                 sb.append(": "); sb.append(BatteryStatsHelper.makemAh(bs.mobilemspp));
   2878                 sb.append(" ("); sb.append(bs.mobileRxPackets+bs.mobileTxPackets);
   2879                 sb.append(" packets over "); formatTimeMsNoSpace(sb, bs.mobileActive);
   2880                 sb.append(") "); sb.append(bs.mobileActiveCount); sb.append("x");
   2881                 pw.println(sb.toString());
   2882                 totalTime += bs.mobileActive;
   2883             }
   2884             sb.setLength(0);
   2885             sb.append(prefix);
   2886             sb.append("    TOTAL TIME: ");
   2887             formatTimeMs(sb, totalTime);
   2888             sb.append("("); sb.append(formatRatioLocked(totalTime, whichBatteryRealtime));
   2889             sb.append(")");
   2890             pw.println(sb.toString());
   2891             pw.println();
   2892         }
   2893 
   2894         final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() {
   2895             @Override
   2896             public int compare(TimerEntry lhs, TimerEntry rhs) {
   2897                 long lhsTime = lhs.mTime;
   2898                 long rhsTime = rhs.mTime;
   2899                 if (lhsTime < rhsTime) {
   2900                     return 1;
   2901                 }
   2902                 if (lhsTime > rhsTime) {
   2903                     return -1;
   2904                 }
   2905                 return 0;
   2906             }
   2907         };
   2908 
   2909         if (reqUid < 0) {
   2910             Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
   2911             if (kernelWakelocks.size() > 0) {
   2912                 final ArrayList<TimerEntry> ktimers = new ArrayList<TimerEntry>();
   2913                 for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
   2914                     BatteryStats.Timer timer = ent.getValue();
   2915                     long totalTimeMillis = computeWakeLock(timer, rawRealtime, which);
   2916                     if (totalTimeMillis > 0) {
   2917                         ktimers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis));
   2918                     }
   2919                 }
   2920                 if (ktimers.size() > 0) {
   2921                     Collections.sort(ktimers, timerComparator);
   2922                     pw.print(prefix); pw.println("  All kernel wake locks:");
   2923                     for (int i=0; i<ktimers.size(); i++) {
   2924                         TimerEntry timer = ktimers.get(i);
   2925                         String linePrefix = ": ";
   2926                         sb.setLength(0);
   2927                         sb.append(prefix);
   2928                         sb.append("  Kernel Wake lock ");
   2929                         sb.append(timer.mName);
   2930                         linePrefix = printWakeLock(sb, timer.mTimer, rawRealtime, null,
   2931                                 which, linePrefix);
   2932                         if (!linePrefix.equals(": ")) {
   2933                             sb.append(" realtime");
   2934                             // Only print out wake locks that were held
   2935                             pw.println(sb.toString());
   2936                         }
   2937                     }
   2938                     pw.println();
   2939                 }
   2940             }
   2941 
   2942             if (timers.size() > 0) {
   2943                 Collections.sort(timers, timerComparator);
   2944                 pw.print(prefix); pw.println("  All partial wake locks:");
   2945                 for (int i=0; i<timers.size(); i++) {
   2946                     TimerEntry timer = timers.get(i);
   2947                     sb.setLength(0);
   2948                     sb.append("  Wake lock ");
   2949                     UserHandle.formatUid(sb, timer.mId);
   2950                     sb.append(" ");
   2951                     sb.append(timer.mName);
   2952                     printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
   2953                     sb.append(" realtime");
   2954                     pw.println(sb.toString());
   2955                 }
   2956                 timers.clear();
   2957                 pw.println();
   2958             }
   2959 
   2960             Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
   2961             if (wakeupReasons.size() > 0) {
   2962                 pw.print(prefix); pw.println("  All wakeup reasons:");
   2963                 final ArrayList<TimerEntry> reasons = new ArrayList<TimerEntry>();
   2964                 for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
   2965                     Timer timer = ent.getValue();
   2966                     reasons.add(new TimerEntry(ent.getKey(), 0, timer,
   2967                             timer.getCountLocked(which)));
   2968                 }
   2969                 Collections.sort(reasons, timerComparator);
   2970                 for (int i=0; i<reasons.size(); i++) {
   2971                     TimerEntry timer = reasons.get(i);
   2972                     String linePrefix = ": ";
   2973                     sb.setLength(0);
   2974                     sb.append(prefix);
   2975                     sb.append("  Wakeup reason ");
   2976                     sb.append(timer.mName);
   2977                     printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
   2978                     sb.append(" realtime");
   2979                     pw.println(sb.toString());
   2980                 }
   2981                 pw.println();
   2982             }
   2983         }
   2984 
   2985         for (int iu=0; iu<NU; iu++) {
   2986             final int uid = uidStats.keyAt(iu);
   2987             if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
   2988                 continue;
   2989             }
   2990 
   2991             Uid u = uidStats.valueAt(iu);
   2992 
   2993             pw.print(prefix);
   2994             pw.print("  ");
   2995             UserHandle.formatUid(pw, uid);
   2996             pw.println(":");
   2997             boolean uidActivity = false;
   2998 
   2999             long mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
   3000             long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
   3001             long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
   3002             long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
   3003             long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
   3004             long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
   3005             long uidMobileActiveTime = u.getMobileRadioActiveTime(which);
   3006             int uidMobileActiveCount = u.getMobileRadioActiveCount(which);
   3007             long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
   3008             long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
   3009             long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
   3010             long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
   3011             long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
   3012 
   3013             if (mobileRxBytes > 0 || mobileTxBytes > 0
   3014                     || mobileRxPackets > 0 || mobileTxPackets > 0) {
   3015                 pw.print(prefix); pw.print("    Mobile network: ");
   3016                         pw.print(formatBytesLocked(mobileRxBytes)); pw.print(" received, ");
   3017                         pw.print(formatBytesLocked(mobileTxBytes));
   3018                         pw.print(" sent (packets "); pw.print(mobileRxPackets);
   3019                         pw.print(" received, "); pw.print(mobileTxPackets); pw.println(" sent)");
   3020             }
   3021             if (uidMobileActiveTime > 0 || uidMobileActiveCount > 0) {
   3022                 sb.setLength(0);
   3023                 sb.append(prefix); sb.append("    Mobile radio active: ");
   3024                 formatTimeMs(sb, uidMobileActiveTime / 1000);
   3025                 sb.append("(");
   3026                 sb.append(formatRatioLocked(uidMobileActiveTime, mobileActiveTime));
   3027                 sb.append(") "); sb.append(uidMobileActiveCount); sb.append("x");
   3028                 long packets = mobileRxPackets + mobileTxPackets;
   3029                 if (packets == 0) {
   3030                     packets = 1;
   3031                 }
   3032                 sb.append(" @ ");
   3033                 sb.append(BatteryStatsHelper.makemAh(uidMobileActiveTime / 1000 / (double)packets));
   3034                 sb.append(" mspp");
   3035                 pw.println(sb.toString());
   3036             }
   3037 
   3038             if (wifiRxBytes > 0 || wifiTxBytes > 0 || wifiRxPackets > 0 || wifiTxPackets > 0) {
   3039                 pw.print(prefix); pw.print("    Wi-Fi network: ");
   3040                         pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, ");
   3041                         pw.print(formatBytesLocked(wifiTxBytes));
   3042                         pw.print(" sent (packets "); pw.print(wifiRxPackets);
   3043                         pw.print(" received, "); pw.print(wifiTxPackets); pw.println(" sent)");
   3044             }
   3045 
   3046             if (fullWifiLockOnTime != 0 || wifiScanTime != 0
   3047                     || uidWifiRunningTime != 0) {
   3048                 sb.setLength(0);
   3049                 sb.append(prefix); sb.append("    Wifi Running: ");
   3050                         formatTimeMs(sb, uidWifiRunningTime / 1000);
   3051                         sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
   3052                                 whichBatteryRealtime)); sb.append(")\n");
   3053                 sb.append(prefix); sb.append("    Full Wifi Lock: ");
   3054                         formatTimeMs(sb, fullWifiLockOnTime / 1000);
   3055                         sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
   3056                                 whichBatteryRealtime)); sb.append(")\n");
   3057                 sb.append(prefix); sb.append("    Wifi Scan: ");
   3058                         formatTimeMs(sb, wifiScanTime / 1000);
   3059                         sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
   3060                                 whichBatteryRealtime)); sb.append(")");
   3061                 pw.println(sb.toString());
   3062             }
   3063 
   3064             if (u.hasUserActivity()) {
   3065                 boolean hasData = false;
   3066                 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
   3067                     int val = u.getUserActivityCount(i, which);
   3068                     if (val != 0) {
   3069                         if (!hasData) {
   3070                             sb.setLength(0);
   3071                             sb.append("    User activity: ");
   3072                             hasData = true;
   3073                         } else {
   3074                             sb.append(", ");
   3075                         }
   3076                         sb.append(val);
   3077                         sb.append(" ");
   3078                         sb.append(Uid.USER_ACTIVITY_TYPES[i]);
   3079                     }
   3080                 }
   3081                 if (hasData) {
   3082                     pw.println(sb.toString());
   3083                 }
   3084             }
   3085 
   3086             Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
   3087             if (wakelocks.size() > 0) {
   3088                 long totalFull = 0, totalPartial = 0, totalWindow = 0;
   3089                 int count = 0;
   3090                 for (Map.Entry<String, ? extends Uid.Wakelock> ent : wakelocks.entrySet()) {
   3091                     Uid.Wakelock wl = ent.getValue();
   3092                     String linePrefix = ": ";
   3093                     sb.setLength(0);
   3094                     sb.append(prefix);
   3095                     sb.append("    Wake lock ");
   3096                     sb.append(ent.getKey());
   3097                     linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime,
   3098                             "full", which, linePrefix);
   3099                     linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime,
   3100                             "partial", which, linePrefix);
   3101                     linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime,
   3102                             "window", which, linePrefix);
   3103                     if (true || !linePrefix.equals(": ")) {
   3104                         sb.append(" realtime");
   3105                         // Only print out wake locks that were held
   3106                         pw.println(sb.toString());
   3107                         uidActivity = true;
   3108                         count++;
   3109                     }
   3110                     totalFull += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL),
   3111                             rawRealtime, which);
   3112                     totalPartial += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL),
   3113                             rawRealtime, which);
   3114                     totalWindow += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW),
   3115                             rawRealtime, which);
   3116                 }
   3117                 if (count > 1) {
   3118                     if (totalFull != 0 || totalPartial != 0 || totalWindow != 0) {
   3119                         sb.setLength(0);
   3120                         sb.append(prefix);
   3121                         sb.append("    TOTAL wake: ");
   3122                         boolean needComma = false;
   3123                         if (totalFull != 0) {
   3124                             needComma = true;
   3125                             formatTimeMs(sb, totalFull);
   3126                             sb.append("full");
   3127                         }
   3128                         if (totalPartial != 0) {
   3129                             if (needComma) {
   3130                                 sb.append(", ");
   3131                             }
   3132                             needComma = true;
   3133                             formatTimeMs(sb, totalPartial);
   3134                             sb.append("partial");
   3135                         }
   3136                         if (totalWindow != 0) {
   3137                             if (needComma) {
   3138                                 sb.append(", ");
   3139                             }
   3140                             needComma = true;
   3141                             formatTimeMs(sb, totalWindow);
   3142                             sb.append("window");
   3143                         }
   3144                         sb.append(" realtime");
   3145                         pw.println(sb.toString());
   3146                     }
   3147                 }
   3148             }
   3149 
   3150             Map<String, ? extends Timer> syncs = u.getSyncStats();
   3151             if (syncs.size() > 0) {
   3152                 for (Map.Entry<String, ? extends Timer> ent : syncs.entrySet()) {
   3153                     Timer timer = ent.getValue();
   3154                     // Convert from microseconds to milliseconds with rounding
   3155                     long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
   3156                     int count = timer.getCountLocked(which);
   3157                     sb.setLength(0);
   3158                     sb.append(prefix);
   3159                     sb.append("    Sync ");
   3160                     sb.append(ent.getKey());
   3161                     sb.append(": ");
   3162                     if (totalTime != 0) {
   3163                         formatTimeMs(sb, totalTime);
   3164                         sb.append("realtime (");
   3165                         sb.append(count);
   3166                         sb.append(" times)");
   3167                     } else {
   3168                         sb.append("(not used)");
   3169                     }
   3170                     pw.println(sb.toString());
   3171                     uidActivity = true;
   3172                 }
   3173             }
   3174 
   3175             Map<String, ? extends Timer> jobs = u.getJobStats();
   3176             if (jobs.size() > 0) {
   3177                 for (Map.Entry<String, ? extends Timer> ent : jobs.entrySet()) {
   3178                     Timer timer = ent.getValue();
   3179                     // Convert from microseconds to milliseconds with rounding
   3180                     long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
   3181                     int count = timer.getCountLocked(which);
   3182                     sb.setLength(0);
   3183                     sb.append(prefix);
   3184                     sb.append("    Job ");
   3185                     sb.append(ent.getKey());
   3186                     sb.append(": ");
   3187                     if (totalTime != 0) {
   3188                         formatTimeMs(sb, totalTime);
   3189                         sb.append("realtime (");
   3190                         sb.append(count);
   3191                         sb.append(" times)");
   3192                     } else {
   3193                         sb.append("(not used)");
   3194                     }
   3195                     pw.println(sb.toString());
   3196                     uidActivity = true;
   3197                 }
   3198             }
   3199 
   3200             SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
   3201             int NSE = sensors.size();
   3202             for (int ise=0; ise<NSE; ise++) {
   3203                 Uid.Sensor se = sensors.valueAt(ise);
   3204                 int sensorNumber = sensors.keyAt(ise);
   3205                 sb.setLength(0);
   3206                 sb.append(prefix);
   3207                 sb.append("    Sensor ");
   3208                 int handle = se.getHandle();
   3209                 if (handle == Uid.Sensor.GPS) {
   3210                     sb.append("GPS");
   3211                 } else {
   3212                     sb.append(handle);
   3213                 }
   3214                 sb.append(": ");
   3215 
   3216                 Timer timer = se.getSensorTime();
   3217                 if (timer != null) {
   3218                     // Convert from microseconds to milliseconds with rounding
   3219                     long totalTime = (timer.getTotalTimeLocked(
   3220                             rawRealtime, which) + 500) / 1000;
   3221                     int count = timer.getCountLocked(which);
   3222                     //timer.logState();
   3223                     if (totalTime != 0) {
   3224                         formatTimeMs(sb, totalTime);
   3225                         sb.append("realtime (");
   3226                         sb.append(count);
   3227                         sb.append(" times)");
   3228                     } else {
   3229                         sb.append("(not used)");
   3230                     }
   3231                 } else {
   3232                     sb.append("(not used)");
   3233                 }
   3234 
   3235                 pw.println(sb.toString());
   3236                 uidActivity = true;
   3237             }
   3238 
   3239             Timer vibTimer = u.getVibratorOnTimer();
   3240             if (vibTimer != null) {
   3241                 // Convert from microseconds to milliseconds with rounding
   3242                 long totalTime = (vibTimer.getTotalTimeLocked(
   3243                         rawRealtime, which) + 500) / 1000;
   3244                 int count = vibTimer.getCountLocked(which);
   3245                 //timer.logState();
   3246                 if (totalTime != 0) {
   3247                     sb.setLength(0);
   3248                     sb.append(prefix);
   3249                     sb.append("    Vibrator: ");
   3250                     formatTimeMs(sb, totalTime);
   3251                     sb.append("realtime (");
   3252                     sb.append(count);
   3253                     sb.append(" times)");
   3254                     pw.println(sb.toString());
   3255                     uidActivity = true;
   3256                 }
   3257             }
   3258 
   3259             Timer fgTimer = u.getForegroundActivityTimer();
   3260             if (fgTimer != null) {
   3261                 // Convert from microseconds to milliseconds with rounding
   3262                 long totalTime = (fgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
   3263                 int count = fgTimer.getCountLocked(which);
   3264                 if (totalTime != 0) {
   3265                     sb.setLength(0);
   3266                     sb.append(prefix);
   3267                     sb.append("    Foreground activities: ");
   3268                     formatTimeMs(sb, totalTime);
   3269                     sb.append("realtime (");
   3270                     sb.append(count);
   3271                     sb.append(" times)");
   3272                     pw.println(sb.toString());
   3273                     uidActivity = true;
   3274                 }
   3275             }
   3276 
   3277             long totalStateTime = 0;
   3278             for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
   3279                 long time = u.getProcessStateTime(ips, rawRealtime, which);
   3280                 if (time > 0) {
   3281                     totalStateTime += time;
   3282                     sb.setLength(0);
   3283                     sb.append(prefix);
   3284                     sb.append("    ");
   3285                     sb.append(Uid.PROCESS_STATE_NAMES[ips]);
   3286                     sb.append(" for: ");
   3287                     formatTimeMs(sb, (totalStateTime + 500) / 1000);
   3288                     pw.println(sb.toString());
   3289                     uidActivity = true;
   3290                 }
   3291             }
   3292 
   3293             Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
   3294             if (processStats.size() > 0) {
   3295                 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
   3296                     : processStats.entrySet()) {
   3297                     Uid.Proc ps = ent.getValue();
   3298                     long userTime;
   3299                     long systemTime;
   3300                     long foregroundTime;
   3301                     int starts;
   3302                     int numExcessive;
   3303 
   3304                     userTime = ps.getUserTime(which);
   3305                     systemTime = ps.getSystemTime(which);
   3306                     foregroundTime = ps.getForegroundTime(which);
   3307                     starts = ps.getStarts(which);
   3308                     final int numCrashes = ps.getNumCrashes(which);
   3309                     final int numAnrs = ps.getNumAnrs(which);
   3310                     numExcessive = which == STATS_SINCE_CHARGED
   3311                             ? ps.countExcessivePowers() : 0;
   3312 
   3313                     if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0
   3314                             || numExcessive != 0 || numCrashes != 0 || numAnrs != 0) {
   3315                         sb.setLength(0);
   3316                         sb.append(prefix); sb.append("    Proc ");
   3317                                 sb.append(ent.getKey()); sb.append(":\n");
   3318                         sb.append(prefix); sb.append("      CPU: ");
   3319                                 formatTime(sb, userTime); sb.append("usr + ");
   3320                                 formatTime(sb, systemTime); sb.append("krn ; ");
   3321                                 formatTime(sb, foregroundTime); sb.append("fg");
   3322                         if (starts != 0 || numCrashes != 0 || numAnrs != 0) {
   3323                             sb.append("\n"); sb.append(prefix); sb.append("      ");
   3324                             boolean hasOne = false;
   3325                             if (starts != 0) {
   3326                                 hasOne = true;
   3327                                 sb.append(starts); sb.append(" starts");
   3328                             }
   3329                             if (numCrashes != 0) {
   3330                                 if (hasOne) {
   3331                                     sb.append(", ");
   3332                                 }
   3333                                 hasOne = true;
   3334                                 sb.append(numCrashes); sb.append(" crashes");
   3335                             }
   3336                             if (numAnrs != 0) {
   3337                                 if (hasOne) {
   3338                                     sb.append(", ");
   3339                                 }
   3340                                 sb.append(numAnrs); sb.append(" anrs");
   3341                             }
   3342                         }
   3343                         pw.println(sb.toString());
   3344                         for (int e=0; e<numExcessive; e++) {
   3345                             Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e);
   3346                             if (ew != null) {
   3347                                 pw.print(prefix); pw.print("      * Killed for ");
   3348                                         if (ew.type == Uid.Proc.ExcessivePower.TYPE_WAKE) {
   3349                                             pw.print("wake lock");
   3350                                         } else if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) {
   3351                                             pw.print("cpu");
   3352                                         } else {
   3353                                             pw.print("unknown");
   3354                                         }
   3355                                         pw.print(" use: ");
   3356                                         TimeUtils.formatDuration(ew.usedTime, pw);
   3357                                         pw.print(" over ");
   3358                                         TimeUtils.formatDuration(ew.overTime, pw);
   3359                                         if (ew.overTime != 0) {
   3360                                             pw.print(" (");
   3361                                             pw.print((ew.usedTime*100)/ew.overTime);
   3362                                             pw.println("%)");
   3363                                         }
   3364                             }
   3365                         }
   3366                         uidActivity = true;
   3367                     }
   3368                 }
   3369             }
   3370 
   3371             Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
   3372             if (packageStats.size() > 0) {
   3373                 for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
   3374                     : packageStats.entrySet()) {
   3375                     pw.print(prefix); pw.print("    Apk "); pw.print(ent.getKey()); pw.println(":");
   3376                     boolean apkActivity = false;
   3377                     Uid.Pkg ps = ent.getValue();
   3378                     int wakeups = ps.getWakeups(which);
   3379                     if (wakeups != 0) {
   3380                         pw.print(prefix); pw.print("      ");
   3381                                 pw.print(wakeups); pw.println(" wakeup alarms");
   3382                         apkActivity = true;
   3383                     }
   3384                     Map<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
   3385                     if (serviceStats.size() > 0) {
   3386                         for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
   3387                                 : serviceStats.entrySet()) {
   3388                             BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
   3389                             long startTime = ss.getStartTime(batteryUptime, which);
   3390                             int starts = ss.getStarts(which);
   3391                             int launches = ss.getLaunches(which);
   3392                             if (startTime != 0 || starts != 0 || launches != 0) {
   3393                                 sb.setLength(0);
   3394                                 sb.append(prefix); sb.append("      Service ");
   3395                                         sb.append(sent.getKey()); sb.append(":\n");
   3396                                 sb.append(prefix); sb.append("        Created for: ");
   3397                                         formatTimeMs(sb, startTime / 1000);
   3398                                         sb.append("uptime\n");
   3399                                 sb.append(prefix); sb.append("        Starts: ");
   3400                                         sb.append(starts);
   3401                                         sb.append(", launches: "); sb.append(launches);
   3402                                 pw.println(sb.toString());
   3403                                 apkActivity = true;
   3404                             }
   3405                         }
   3406                     }
   3407                     if (!apkActivity) {
   3408                         pw.print(prefix); pw.println("      (nothing executed)");
   3409                     }
   3410                     uidActivity = true;
   3411                 }
   3412             }
   3413             if (!uidActivity) {
   3414                 pw.print(prefix); pw.println("    (nothing executed)");
   3415             }
   3416         }
   3417     }
   3418 
   3419     static void printBitDescriptions(PrintWriter pw, int oldval, int newval, HistoryTag wakelockTag,
   3420             BitDescription[] descriptions, boolean longNames) {
   3421         int diff = oldval ^ newval;
   3422         if (diff == 0) return;
   3423         boolean didWake = false;
   3424         for (int i=0; i<descriptions.length; i++) {
   3425             BitDescription bd = descriptions[i];
   3426             if ((diff&bd.mask) != 0) {
   3427                 pw.print(longNames ? " " : ",");
   3428                 if (bd.shift < 0) {
   3429                     pw.print((newval&bd.mask) != 0 ? "+" : "-");
   3430                     pw.print(longNames ? bd.name : bd.shortName);
   3431                     if (bd.mask == HistoryItem.STATE_WAKE_LOCK_FLAG && wakelockTag != null) {
   3432                         didWake = true;
   3433                         pw.print("=");
   3434                         if (longNames) {
   3435                             UserHandle.formatUid(pw, wakelockTag.uid);
   3436                             pw.print(":\"");
   3437                             pw.print(wakelockTag.string);
   3438                             pw.print("\"");
   3439                         } else {
   3440                             pw.print(wakelockTag.poolIdx);
   3441                         }
   3442                     }
   3443                 } else {
   3444                     pw.print(longNames ? bd.name : bd.shortName);
   3445                     pw.print("=");
   3446                     int val = (newval&bd.mask)>>bd.shift;
   3447                     if (bd.values != null && val >= 0 && val < bd.values.length) {
   3448                         pw.print(longNames? bd.values[val] : bd.shortValues[val]);
   3449                     } else {
   3450                         pw.print(val);
   3451                     }
   3452                 }
   3453             }
   3454         }
   3455         if (!didWake && wakelockTag != null) {
   3456             pw.print(longNames ? " wake_lock=" : ",w=");
   3457             if (longNames) {
   3458                 UserHandle.formatUid(pw, wakelockTag.uid);
   3459                 pw.print(":\"");
   3460                 pw.print(wakelockTag.string);
   3461                 pw.print("\"");
   3462             } else {
   3463                 pw.print(wakelockTag.poolIdx);
   3464             }
   3465         }
   3466     }
   3467 
   3468     public void prepareForDumpLocked() {
   3469     }
   3470 
   3471     public static class HistoryPrinter {
   3472         int oldState = 0;
   3473         int oldState2 = 0;
   3474         int oldLevel = -1;
   3475         int oldStatus = -1;
   3476         int oldHealth = -1;
   3477         int oldPlug = -1;
   3478         int oldTemp = -1;
   3479         int oldVolt = -1;
   3480         long lastTime = -1;
   3481 
   3482         void reset() {
   3483             oldState = oldState2 = 0;
   3484             oldLevel = -1;
   3485             oldStatus = -1;
   3486             oldHealth = -1;
   3487             oldPlug = -1;
   3488             oldTemp = -1;
   3489             oldVolt = -1;
   3490         }
   3491 
   3492         public void printNextItem(PrintWriter pw, HistoryItem rec, long baseTime, boolean checkin,
   3493                 boolean verbose) {
   3494             if (!checkin) {
   3495                 pw.print("  ");
   3496                 TimeUtils.formatDuration(rec.time - baseTime, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
   3497                 pw.print(" (");
   3498                 pw.print(rec.numReadInts);
   3499                 pw.print(") ");
   3500             } else {
   3501                 pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
   3502                 pw.print(HISTORY_DATA); pw.print(',');
   3503                 if (lastTime < 0) {
   3504                     pw.print(rec.time - baseTime);
   3505                 } else {
   3506                     pw.print(rec.time - lastTime);
   3507                 }
   3508                 lastTime = rec.time;
   3509             }
   3510             if (rec.cmd == HistoryItem.CMD_START) {
   3511                 if (checkin) {
   3512                     pw.print(":");
   3513                 }
   3514                 pw.println("START");
   3515                 reset();
   3516             } else if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
   3517                     || rec.cmd == HistoryItem.CMD_RESET) {
   3518                 if (checkin) {
   3519                     pw.print(":");
   3520                 }
   3521                 if (rec.cmd == HistoryItem.CMD_RESET) {
   3522                     pw.print("RESET:");
   3523                     reset();
   3524                 }
   3525                 pw.print("TIME:");
   3526                 if (checkin) {
   3527                     pw.println(rec.currentTime);
   3528                 } else {
   3529                     pw.print(" ");
   3530                     pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
   3531                             rec.currentTime).toString());
   3532                 }
   3533             } else if (rec.cmd == HistoryItem.CMD_SHUTDOWN) {
   3534                 if (checkin) {
   3535                     pw.print(":");
   3536                 }
   3537                 pw.println("SHUTDOWN");
   3538             } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
   3539                 if (checkin) {
   3540                     pw.print(":");
   3541                 }
   3542                 pw.println("*OVERFLOW*");
   3543             } else {
   3544                 if (!checkin) {
   3545                     if (rec.batteryLevel < 10) pw.print("00");
   3546                     else if (rec.batteryLevel < 100) pw.print("0");
   3547                     pw.print(rec.batteryLevel);
   3548                     if (verbose) {
   3549                         pw.print(" ");
   3550                         if (rec.states < 0) ;
   3551                         else if (rec.states < 0x10) pw.print("0000000");
   3552                         else if (rec.states < 0x100) pw.print("000000");
   3553                         else if (rec.states < 0x1000) pw.print("00000");
   3554                         else if (rec.states < 0x10000) pw.print("0000");
   3555                         else if (rec.states < 0x100000) pw.print("000");
   3556                         else if (rec.states < 0x1000000) pw.print("00");
   3557                         else if (rec.states < 0x10000000) pw.print("0");
   3558                         pw.print(Integer.toHexString(rec.states));
   3559                     }
   3560                 } else {
   3561                     if (oldLevel != rec.batteryLevel) {
   3562                         oldLevel = rec.batteryLevel;
   3563                         pw.print(",Bl="); pw.print(rec.batteryLevel);
   3564                     }
   3565                 }
   3566                 if (oldStatus != rec.batteryStatus) {
   3567                     oldStatus = rec.batteryStatus;
   3568                     pw.print(checkin ? ",Bs=" : " status=");
   3569                     switch (oldStatus) {
   3570                         case BatteryManager.BATTERY_STATUS_UNKNOWN:
   3571                             pw.print(checkin ? "?" : "unknown");
   3572                             break;
   3573                         case BatteryManager.BATTERY_STATUS_CHARGING:
   3574                             pw.print(checkin ? "c" : "charging");
   3575                             break;
   3576                         case BatteryManager.BATTERY_STATUS_DISCHARGING:
   3577                             pw.print(checkin ? "d" : "discharging");
   3578                             break;
   3579                         case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
   3580                             pw.print(checkin ? "n" : "not-charging");
   3581                             break;
   3582                         case BatteryManager.BATTERY_STATUS_FULL:
   3583                             pw.print(checkin ? "f" : "full");
   3584                             break;
   3585                         default:
   3586                             pw.print(oldStatus);
   3587                             break;
   3588                     }
   3589                 }
   3590                 if (oldHealth != rec.batteryHealth) {
   3591                     oldHealth = rec.batteryHealth;
   3592                     pw.print(checkin ? ",Bh=" : " health=");
   3593                     switch (oldHealth) {
   3594                         case BatteryManager.BATTERY_HEALTH_UNKNOWN:
   3595                             pw.print(checkin ? "?" : "unknown");
   3596                             break;
   3597                         case BatteryManager.BATTERY_HEALTH_GOOD:
   3598                             pw.print(checkin ? "g" : "good");
   3599                             break;
   3600                         case BatteryManager.BATTERY_HEALTH_OVERHEAT:
   3601                             pw.print(checkin ? "h" : "overheat");
   3602                             break;
   3603                         case BatteryManager.BATTERY_HEALTH_DEAD:
   3604                             pw.print(checkin ? "d" : "dead");
   3605                             break;
   3606                         case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
   3607                             pw.print(checkin ? "v" : "over-voltage");
   3608                             break;
   3609                         case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
   3610                             pw.print(checkin ? "f" : "failure");
   3611                             break;
   3612                         case BatteryManager.BATTERY_HEALTH_COLD:
   3613                             pw.print(checkin ? "c" : "cold");
   3614                             break;
   3615                         default:
   3616                             pw.print(oldHealth);
   3617                             break;
   3618                     }
   3619                 }
   3620                 if (oldPlug != rec.batteryPlugType) {
   3621                     oldPlug = rec.batteryPlugType;
   3622                     pw.print(checkin ? ",Bp=" : " plug=");
   3623                     switch (oldPlug) {
   3624                         case 0:
   3625                             pw.print(checkin ? "n" : "none");
   3626                             break;
   3627                         case BatteryManager.BATTERY_PLUGGED_AC:
   3628                             pw.print(checkin ? "a" : "ac");
   3629                             break;
   3630                         case BatteryManager.BATTERY_PLUGGED_USB:
   3631                             pw.print(checkin ? "u" : "usb");
   3632                             break;
   3633                         case BatteryManager.BATTERY_PLUGGED_WIRELESS:
   3634                             pw.print(checkin ? "w" : "wireless");
   3635                             break;
   3636                         default:
   3637                             pw.print(oldPlug);
   3638                             break;
   3639                     }
   3640                 }
   3641                 if (oldTemp != rec.batteryTemperature) {
   3642                     oldTemp = rec.batteryTemperature;
   3643                     pw.print(checkin ? ",Bt=" : " temp=");
   3644                     pw.print(oldTemp);
   3645                 }
   3646                 if (oldVolt != rec.batteryVoltage) {
   3647                     oldVolt = rec.batteryVoltage;
   3648                     pw.print(checkin ? ",Bv=" : " volt=");
   3649                     pw.print(oldVolt);
   3650                 }
   3651                 printBitDescriptions(pw, oldState, rec.states, rec.wakelockTag,
   3652                         HISTORY_STATE_DESCRIPTIONS, !checkin);
   3653                 printBitDescriptions(pw, oldState2, rec.states2, null,
   3654                         HISTORY_STATE2_DESCRIPTIONS, !checkin);
   3655                 if (rec.wakeReasonTag != null) {
   3656                     if (checkin) {
   3657                         pw.print(",wr=");
   3658                         pw.print(rec.wakeReasonTag.poolIdx);
   3659                     } else {
   3660                         pw.print(" wake_reason=");
   3661                         pw.print(rec.wakeReasonTag.uid);
   3662                         pw.print(":\"");
   3663                         pw.print(rec.wakeReasonTag.string);
   3664                         pw.print("\"");
   3665                     }
   3666                 }
   3667                 if (rec.eventCode != HistoryItem.EVENT_NONE) {
   3668                     pw.print(checkin ? "," : " ");
   3669                     if ((rec.eventCode&HistoryItem.EVENT_FLAG_START) != 0) {
   3670                         pw.print("+");
   3671                     } else if ((rec.eventCode&HistoryItem.EVENT_FLAG_FINISH) != 0) {
   3672                         pw.print("-");
   3673                     }
   3674                     String[] eventNames = checkin ? HISTORY_EVENT_CHECKIN_NAMES
   3675                             : HISTORY_EVENT_NAMES;
   3676                     int idx = rec.eventCode & ~(HistoryItem.EVENT_FLAG_START
   3677                             | HistoryItem.EVENT_FLAG_FINISH);
   3678                     if (idx >= 0 && idx < eventNames.length) {
   3679                         pw.print(eventNames[idx]);
   3680                     } else {
   3681                         pw.print(checkin ? "Ev" : "event");
   3682                         pw.print(idx);
   3683                     }
   3684                     pw.print("=");
   3685                     if (checkin) {
   3686                         pw.print(rec.eventTag.poolIdx);
   3687                     } else {
   3688                         UserHandle.formatUid(pw, rec.eventTag.uid);
   3689                         pw.print(":\"");
   3690                         pw.print(rec.eventTag.string);
   3691                         pw.print("\"");
   3692                     }
   3693                 }
   3694                 pw.println();
   3695                 oldState = rec.states;
   3696                 oldState2 = rec.states2;
   3697             }
   3698         }
   3699     }
   3700 
   3701     private void printSizeValue(PrintWriter pw, long size) {
   3702         float result = size;
   3703         String suffix = "";
   3704         if (result >= 10*1024) {
   3705             suffix = "KB";
   3706             result = result / 1024;
   3707         }
   3708         if (result >= 10*1024) {
   3709             suffix = "MB";
   3710             result = result / 1024;
   3711         }
   3712         if (result >= 10*1024) {
   3713             suffix = "GB";
   3714             result = result / 1024;
   3715         }
   3716         if (result >= 10*1024) {
   3717             suffix = "TB";
   3718             result = result / 1024;
   3719         }
   3720         if (result >= 10*1024) {
   3721             suffix = "PB";
   3722             result = result / 1024;
   3723         }
   3724         pw.print((int)result);
   3725         pw.print(suffix);
   3726     }
   3727 
   3728     private static boolean dumpTimeEstimate(PrintWriter pw, String label, long[] steps,
   3729             int count, long modesOfInterest, long modeValues) {
   3730         if (count <= 0) {
   3731             return false;
   3732         }
   3733         long total = 0;
   3734         int numOfInterest = 0;
   3735         for (int i=0; i<count; i++) {
   3736             long initMode = (steps[i] & STEP_LEVEL_INITIAL_MODE_MASK)
   3737                     >> STEP_LEVEL_INITIAL_MODE_SHIFT;
   3738             long modMode = (steps[i] & STEP_LEVEL_MODIFIED_MODE_MASK)
   3739                     >> STEP_LEVEL_MODIFIED_MODE_SHIFT;
   3740             // If the modes of interest didn't change during this step period...
   3741             if ((modMode&modesOfInterest) == 0) {
   3742                 // And the mode values during this period match those we are measuring...
   3743                 if ((initMode&modesOfInterest) == modeValues) {
   3744                     // Then this can be used to estimate the total time!
   3745                     numOfInterest++;
   3746                     total += steps[i] & STEP_LEVEL_TIME_MASK;
   3747                 }
   3748             }
   3749         }
   3750         if (numOfInterest <= 0) {
   3751             return false;
   3752         }
   3753 
   3754         // The estimated time is the average time we spend in each level, multipled
   3755         // by 100 -- the total number of battery levels
   3756         long estimatedTime = (total / numOfInterest) * 100;
   3757 
   3758         pw.print(label);
   3759         StringBuilder sb = new StringBuilder(64);
   3760         formatTimeMs(sb, estimatedTime);
   3761         pw.print(sb);
   3762         pw.println();
   3763 
   3764         return true;
   3765     }
   3766 
   3767     private static boolean dumpDurationSteps(PrintWriter pw, String header, long[] steps,
   3768             int count, boolean checkin) {
   3769         if (count <= 0) {
   3770             return false;
   3771         }
   3772         if (!checkin) {
   3773             pw.println(header);
   3774         }
   3775         String[] lineArgs = new String[4];
   3776         for (int i=0; i<count; i++) {
   3777             long duration = steps[i] & STEP_LEVEL_TIME_MASK;
   3778             int level = (int)((steps[i] & STEP_LEVEL_LEVEL_MASK)
   3779                     >> STEP_LEVEL_LEVEL_SHIFT);
   3780             long initMode = (steps[i] & STEP_LEVEL_INITIAL_MODE_MASK)
   3781                     >> STEP_LEVEL_INITIAL_MODE_SHIFT;
   3782             long modMode = (steps[i] & STEP_LEVEL_MODIFIED_MODE_MASK)
   3783                     >> STEP_LEVEL_MODIFIED_MODE_SHIFT;
   3784             if (checkin) {
   3785                 lineArgs[0] = Long.toString(duration);
   3786                 lineArgs[1] = Integer.toString(level);
   3787                 if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
   3788                     switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
   3789                         case Display.STATE_OFF: lineArgs[2] = "s-"; break;
   3790                         case Display.STATE_ON: lineArgs[2] = "s+"; break;
   3791                         case Display.STATE_DOZE: lineArgs[2] = "sd"; break;
   3792                         case Display.STATE_DOZE_SUSPEND: lineArgs[2] = "sds"; break;
   3793                         default: lineArgs[1] = "?"; break;
   3794                     }
   3795                 } else {
   3796                     lineArgs[2] = "";
   3797                 }
   3798                 if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) {
   3799                     lineArgs[3] = (initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0 ? "p+" : "p-";
   3800                 } else {
   3801                     lineArgs[3] = "";
   3802                 }
   3803                 dumpLine(pw, 0 /* uid */, "i" /* category */, header, (Object[])lineArgs);
   3804             } else {
   3805                 pw.print("  #"); pw.print(i); pw.print(": ");
   3806                 TimeUtils.formatDuration(duration, pw);
   3807                 pw.print(" to "); pw.print(level);
   3808                 boolean haveModes = false;
   3809                 if ((modMode&STEP_LEVEL_MODE_SCREEN_STATE) == 0) {
   3810                     pw.print(" (");
   3811                     switch ((int)(initMode&STEP_LEVEL_MODE_SCREEN_STATE) + 1) {
   3812                         case Display.STATE_OFF: pw.print("screen-off"); break;
   3813                         case Display.STATE_ON: pw.print("screen-on"); break;
   3814                         case Display.STATE_DOZE: pw.print("screen-doze"); break;
   3815                         case Display.STATE_DOZE_SUSPEND: pw.print("screen-doze-suspend"); break;
   3816                         default: lineArgs[1] = "screen-?"; break;
   3817                     }
   3818                     haveModes = true;
   3819                 }
   3820                 if ((modMode&STEP_LEVEL_MODE_POWER_SAVE) == 0) {
   3821                     pw.print(haveModes ? ", " : " (");
   3822                     pw.print((initMode&STEP_LEVEL_MODE_POWER_SAVE) != 0
   3823                             ? "power-save-on" : "power-save-off");
   3824                     haveModes = true;
   3825                 }
   3826                 if (haveModes) {
   3827                     pw.print(")");
   3828                 }
   3829                 pw.println();
   3830             }
   3831         }
   3832         return true;
   3833     }
   3834 
   3835     public static final int DUMP_UNPLUGGED_ONLY = 1<<0;
   3836     public static final int DUMP_CHARGED_ONLY = 1<<1;
   3837     public static final int DUMP_HISTORY_ONLY = 1<<2;
   3838     public static final int DUMP_INCLUDE_HISTORY = 1<<3;
   3839     public static final int DUMP_VERBOSE = 1<<4;
   3840     public static final int DUMP_DEVICE_WIFI_ONLY = 1<<5;
   3841 
   3842     private void dumpHistoryLocked(PrintWriter pw, int flags, long histStart, boolean checkin) {
   3843         final HistoryPrinter hprinter = new HistoryPrinter();
   3844         final HistoryItem rec = new HistoryItem();
   3845         long lastTime = -1;
   3846         long baseTime = -1;
   3847         boolean printed = false;
   3848         HistoryEventTracker tracker = null;
   3849         while (getNextHistoryLocked(rec)) {
   3850             lastTime = rec.time;
   3851             if (baseTime < 0) {
   3852                 baseTime = lastTime;
   3853             }
   3854             if (rec.time >= histStart) {
   3855                 if (histStart >= 0 && !printed) {
   3856                     if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
   3857                             || rec.cmd == HistoryItem.CMD_RESET
   3858                             || rec.cmd == HistoryItem.CMD_START
   3859                             || rec.cmd == HistoryItem.CMD_SHUTDOWN) {
   3860                         printed = true;
   3861                         hprinter.printNextItem(pw, rec, baseTime, checkin,
   3862                                 (flags&DUMP_VERBOSE) != 0);
   3863                         rec.cmd = HistoryItem.CMD_UPDATE;
   3864                     } else if (rec.currentTime != 0) {
   3865                         printed = true;
   3866                         byte cmd = rec.cmd;
   3867                         rec.cmd = HistoryItem.CMD_CURRENT_TIME;
   3868                         hprinter.printNextItem(pw, rec, baseTime, checkin,
   3869                                 (flags&DUMP_VERBOSE) != 0);
   3870                         rec.cmd = cmd;
   3871                     }
   3872                     if (tracker != null) {
   3873                         if (rec.cmd != HistoryItem.CMD_UPDATE) {
   3874                             hprinter.printNextItem(pw, rec, baseTime, checkin,
   3875                                     (flags&DUMP_VERBOSE) != 0);
   3876                             rec.cmd = HistoryItem.CMD_UPDATE;
   3877                         }
   3878                         int oldEventCode = rec.eventCode;
   3879                         HistoryTag oldEventTag = rec.eventTag;
   3880                         rec.eventTag = new HistoryTag();
   3881                         for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
   3882                             HashMap<String, SparseIntArray> active
   3883                                     = tracker.getStateForEvent(i);
   3884                             if (active == null) {
   3885                                 continue;
   3886                             }
   3887                             for (HashMap.Entry<String, SparseIntArray> ent
   3888                                     : active.entrySet()) {
   3889                                 SparseIntArray uids = ent.getValue();
   3890                                 for (int j=0; j<uids.size(); j++) {
   3891                                     rec.eventCode = i;
   3892                                     rec.eventTag.string = ent.getKey();
   3893                                     rec.eventTag.uid = uids.keyAt(j);
   3894                                     rec.eventTag.poolIdx = uids.valueAt(j);
   3895                                     hprinter.printNextItem(pw, rec, baseTime, checkin,
   3896                                             (flags&DUMP_VERBOSE) != 0);
   3897                                     rec.wakeReasonTag = null;
   3898                                     rec.wakelockTag = null;
   3899                                 }
   3900                             }
   3901                         }
   3902                         rec.eventCode = oldEventCode;
   3903                         rec.eventTag = oldEventTag;
   3904                         tracker = null;
   3905                     }
   3906                 }
   3907                 hprinter.printNextItem(pw, rec, baseTime, checkin,
   3908                         (flags&DUMP_VERBOSE) != 0);
   3909             } else if (false && rec.eventCode != HistoryItem.EVENT_NONE) {
   3910                 // This is an attempt to aggregate the previous state and generate
   3911                 //fake events to reflect that state at the point where we start
   3912                 // printing real events.  It doesn't really work right, so is turned off.
   3913                 if (tracker == null) {
   3914                     tracker = new HistoryEventTracker();
   3915                 }
   3916                 tracker.updateState(rec.eventCode, rec.eventTag.string,
   3917                         rec.eventTag.uid, rec.eventTag.poolIdx);
   3918             }
   3919         }
   3920         if (histStart >= 0) {
   3921             commitCurrentHistoryBatchLocked();
   3922             pw.print(checkin ? "NEXT: " : "  NEXT: "); pw.println(lastTime+1);
   3923         }
   3924     }
   3925 
   3926     /**
   3927      * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
   3928      *
   3929      * @param pw a Printer to receive the dump output.
   3930      */
   3931     @SuppressWarnings("unused")
   3932     public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
   3933         prepareForDumpLocked();
   3934 
   3935         final boolean filtering =
   3936                 (flags&(DUMP_HISTORY_ONLY|DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) != 0;
   3937 
   3938         if ((flags&DUMP_HISTORY_ONLY) != 0 || !filtering) {
   3939             final long historyTotalSize = getHistoryTotalSize();
   3940             final long historyUsedSize = getHistoryUsedSize();
   3941             if (startIteratingHistoryLocked()) {
   3942                 try {
   3943                     pw.print("Battery History (");
   3944                     pw.print((100*historyUsedSize)/historyTotalSize);
   3945                     pw.print("% used, ");
   3946                     printSizeValue(pw, historyUsedSize);
   3947                     pw.print(" used of ");
   3948                     printSizeValue(pw, historyTotalSize);
   3949                     pw.print(", ");
   3950                     pw.print(getHistoryStringPoolSize());
   3951                     pw.print(" strings using ");
   3952                     printSizeValue(pw, getHistoryStringPoolBytes());
   3953                     pw.println("):");
   3954                     dumpHistoryLocked(pw, flags, histStart, false);
   3955                     pw.println();
   3956                 } finally {
   3957                     finishIteratingHistoryLocked();
   3958                 }
   3959             }
   3960 
   3961             if (startIteratingOldHistoryLocked()) {
   3962                 try {
   3963                     final HistoryItem rec = new HistoryItem();
   3964                     pw.println("Old battery History:");
   3965                     HistoryPrinter hprinter = new HistoryPrinter();
   3966                     long baseTime = -1;
   3967                     while (getNextOldHistoryLocked(rec)) {
   3968                         if (baseTime < 0) {
   3969                             baseTime = rec.time;
   3970                         }
   3971                         hprinter.printNextItem(pw, rec, baseTime, false, (flags&DUMP_VERBOSE) != 0);
   3972                     }
   3973                     pw.println();
   3974                 } finally {
   3975                     finishIteratingOldHistoryLocked();
   3976                 }
   3977             }
   3978         }
   3979 
   3980         if (filtering && (flags&(DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) == 0) {
   3981             return;
   3982         }
   3983 
   3984         if (!filtering) {
   3985             SparseArray<? extends Uid> uidStats = getUidStats();
   3986             final int NU = uidStats.size();
   3987             boolean didPid = false;
   3988             long nowRealtime = SystemClock.elapsedRealtime();
   3989             for (int i=0; i<NU; i++) {
   3990                 Uid uid = uidStats.valueAt(i);
   3991                 SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
   3992                 if (pids != null) {
   3993                     for (int j=0; j<pids.size(); j++) {
   3994                         Uid.Pid pid = pids.valueAt(j);
   3995                         if (!didPid) {
   3996                             pw.println("Per-PID Stats:");
   3997                             didPid = true;
   3998                         }
   3999                         long time = pid.mWakeSumMs + (pid.mWakeNesting > 0
   4000                                 ? (nowRealtime - pid.mWakeStartMs) : 0);
   4001                         pw.print("  PID "); pw.print(pids.keyAt(j));
   4002                                 pw.print(" wake time: ");
   4003                                 TimeUtils.formatDuration(time, pw);
   4004                                 pw.println("");
   4005                     }
   4006                 }
   4007             }
   4008             if (didPid) {
   4009                 pw.println();
   4010             }
   4011         }
   4012 
   4013         if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
   4014             if (dumpDurationSteps(pw, "Discharge step durations:", getDischargeStepDurationsArray(),
   4015                     getNumDischargeStepDurations(), false)) {
   4016                 long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
   4017                 if (timeRemaining >= 0) {
   4018                     pw.print("  Estimated discharge time remaining: ");
   4019                     TimeUtils.formatDuration(timeRemaining / 1000, pw);
   4020                     pw.println();
   4021                 }
   4022                 dumpTimeEstimate(pw, "  Estimated screen off time: ",
   4023                         getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
   4024                         STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
   4025                         (Display.STATE_OFF-1));
   4026                 dumpTimeEstimate(pw, "  Estimated screen off power save time: ",
   4027                         getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
   4028                         STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
   4029                         (Display.STATE_OFF-1)|STEP_LEVEL_MODE_POWER_SAVE);
   4030                 dumpTimeEstimate(pw, "  Estimated screen on time: ",
   4031                         getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
   4032                         STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
   4033                         (Display.STATE_ON-1));
   4034                 dumpTimeEstimate(pw, "  Estimated screen on power save time: ",
   4035                         getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
   4036                         STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
   4037                         (Display.STATE_ON-1)|STEP_LEVEL_MODE_POWER_SAVE);
   4038                 dumpTimeEstimate(pw, "  Estimated screen doze time: ",
   4039                         getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
   4040                         STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
   4041                         (Display.STATE_DOZE-1));
   4042                 dumpTimeEstimate(pw, "  Estimated screen doze power save time: ",
   4043                         getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
   4044                         STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
   4045                         (Display.STATE_DOZE-1)|STEP_LEVEL_MODE_POWER_SAVE);
   4046                 dumpTimeEstimate(pw, "  Estimated screen doze suspend time: ",
   4047                         getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
   4048                         STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
   4049                         (Display.STATE_DOZE_SUSPEND-1));
   4050                 dumpTimeEstimate(pw, "  Estimated screen doze suspend power save time: ",
   4051                         getDischargeStepDurationsArray(), getNumDischargeStepDurations(),
   4052                         STEP_LEVEL_MODE_SCREEN_STATE|STEP_LEVEL_MODE_POWER_SAVE,
   4053                         (Display.STATE_DOZE_SUSPEND-1)|STEP_LEVEL_MODE_POWER_SAVE);
   4054                 pw.println();
   4055             }
   4056             if (dumpDurationSteps(pw, "Charge step durations:", getChargeStepDurationsArray(),
   4057                     getNumChargeStepDurations(), false)) {
   4058                 long timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime());
   4059                 if (timeRemaining >= 0) {
   4060                     pw.print("  Estimated charge time remaining: ");
   4061                     TimeUtils.formatDuration(timeRemaining / 1000, pw);
   4062                     pw.println();
   4063                 }
   4064                 pw.println();
   4065             }
   4066             pw.println("Statistics since last charge:");
   4067             pw.println("  System starts: " + getStartCount()
   4068                     + ", currently on battery: " + getIsOnBattery());
   4069             dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid,
   4070                     (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
   4071             pw.println();
   4072         }
   4073         if (!filtering || (flags&DUMP_UNPLUGGED_ONLY) != 0) {
   4074             pw.println("Statistics since last unplugged:");
   4075             dumpLocked(context, pw, "", STATS_SINCE_UNPLUGGED, reqUid,
   4076                     (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
   4077         }
   4078     }
   4079 
   4080     @SuppressWarnings("unused")
   4081     public void dumpCheckinLocked(Context context, PrintWriter pw,
   4082             List<ApplicationInfo> apps, int flags, long histStart) {
   4083         prepareForDumpLocked();
   4084 
   4085         dumpLine(pw, 0 /* uid */, "i" /* category */, VERSION_DATA,
   4086                 "12", getParcelVersion(), getStartPlatformVersion(), getEndPlatformVersion());
   4087 
   4088         long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
   4089 
   4090         final boolean filtering =
   4091                 (flags&(DUMP_HISTORY_ONLY|DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) != 0;
   4092 
   4093         if ((flags&DUMP_INCLUDE_HISTORY) != 0 || (flags&DUMP_HISTORY_ONLY) != 0) {
   4094             if (startIteratingHistoryLocked()) {
   4095                 try {
   4096                     for (int i=0; i<getHistoryStringPoolSize(); i++) {
   4097                         pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
   4098                         pw.print(HISTORY_STRING_POOL); pw.print(',');
   4099                         pw.print(i);
   4100                         pw.print(",");
   4101                         pw.print(getHistoryTagPoolUid(i));
   4102                         pw.print(",\"");
   4103                         String str = getHistoryTagPoolString(i);
   4104                         str = str.replace("\\", "\\\\");
   4105                         str = str.replace("\"", "\\\"");
   4106                         pw.print(str);
   4107                         pw.print("\"");
   4108                         pw.println();
   4109                     }
   4110                     dumpHistoryLocked(pw, flags, histStart, true);
   4111                 } finally {
   4112                     finishIteratingHistoryLocked();
   4113                 }
   4114             }
   4115         }
   4116 
   4117         if (filtering && (flags&(DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) == 0) {
   4118             return;
   4119         }
   4120 
   4121         if (apps != null) {
   4122             SparseArray<ArrayList<String>> uids = new SparseArray<ArrayList<String>>();
   4123             for (int i=0; i<apps.size(); i++) {
   4124                 ApplicationInfo ai = apps.get(i);
   4125                 ArrayList<String> pkgs = uids.get(ai.uid);
   4126                 if (pkgs == null) {
   4127                     pkgs = new ArrayList<String>();
   4128                     uids.put(ai.uid, pkgs);
   4129                 }
   4130                 pkgs.add(ai.packageName);
   4131             }
   4132             SparseArray<? extends Uid> uidStats = getUidStats();
   4133             final int NU = uidStats.size();
   4134             String[] lineArgs = new String[2];
   4135             for (int i=0; i<NU; i++) {
   4136                 int uid = uidStats.keyAt(i);
   4137                 ArrayList<String> pkgs = uids.get(uid);
   4138                 if (pkgs != null) {
   4139                     for (int j=0; j<pkgs.size(); j++) {
   4140                         lineArgs[0] = Integer.toString(uid);
   4141                         lineArgs[1] = pkgs.get(j);
   4142                         dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA,
   4143                                 (Object[])lineArgs);
   4144                     }
   4145                 }
   4146             }
   4147         }
   4148         if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
   4149             dumpDurationSteps(pw, DISCHARGE_STEP_DATA, getDischargeStepDurationsArray(),
   4150                     getNumDischargeStepDurations(), true);
   4151             String[] lineArgs = new String[1];
   4152             long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
   4153             if (timeRemaining >= 0) {
   4154                 lineArgs[0] = Long.toString(timeRemaining);
   4155                 dumpLine(pw, 0 /* uid */, "i" /* category */, DISCHARGE_TIME_REMAIN_DATA,
   4156                         (Object[])lineArgs);
   4157             }
   4158             dumpDurationSteps(pw, CHARGE_STEP_DATA, getChargeStepDurationsArray(),
   4159                     getNumChargeStepDurations(), true);
   4160             timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime());
   4161             if (timeRemaining >= 0) {
   4162                 lineArgs[0] = Long.toString(timeRemaining);
   4163                 dumpLine(pw, 0 /* uid */, "i" /* category */, CHARGE_TIME_REMAIN_DATA,
   4164                         (Object[])lineArgs);
   4165             }
   4166             dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1,
   4167                     (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
   4168         }
   4169         if (!filtering || (flags&DUMP_UNPLUGGED_ONLY) != 0) {
   4170             dumpCheckinLocked(context, pw, STATS_SINCE_UNPLUGGED, -1,
   4171                     (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
   4172         }
   4173     }
   4174 }
   4175