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