HealthStatsBatteryStatsWriter.java revision bee44ae8e5da109cd8273a057b566dc6925d6a71
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
17package com.android.server.am;
18
19import android.os.BatteryStats;
20import static android.os.BatteryStats.STATS_SINCE_UNPLUGGED;
21import android.os.PowerManager;
22import android.os.SystemClock;
23import android.os.health.HealthKeys;
24import android.os.health.HealthStatsParceler;
25import android.os.health.HealthStatsWriter;
26import android.os.health.PackageHealthStats;
27import android.os.health.ProcessHealthStats;
28import android.os.health.PidHealthStats;
29import android.os.health.ServiceHealthStats;
30import android.os.health.TimerStat;
31import android.os.health.UidHealthStats;
32import android.util.SparseArray;
33
34import java.util.Map;
35
36public 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    public void writeUid(HealthStatsWriter uidWriter, BatteryStats bs, BatteryStats.Uid uid) {
50        int N;
51        BatteryStats.Timer timer;
52        SparseArray<? extends BatteryStats.Uid.Sensor> sensors;
53        SparseArray<? extends BatteryStats.Uid.Pid> pids;
54        BatteryStats.ControllerActivityCounter controller;
55        long sum;
56
57        //
58        // It's a little odd for these first four to be here but it's not the end of the
59        // world. It would be easy enough to duplicate them somewhere else if this API
60        // grows.
61        //
62
63        // MEASUREMENT_REALTIME_BATTERY_MS
64        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_REALTIME_BATTERY_MS,
65                bs.computeBatteryRealtime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
66
67        // MEASUREMENT_UPTIME_BATTERY_MS
68        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_UPTIME_BATTERY_MS,
69                bs.computeBatteryUptime(mNowUptimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
70
71        // MEASUREMENT_REALTIME_SCREEN_OFF_BATTERY_MS
72        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_REALTIME_SCREEN_OFF_BATTERY_MS,
73                bs.computeBatteryScreenOffRealtime(
74                    mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
75
76        // MEASUREMENT_UPTIME_SCREEN_OFF_BATTERY_MS
77        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_UPTIME_SCREEN_OFF_BATTERY_MS,
78                bs.computeBatteryScreenOffUptime(mNowUptimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
79
80        //
81        // Now on to the real per-uid stats...
82        //
83
84        for (final Map.Entry<String,? extends BatteryStats.Uid.Wakelock> entry:
85                uid.getWakelockStats().entrySet()) {
86            final String key = entry.getKey();
87            final BatteryStats.Uid.Wakelock wakelock = entry.getValue();
88
89            // TIMERS_WAKELOCKS_FULL
90            timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_FULL);
91            addTimers(uidWriter, UidHealthStats.TIMERS_WAKELOCKS_FULL, key, timer);
92
93            // TIMERS_WAKELOCKS_PARTIAL
94            timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL);
95            addTimers(uidWriter, UidHealthStats.TIMERS_WAKELOCKS_PARTIAL, key, timer);
96
97            // TIMERS_WAKELOCKS_WINDOW
98            timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_WINDOW);
99            addTimers(uidWriter, UidHealthStats.TIMERS_WAKELOCKS_WINDOW, key, timer);
100
101            // TIMERS_WAKELOCKS_DRAW
102            timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_DRAW);
103            addTimers(uidWriter, UidHealthStats.TIMERS_WAKELOCKS_DRAW, key, timer);
104        }
105
106        // TIMERS_SYNCS
107        for (final Map.Entry<String,? extends BatteryStats.Timer> entry:
108                uid.getSyncStats().entrySet()) {
109            addTimers(uidWriter, UidHealthStats.TIMERS_SYNCS, entry.getKey(), entry.getValue());
110        }
111
112        // TIMERS_JOBS
113        for (final Map.Entry<String,? extends BatteryStats.Timer> entry:
114                uid.getJobStats().entrySet()) {
115            addTimers(uidWriter, UidHealthStats.TIMERS_JOBS, entry.getKey(), entry.getValue());
116        }
117
118        // TIMERS_SENSORS
119        sensors = uid.getSensorStats();
120        N = sensors.size();
121        for (int i=0; i<N; i++) {
122            int sensorId = sensors.keyAt(i);
123            // Battery Stats stores the GPS sensors with a bogus key in this API. Pull it out
124            // as a separate metric here so as to not expose that in the API.
125            if (sensorId == BatteryStats.Uid.Sensor.GPS) {
126                addTimer(uidWriter, UidHealthStats.TIMER_GPS_SENSOR,
127                        sensors.valueAt(i).getSensorTime());
128            } else {
129                addTimers(uidWriter, UidHealthStats.TIMERS_SENSORS, Integer.toString(sensorId),
130                        sensors.valueAt(i).getSensorTime());
131            }
132        }
133
134        // STATS_PIDS
135        pids = uid.getPidStats();
136        N = pids.size();
137        for (int i=0; i<N; i++) {
138            final HealthStatsWriter writer = new HealthStatsWriter(PidHealthStats.CONSTANTS);
139            writePid(writer, pids.valueAt(i));
140            uidWriter.addStats(UidHealthStats.STATS_PIDS, Integer.toString(pids.keyAt(i)), writer);
141        }
142
143        // STATS_PROCESSES
144        for (final Map.Entry<String,? extends BatteryStats.Uid.Proc> entry:
145                uid.getProcessStats().entrySet()) {
146            final HealthStatsWriter writer = new HealthStatsWriter(ProcessHealthStats.CONSTANTS);
147            writeProc(writer, entry.getValue());
148            uidWriter.addStats(UidHealthStats.STATS_PROCESSES, entry.getKey(), writer);
149        }
150
151        // STATS_PACKAGES
152        for (final Map.Entry<String,? extends BatteryStats.Uid.Pkg> entry:
153                uid.getPackageStats().entrySet()) {
154            final HealthStatsWriter writer = new HealthStatsWriter(PackageHealthStats.CONSTANTS);
155            writePkg(writer, entry.getValue());
156            uidWriter.addStats(UidHealthStats.STATS_PACKAGES, entry.getKey(), writer);
157        }
158
159        controller = uid.getWifiControllerActivity();
160        if (controller != null) {
161            // MEASUREMENT_WIFI_IDLE_MS
162            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_IDLE_MS,
163                    controller.getIdleTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
164            // MEASUREMENT_WIFI_RX_MS
165            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_RX_MS,
166                    controller.getRxTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
167            // MEASUREMENT_WIFI_TX_MS
168            sum = 0;
169            for (final BatteryStats.LongCounter counter: controller.getTxTimeCounters()) {
170                sum += counter.getCountLocked(STATS_SINCE_UNPLUGGED);
171            }
172            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_TX_MS, sum);
173            // MEASUREMENT_WIFI_POWER_MAMS
174            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_POWER_MAMS,
175                    controller.getPowerCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
176        }
177
178        controller = uid.getBluetoothControllerActivity();
179        if (controller != null) {
180            // MEASUREMENT_BLUETOOTH_IDLE_MS
181            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_IDLE_MS,
182                    controller.getIdleTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
183            // MEASUREMENT_BLUETOOTH_RX_MS
184            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_RX_MS,
185                    controller.getRxTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
186            // MEASUREMENT_BLUETOOTH_TX_MS
187            sum = 0;
188            for (final BatteryStats.LongCounter counter: controller.getTxTimeCounters()) {
189                sum += counter.getCountLocked(STATS_SINCE_UNPLUGGED);
190            }
191            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_TX_MS, sum);
192            // MEASUREMENT_BLUETOOTH_POWER_MAMS
193            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_POWER_MAMS,
194                    controller.getPowerCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
195        }
196
197        controller = uid.getModemControllerActivity();
198        if (controller != null) {
199            // MEASUREMENT_MOBILE_IDLE_MS
200            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_IDLE_MS,
201                    controller.getIdleTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
202            // MEASUREMENT_MOBILE_RX_MS
203            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_RX_MS,
204                    controller.getRxTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
205            // MEASUREMENT_MOBILE_TX_MS
206            sum = 0;
207            for (final BatteryStats.LongCounter counter: controller.getTxTimeCounters()) {
208                sum += counter.getCountLocked(STATS_SINCE_UNPLUGGED);
209            }
210            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_TX_MS, sum);
211            // MEASUREMENT_MOBILE_POWER_MAMS
212            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_POWER_MAMS,
213                    controller.getPowerCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
214        }
215
216        // MEASUREMENT_WIFI_RUNNING_MS
217        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_RUNNING_MS,
218                uid.getWifiRunningTime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
219
220        // MEASUREMENT_WIFI_FULL_LOCK_MS
221        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_FULL_LOCK_MS,
222                uid.getFullWifiLockTime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
223
224        // TIMER_WIFI_SCAN
225        uidWriter.addTimer(UidHealthStats.TIMER_WIFI_SCAN,
226                uid.getWifiScanCount(STATS_SINCE_UNPLUGGED),
227                uid.getWifiScanTime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
228
229        // MEASUREMENT_WIFI_MULTICAST_MS
230        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_MULTICAST_MS,
231                uid.getWifiMulticastTime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);
232
233        // TIMER_AUDIO
234        addTimer(uidWriter, UidHealthStats.TIMER_AUDIO, uid.getAudioTurnedOnTimer());
235
236        // TIMER_VIDEO
237        addTimer(uidWriter, UidHealthStats.TIMER_VIDEO, uid.getVideoTurnedOnTimer());
238
239        // TIMER_FLASHLIGHT
240        addTimer(uidWriter, UidHealthStats.TIMER_FLASHLIGHT, uid.getFlashlightTurnedOnTimer());
241
242        // TIMER_CAMERA
243        addTimer(uidWriter, UidHealthStats.TIMER_CAMERA, uid.getCameraTurnedOnTimer());
244
245        // TIMER_FOREGROUND_ACTIVITY
246        addTimer(uidWriter, UidHealthStats.TIMER_FOREGROUND_ACTIVITY,
247                uid.getForegroundActivityTimer());
248
249        // TIMER_BLUETOOTH_SCAN
250        addTimer(uidWriter, UidHealthStats.TIMER_BLUETOOTH_SCAN, uid.getBluetoothScanTimer());
251
252        // TIMER_PROCESS_STATE_TOP_MS
253        addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_TOP_MS,
254                uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_TOP));
255
256        // TIMER_PROCESS_STATE_FOREGROUND_SERVICE_MS
257        addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_FOREGROUND_SERVICE_MS,
258                uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE));
259
260        // TIMER_PROCESS_STATE_TOP_SLEEPING_MS
261        addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_TOP_SLEEPING_MS,
262                uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING));
263
264        // TIMER_PROCESS_STATE_FOREGROUND_MS
265        addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_FOREGROUND_MS,
266                uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_FOREGROUND));
267
268        // TIMER_PROCESS_STATE_BACKGROUND_MS
269        addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_BACKGROUND_MS,
270                uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_BACKGROUND));
271
272        // TIMER_PROCESS_STATE_CACHED_MS
273        addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_CACHED_MS,
274                uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_CACHED));
275
276        // TIMER_VIBRATOR
277        addTimer(uidWriter, UidHealthStats.TIMER_VIBRATOR, uid.getVibratorOnTimer());
278
279        // MEASUREMENT_OTHER_USER_ACTIVITY_COUNT
280        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_OTHER_USER_ACTIVITY_COUNT,
281                uid.getUserActivityCount(PowerManager.USER_ACTIVITY_EVENT_OTHER,
282                    STATS_SINCE_UNPLUGGED));
283
284        // MEASUREMENT_BUTTON_USER_ACTIVITY_COUNT
285        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BUTTON_USER_ACTIVITY_COUNT,
286                uid.getUserActivityCount(PowerManager.USER_ACTIVITY_EVENT_BUTTON,
287                    STATS_SINCE_UNPLUGGED));
288
289        // MEASUREMENT_TOUCH_USER_ACTIVITY_COUNT
290        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_TOUCH_USER_ACTIVITY_COUNT,
291                uid.getUserActivityCount(PowerManager.USER_ACTIVITY_EVENT_TOUCH,
292                    STATS_SINCE_UNPLUGGED));
293
294        // MEASUREMENT_MOBILE_RX_BYTES
295        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_RX_BYTES,
296                uid.getNetworkActivityBytes(BatteryStats.NETWORK_MOBILE_RX_DATA,
297                    STATS_SINCE_UNPLUGGED));
298
299        // MEASUREMENT_MOBILE_TX_BYTES
300        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_TX_BYTES,
301                uid.getNetworkActivityBytes(BatteryStats.NETWORK_MOBILE_TX_DATA,
302                    STATS_SINCE_UNPLUGGED));
303
304        // MEASUREMENT_WIFI_RX_BYTES
305        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_RX_BYTES,
306                uid.getNetworkActivityBytes(BatteryStats.NETWORK_WIFI_RX_DATA,
307                    STATS_SINCE_UNPLUGGED));
308
309        // MEASUREMENT_WIFI_TX_BYTES
310        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_TX_BYTES,
311                uid.getNetworkActivityBytes(BatteryStats.NETWORK_WIFI_TX_DATA,
312                    STATS_SINCE_UNPLUGGED));
313
314        // MEASUREMENT_BLUETOOTH_RX_BYTES
315        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_RX_BYTES,
316                uid.getNetworkActivityBytes(BatteryStats.NETWORK_BT_RX_DATA,
317                    STATS_SINCE_UNPLUGGED));
318
319        // MEASUREMENT_BLUETOOTH_TX_BYTES
320        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_TX_BYTES,
321                uid.getNetworkActivityBytes(BatteryStats.NETWORK_BT_TX_DATA,
322                    STATS_SINCE_UNPLUGGED));
323
324        // MEASUREMENT_MOBILE_RX_PACKETS
325        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_RX_PACKETS,
326                uid.getNetworkActivityPackets(BatteryStats.NETWORK_MOBILE_RX_DATA,
327                    STATS_SINCE_UNPLUGGED));
328
329        // MEASUREMENT_MOBILE_TX_PACKETS
330        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_TX_PACKETS,
331                uid.getNetworkActivityPackets(BatteryStats.NETWORK_MOBILE_TX_DATA,
332                    STATS_SINCE_UNPLUGGED));
333
334        // MEASUREMENT_WIFI_RX_PACKETS
335        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_RX_PACKETS,
336                uid.getNetworkActivityPackets(BatteryStats.NETWORK_WIFI_RX_DATA,
337                    STATS_SINCE_UNPLUGGED));
338
339        // MEASUREMENT_WIFI_TX_PACKETS
340        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_TX_PACKETS,
341                uid.getNetworkActivityPackets(BatteryStats.NETWORK_WIFI_TX_DATA,
342                    STATS_SINCE_UNPLUGGED));
343
344        // MEASUREMENT_BLUETOOTH_RX_PACKETS
345        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_RX_PACKETS,
346                uid.getNetworkActivityPackets(BatteryStats.NETWORK_BT_RX_DATA,
347                    STATS_SINCE_UNPLUGGED));
348
349        // MEASUREMENT_BLUETOOTH_TX_PACKETS
350        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_TX_PACKETS,
351                uid.getNetworkActivityPackets(BatteryStats.NETWORK_BT_TX_DATA,
352                    STATS_SINCE_UNPLUGGED));
353
354        // TIMER_MOBILE_RADIO_ACTIVE
355        uidWriter.addTimer(UidHealthStats.TIMER_MOBILE_RADIO_ACTIVE,
356                uid.getMobileRadioActiveCount(STATS_SINCE_UNPLUGGED),
357                uid.getMobileRadioActiveTime(STATS_SINCE_UNPLUGGED));
358
359        // MEASUREMENT_USER_CPU_TIME_MS
360        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_USER_CPU_TIME_MS,
361                uid.getUserCpuTimeUs(STATS_SINCE_UNPLUGGED)/1000);
362
363        // MEASUREMENT_SYSTEM_CPU_TIME_MS
364        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_SYSTEM_CPU_TIME_MS,
365                uid.getSystemCpuTimeUs(STATS_SINCE_UNPLUGGED)/1000);
366
367        // MEASUREMENT_CPU_POWER_MAMS
368        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_CPU_POWER_MAMS,
369                uid.getCpuPowerMaUs(STATS_SINCE_UNPLUGGED)/1000);
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