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    @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