Home | History | Annotate | Download | only in am
      1 /*
      2  * Copyright (C) 2016 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 com.android.server.am;
     18 
     19 import android.os.BatteryStats;
     20 import static android.os.BatteryStats.STATS_SINCE_UNPLUGGED;
     21 import android.os.PowerManager;
     22 import android.os.SystemClock;
     23 import android.os.health.HealthKeys;
     24 import android.os.health.HealthStatsParceler;
     25 import android.os.health.HealthStatsWriter;
     26 import android.os.health.PackageHealthStats;
     27 import android.os.health.ProcessHealthStats;
     28 import android.os.health.PidHealthStats;
     29 import android.os.health.ServiceHealthStats;
     30 import android.os.health.TimerStat;
     31 import android.os.health.UidHealthStats;
     32 import android.util.SparseArray;
     33 
     34 import java.util.Map;
     35 
     36 public class HealthStatsBatteryStatsWriter {
     37 
     38     private final long mNowRealtimeMs;
     39     private final long mNowUptimeMs;
     40 
     41     public HealthStatsBatteryStatsWriter() {
     42         mNowRealtimeMs = SystemClock.elapsedRealtime();
     43         mNowUptimeMs = SystemClock.uptimeMillis();
     44     }
     45 
     46     /**
     47      * Writes the contents of a BatteryStats.Uid into a HealthStatsWriter.
     48      */
     49     @SuppressWarnings("deprecation")
     50     public void writeUid(HealthStatsWriter uidWriter, BatteryStats bs, BatteryStats.Uid uid) {
     51         int N;
     52         BatteryStats.Timer timer;
     53         SparseArray<? extends BatteryStats.Uid.Sensor> sensors;
     54         SparseArray<? extends BatteryStats.Uid.Pid> pids;
     55         BatteryStats.ControllerActivityCounter controller;
     56         long sum;
     57 
     58         //
     59         // It's a little odd for these first four to be here but it's not the end of the
     60         // world. It would be easy enough to duplicate them somewhere else if this API
     61         // grows.
     62         //
     63 
     64         // MEASUREMENT_REALTIME_BATTERY_MS
     65         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_REALTIME_BATTERY_MS,
     66                 bs.computeBatteryRealtime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
     67 
     68         // MEASUREMENT_UPTIME_BATTERY_MS
     69         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_UPTIME_BATTERY_MS,
     70                 bs.computeBatteryUptime(mNowUptimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
     71 
     72         // MEASUREMENT_REALTIME_SCREEN_OFF_BATTERY_MS
     73         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_REALTIME_SCREEN_OFF_BATTERY_MS,
     74                 bs.computeBatteryScreenOffRealtime(
     75                     mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
     76 
     77         // MEASUREMENT_UPTIME_SCREEN_OFF_BATTERY_MS
     78         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_UPTIME_SCREEN_OFF_BATTERY_MS,
     79                 bs.computeBatteryScreenOffUptime(mNowUptimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
     80 
     81         //
     82         // Now on to the real per-uid stats...
     83         //
     84 
     85         for (final Map.Entry<String,? extends BatteryStats.Uid.Wakelock> entry:
     86                 uid.getWakelockStats().entrySet()) {
     87             final String key = entry.getKey();
     88             final BatteryStats.Uid.Wakelock wakelock = entry.getValue();
     89 
     90             // TIMERS_WAKELOCKS_FULL
     91             timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_FULL);
     92             addTimers(uidWriter, UidHealthStats.TIMERS_WAKELOCKS_FULL, key, timer);
     93 
     94             // TIMERS_WAKELOCKS_PARTIAL
     95             timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL);
     96             addTimers(uidWriter, UidHealthStats.TIMERS_WAKELOCKS_PARTIAL, key, timer);
     97 
     98             // TIMERS_WAKELOCKS_WINDOW
     99             timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_WINDOW);
    100             addTimers(uidWriter, UidHealthStats.TIMERS_WAKELOCKS_WINDOW, key, timer);
    101 
    102             // TIMERS_WAKELOCKS_DRAW
    103             timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_DRAW);
    104             addTimers(uidWriter, UidHealthStats.TIMERS_WAKELOCKS_DRAW, key, timer);
    105         }
    106 
    107         // TIMERS_SYNCS
    108         for (final Map.Entry<String,? extends BatteryStats.Timer> entry:
    109                 uid.getSyncStats().entrySet()) {
    110             addTimers(uidWriter, UidHealthStats.TIMERS_SYNCS, entry.getKey(), entry.getValue());
    111         }
    112 
    113         // TIMERS_JOBS
    114         for (final Map.Entry<String,? extends BatteryStats.Timer> entry:
    115                 uid.getJobStats().entrySet()) {
    116             addTimers(uidWriter, UidHealthStats.TIMERS_JOBS, entry.getKey(), entry.getValue());
    117         }
    118 
    119         // TIMERS_SENSORS
    120         sensors = uid.getSensorStats();
    121         N = sensors.size();
    122         for (int i=0; i<N; i++) {
    123             int sensorId = sensors.keyAt(i);
    124             // Battery Stats stores the GPS sensors with a bogus key in this API. Pull it out
    125             // as a separate metric here so as to not expose that in the API.
    126             if (sensorId == BatteryStats.Uid.Sensor.GPS) {
    127                 addTimer(uidWriter, UidHealthStats.TIMER_GPS_SENSOR,
    128                         sensors.valueAt(i).getSensorTime());
    129             } else {
    130                 addTimers(uidWriter, UidHealthStats.TIMERS_SENSORS, Integer.toString(sensorId),
    131                         sensors.valueAt(i).getSensorTime());
    132             }
    133         }
    134 
    135         // STATS_PIDS
    136         pids = uid.getPidStats();
    137         N = pids.size();
    138         for (int i=0; i<N; i++) {
    139             final HealthStatsWriter writer = new HealthStatsWriter(PidHealthStats.CONSTANTS);
    140             writePid(writer, pids.valueAt(i));
    141             uidWriter.addStats(UidHealthStats.STATS_PIDS, Integer.toString(pids.keyAt(i)), writer);
    142         }
    143 
    144         // STATS_PROCESSES
    145         for (final Map.Entry<String,? extends BatteryStats.Uid.Proc> entry:
    146                 uid.getProcessStats().entrySet()) {
    147             final HealthStatsWriter writer = new HealthStatsWriter(ProcessHealthStats.CONSTANTS);
    148             writeProc(writer, entry.getValue());
    149             uidWriter.addStats(UidHealthStats.STATS_PROCESSES, entry.getKey(), writer);
    150         }
    151 
    152         // STATS_PACKAGES
    153         for (final Map.Entry<String,? extends BatteryStats.Uid.Pkg> entry:
    154                 uid.getPackageStats().entrySet()) {
    155             final HealthStatsWriter writer = new HealthStatsWriter(PackageHealthStats.CONSTANTS);
    156             writePkg(writer, entry.getValue());
    157             uidWriter.addStats(UidHealthStats.STATS_PACKAGES, entry.getKey(), writer);
    158         }
    159 
    160         controller = uid.getWifiControllerActivity();
    161         if (controller != null) {
    162             // MEASUREMENT_WIFI_IDLE_MS
    163             uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_IDLE_MS,
    164                     controller.getIdleTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
    165             // MEASUREMENT_WIFI_RX_MS
    166             uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_RX_MS,
    167                     controller.getRxTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
    168             // MEASUREMENT_WIFI_TX_MS
    169             sum = 0;
    170             for (final BatteryStats.LongCounter counter: controller.getTxTimeCounters()) {
    171                 sum += counter.getCountLocked(STATS_SINCE_UNPLUGGED);
    172             }
    173             uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_TX_MS, sum);
    174             // MEASUREMENT_WIFI_POWER_MAMS
    175             uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_POWER_MAMS,
    176                     controller.getPowerCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
    177         }
    178 
    179         controller = uid.getBluetoothControllerActivity();
    180         if (controller != null) {
    181             // MEASUREMENT_BLUETOOTH_IDLE_MS
    182             uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_IDLE_MS,
    183                     controller.getIdleTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
    184             // MEASUREMENT_BLUETOOTH_RX_MS
    185             uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_RX_MS,
    186                     controller.getRxTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
    187             // MEASUREMENT_BLUETOOTH_TX_MS
    188             sum = 0;
    189             for (final BatteryStats.LongCounter counter: controller.getTxTimeCounters()) {
    190                 sum += counter.getCountLocked(STATS_SINCE_UNPLUGGED);
    191             }
    192             uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_TX_MS, sum);
    193             // MEASUREMENT_BLUETOOTH_POWER_MAMS
    194             uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_POWER_MAMS,
    195                     controller.getPowerCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
    196         }
    197 
    198         controller = uid.getModemControllerActivity();
    199         if (controller != null) {
    200             // MEASUREMENT_MOBILE_IDLE_MS
    201             uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_IDLE_MS,
    202                     controller.getIdleTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
    203             // MEASUREMENT_MOBILE_RX_MS
    204             uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_RX_MS,
    205                     controller.getRxTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
    206             // MEASUREMENT_MOBILE_TX_MS
    207             sum = 0;
    208             for (final BatteryStats.LongCounter counter: controller.getTxTimeCounters()) {
    209                 sum += counter.getCountLocked(STATS_SINCE_UNPLUGGED);
    210             }
    211             uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_TX_MS, sum);
    212             // MEASUREMENT_MOBILE_POWER_MAMS
    213             uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_POWER_MAMS,
    214                     controller.getPowerCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
    215         }
    216 
    217         // MEASUREMENT_WIFI_RUNNING_MS
    218         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_RUNNING_MS,
    219                 uid.getWifiRunningTime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
    220 
    221         // MEASUREMENT_WIFI_FULL_LOCK_MS
    222         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_FULL_LOCK_MS,
    223                 uid.getFullWifiLockTime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
    224 
    225         // TIMER_WIFI_SCAN
    226         uidWriter.addTimer(UidHealthStats.TIMER_WIFI_SCAN,
    227                 uid.getWifiScanCount(STATS_SINCE_UNPLUGGED),
    228                 uid.getWifiScanTime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
    229 
    230         // MEASUREMENT_WIFI_MULTICAST_MS
    231         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_MULTICAST_MS,
    232                 uid.getWifiMulticastTime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
    233 
    234         // TIMER_AUDIO
    235         addTimer(uidWriter, UidHealthStats.TIMER_AUDIO, uid.getAudioTurnedOnTimer());
    236 
    237         // TIMER_VIDEO
    238         addTimer(uidWriter, UidHealthStats.TIMER_VIDEO, uid.getVideoTurnedOnTimer());
    239 
    240         // TIMER_FLASHLIGHT
    241         addTimer(uidWriter, UidHealthStats.TIMER_FLASHLIGHT, uid.getFlashlightTurnedOnTimer());
    242 
    243         // TIMER_CAMERA
    244         addTimer(uidWriter, UidHealthStats.TIMER_CAMERA, uid.getCameraTurnedOnTimer());
    245 
    246         // TIMER_FOREGROUND_ACTIVITY
    247         addTimer(uidWriter, UidHealthStats.TIMER_FOREGROUND_ACTIVITY,
    248                 uid.getForegroundActivityTimer());
    249 
    250         // TIMER_BLUETOOTH_SCAN
    251         addTimer(uidWriter, UidHealthStats.TIMER_BLUETOOTH_SCAN, uid.getBluetoothScanTimer());
    252 
    253         // TIMER_PROCESS_STATE_TOP_MS
    254         addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_TOP_MS,
    255                 uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_TOP));
    256 
    257         // TIMER_PROCESS_STATE_FOREGROUND_SERVICE_MS
    258         addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_FOREGROUND_SERVICE_MS,
    259                 uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE));
    260 
    261         // TIMER_PROCESS_STATE_TOP_SLEEPING_MS
    262         addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_TOP_SLEEPING_MS,
    263                 uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING));
    264 
    265         // TIMER_PROCESS_STATE_FOREGROUND_MS
    266         addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_FOREGROUND_MS,
    267                 uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_FOREGROUND));
    268 
    269         // TIMER_PROCESS_STATE_BACKGROUND_MS
    270         addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_BACKGROUND_MS,
    271                 uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_BACKGROUND));
    272 
    273         // TIMER_PROCESS_STATE_CACHED_MS
    274         addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_CACHED_MS,
    275                 uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_CACHED));
    276 
    277         // TIMER_VIBRATOR
    278         addTimer(uidWriter, UidHealthStats.TIMER_VIBRATOR, uid.getVibratorOnTimer());
    279 
    280         // MEASUREMENT_OTHER_USER_ACTIVITY_COUNT
    281         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_OTHER_USER_ACTIVITY_COUNT,
    282                 uid.getUserActivityCount(PowerManager.USER_ACTIVITY_EVENT_OTHER,
    283                     STATS_SINCE_UNPLUGGED));
    284 
    285         // MEASUREMENT_BUTTON_USER_ACTIVITY_COUNT
    286         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BUTTON_USER_ACTIVITY_COUNT,
    287                 uid.getUserActivityCount(PowerManager.USER_ACTIVITY_EVENT_BUTTON,
    288                     STATS_SINCE_UNPLUGGED));
    289 
    290         // MEASUREMENT_TOUCH_USER_ACTIVITY_COUNT
    291         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_TOUCH_USER_ACTIVITY_COUNT,
    292                 uid.getUserActivityCount(PowerManager.USER_ACTIVITY_EVENT_TOUCH,
    293                     STATS_SINCE_UNPLUGGED));
    294 
    295         // MEASUREMENT_MOBILE_RX_BYTES
    296         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_RX_BYTES,
    297                 uid.getNetworkActivityBytes(BatteryStats.NETWORK_MOBILE_RX_DATA,
    298                     STATS_SINCE_UNPLUGGED));
    299 
    300         // MEASUREMENT_MOBILE_TX_BYTES
    301         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_TX_BYTES,
    302                 uid.getNetworkActivityBytes(BatteryStats.NETWORK_MOBILE_TX_DATA,
    303                     STATS_SINCE_UNPLUGGED));
    304 
    305         // MEASUREMENT_WIFI_RX_BYTES
    306         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_RX_BYTES,
    307                 uid.getNetworkActivityBytes(BatteryStats.NETWORK_WIFI_RX_DATA,
    308                     STATS_SINCE_UNPLUGGED));
    309 
    310         // MEASUREMENT_WIFI_TX_BYTES
    311         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_TX_BYTES,
    312                 uid.getNetworkActivityBytes(BatteryStats.NETWORK_WIFI_TX_DATA,
    313                     STATS_SINCE_UNPLUGGED));
    314 
    315         // MEASUREMENT_BLUETOOTH_RX_BYTES
    316         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_RX_BYTES,
    317                 uid.getNetworkActivityBytes(BatteryStats.NETWORK_BT_RX_DATA,
    318                     STATS_SINCE_UNPLUGGED));
    319 
    320         // MEASUREMENT_BLUETOOTH_TX_BYTES
    321         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_TX_BYTES,
    322                 uid.getNetworkActivityBytes(BatteryStats.NETWORK_BT_TX_DATA,
    323                     STATS_SINCE_UNPLUGGED));
    324 
    325         // MEASUREMENT_MOBILE_RX_PACKETS
    326         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_RX_PACKETS,
    327                 uid.getNetworkActivityPackets(BatteryStats.NETWORK_MOBILE_RX_DATA,
    328                     STATS_SINCE_UNPLUGGED));
    329 
    330         // MEASUREMENT_MOBILE_TX_PACKETS
    331         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_TX_PACKETS,
    332                 uid.getNetworkActivityPackets(BatteryStats.NETWORK_MOBILE_TX_DATA,
    333                     STATS_SINCE_UNPLUGGED));
    334 
    335         // MEASUREMENT_WIFI_RX_PACKETS
    336         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_RX_PACKETS,
    337                 uid.getNetworkActivityPackets(BatteryStats.NETWORK_WIFI_RX_DATA,
    338                     STATS_SINCE_UNPLUGGED));
    339 
    340         // MEASUREMENT_WIFI_TX_PACKETS
    341         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_TX_PACKETS,
    342                 uid.getNetworkActivityPackets(BatteryStats.NETWORK_WIFI_TX_DATA,
    343                     STATS_SINCE_UNPLUGGED));
    344 
    345         // MEASUREMENT_BLUETOOTH_RX_PACKETS
    346         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_RX_PACKETS,
    347                 uid.getNetworkActivityPackets(BatteryStats.NETWORK_BT_RX_DATA,
    348                     STATS_SINCE_UNPLUGGED));
    349 
    350         // MEASUREMENT_BLUETOOTH_TX_PACKETS
    351         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_TX_PACKETS,
    352                 uid.getNetworkActivityPackets(BatteryStats.NETWORK_BT_TX_DATA,
    353                     STATS_SINCE_UNPLUGGED));
    354 
    355         // TIMER_MOBILE_RADIO_ACTIVE
    356         uidWriter.addTimer(UidHealthStats.TIMER_MOBILE_RADIO_ACTIVE,
    357                 uid.getMobileRadioActiveCount(STATS_SINCE_UNPLUGGED),
    358                 uid.getMobileRadioActiveTime(STATS_SINCE_UNPLUGGED));
    359 
    360         // MEASUREMENT_USER_CPU_TIME_MS
    361         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_USER_CPU_TIME_MS,
    362                 uid.getUserCpuTimeUs(STATS_SINCE_UNPLUGGED)/1000);
    363 
    364         // MEASUREMENT_SYSTEM_CPU_TIME_MS
    365         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_SYSTEM_CPU_TIME_MS,
    366                 uid.getSystemCpuTimeUs(STATS_SINCE_UNPLUGGED)/1000);
    367 
    368         // MEASUREMENT_CPU_POWER_MAMS
    369         uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_CPU_POWER_MAMS, 0);
    370     }
    371 
    372     /**
    373      * Writes the contents of a BatteryStats.Uid.Pid into a HealthStatsWriter.
    374      */
    375     public void writePid(HealthStatsWriter pidWriter, BatteryStats.Uid.Pid pid) {
    376         if (pid == null) {
    377             return;
    378         }
    379 
    380         // MEASUREMENT_WAKE_NESTING_COUNT
    381         pidWriter.addMeasurement(PidHealthStats.MEASUREMENT_WAKE_NESTING_COUNT, pid.mWakeNesting);
    382 
    383         // MEASUREMENT_WAKE_SUM_MS
    384         pidWriter.addMeasurement(PidHealthStats.MEASUREMENT_WAKE_SUM_MS, pid.mWakeSumMs);
    385 
    386         // MEASUREMENT_WAKE_START_MS
    387         pidWriter.addMeasurement(PidHealthStats.MEASUREMENT_WAKE_SUM_MS, pid.mWakeStartMs);
    388     }
    389 
    390     /**
    391      * Writes the contents of a BatteryStats.Uid.Proc into a HealthStatsWriter.
    392      */
    393     public void writeProc(HealthStatsWriter procWriter, BatteryStats.Uid.Proc proc) {
    394         // MEASUREMENT_USER_TIME_MS
    395         procWriter.addMeasurement(ProcessHealthStats.MEASUREMENT_USER_TIME_MS,
    396                 proc.getUserTime(STATS_SINCE_UNPLUGGED));
    397 
    398         // MEASUREMENT_SYSTEM_TIME_MS
    399         procWriter.addMeasurement(ProcessHealthStats.MEASUREMENT_SYSTEM_TIME_MS,
    400                 proc.getSystemTime(STATS_SINCE_UNPLUGGED));
    401 
    402         // MEASUREMENT_STARTS_COUNT
    403         procWriter.addMeasurement(ProcessHealthStats.MEASUREMENT_STARTS_COUNT,
    404                 proc.getStarts(STATS_SINCE_UNPLUGGED));
    405 
    406         // MEASUREMENT_CRASHES_COUNT
    407         procWriter.addMeasurement(ProcessHealthStats.MEASUREMENT_CRASHES_COUNT,
    408                 proc.getNumCrashes(STATS_SINCE_UNPLUGGED));
    409 
    410         // MEASUREMENT_ANR_COUNT
    411         procWriter.addMeasurement(ProcessHealthStats.MEASUREMENT_ANR_COUNT,
    412                 proc.getNumAnrs(STATS_SINCE_UNPLUGGED));
    413 
    414         // MEASUREMENT_FOREGROUND_MS
    415         procWriter.addMeasurement(ProcessHealthStats.MEASUREMENT_FOREGROUND_MS,
    416                 proc.getForegroundTime(STATS_SINCE_UNPLUGGED));
    417     }
    418 
    419     /**
    420      * Writes the contents of a BatteryStats.Uid.Pkg into a HealthStatsWriter.
    421      */
    422     public void writePkg(HealthStatsWriter pkgWriter, BatteryStats.Uid.Pkg pkg) {
    423         // STATS_SERVICES
    424         for (final Map.Entry<String,? extends BatteryStats.Uid.Pkg.Serv> entry:
    425                 pkg.getServiceStats().entrySet()) {
    426             final HealthStatsWriter writer = new HealthStatsWriter(ServiceHealthStats.CONSTANTS);
    427             writeServ(writer, entry.getValue());
    428             pkgWriter.addStats(PackageHealthStats.STATS_SERVICES, entry.getKey(), writer);
    429         }
    430 
    431         // MEASUREMENTS_WAKEUP_ALARMS_COUNT
    432         for (final Map.Entry<String,? extends BatteryStats.Counter> entry:
    433                 pkg.getWakeupAlarmStats().entrySet()) {
    434             final BatteryStats.Counter counter = entry.getValue();
    435             if (counter != null) {
    436                 pkgWriter.addMeasurements(PackageHealthStats.MEASUREMENTS_WAKEUP_ALARMS_COUNT,
    437                         entry.getKey(), counter.getCountLocked(STATS_SINCE_UNPLUGGED));
    438             }
    439         }
    440     }
    441 
    442     /**
    443      * Writes the contents of a BatteryStats.Uid.Pkg.Serv into a HealthStatsWriter.
    444      */
    445     public void writeServ(HealthStatsWriter servWriter, BatteryStats.Uid.Pkg.Serv serv) {
    446         // MEASUREMENT_START_SERVICE_COUNT
    447         servWriter.addMeasurement(ServiceHealthStats.MEASUREMENT_START_SERVICE_COUNT,
    448                 serv.getStarts(STATS_SINCE_UNPLUGGED));
    449 
    450         // MEASUREMENT_LAUNCH_COUNT
    451         servWriter.addMeasurement(ServiceHealthStats.MEASUREMENT_LAUNCH_COUNT,
    452                 serv.getLaunches(STATS_SINCE_UNPLUGGED));
    453     }
    454 
    455     /**
    456      * Adds a BatteryStats.Timer into a HealthStatsWriter. Safe to pass a null timer.
    457      */
    458     private void addTimer(HealthStatsWriter writer, int key, BatteryStats.Timer timer) {
    459         if (timer != null) {
    460             writer.addTimer(key, timer.getCountLocked(STATS_SINCE_UNPLUGGED),
    461                     timer.getTotalTimeLocked(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED) / 1000);
    462         }
    463     }
    464 
    465     /**
    466      * Adds a named BatteryStats.Timer into a HealthStatsWriter. Safe to pass a null timer.
    467      */
    468     private void addTimers(HealthStatsWriter writer, int key, String name,
    469             BatteryStats.Timer timer) {
    470         if (timer != null) {
    471             writer.addTimers(key, name, new TimerStat(timer.getCountLocked(STATS_SINCE_UNPLUGGED),
    472                     timer.getTotalTimeLocked(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED) / 1000));
    473         }
    474     }
    475 }
    476 
    477