/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.am;

import android.os.BatteryStats;
import static android.os.BatteryStats.STATS_SINCE_UNPLUGGED;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.health.HealthKeys;
import android.os.health.HealthStatsParceler;
import android.os.health.HealthStatsWriter;
import android.os.health.PackageHealthStats;
import android.os.health.ProcessHealthStats;
import android.os.health.PidHealthStats;
import android.os.health.ServiceHealthStats;
import android.os.health.TimerStat;
import android.os.health.UidHealthStats;
import android.util.SparseArray;

import java.util.Map;

public class HealthStatsBatteryStatsWriter {

    private final long mNowRealtimeMs;
    private final long mNowUptimeMs;

    public HealthStatsBatteryStatsWriter() {
        mNowRealtimeMs = SystemClock.elapsedRealtime();
        mNowUptimeMs = SystemClock.uptimeMillis();
    }

    /**
     * Writes the contents of a BatteryStats.Uid into a HealthStatsWriter.
     */
    public void writeUid(HealthStatsWriter uidWriter, BatteryStats bs, BatteryStats.Uid uid) {
        int N;
        BatteryStats.Timer timer;
        SparseArray<? extends BatteryStats.Uid.Sensor> sensors;
        SparseArray<? extends BatteryStats.Uid.Pid> pids;
        BatteryStats.ControllerActivityCounter controller;
        long sum;

        //
        // It's a little odd for these first four to be here but it's not the end of the
        // world. It would be easy enough to duplicate them somewhere else if this API
        // grows.
        //

        // MEASUREMENT_REALTIME_BATTERY_MS
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_REALTIME_BATTERY_MS,
                bs.computeBatteryRealtime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);

        // MEASUREMENT_UPTIME_BATTERY_MS
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_UPTIME_BATTERY_MS,
                bs.computeBatteryUptime(mNowUptimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);

        // MEASUREMENT_REALTIME_SCREEN_OFF_BATTERY_MS
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_REALTIME_SCREEN_OFF_BATTERY_MS,
                bs.computeBatteryScreenOffRealtime(
                    mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);

        // MEASUREMENT_UPTIME_SCREEN_OFF_BATTERY_MS
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_UPTIME_SCREEN_OFF_BATTERY_MS,
                bs.computeBatteryScreenOffUptime(mNowUptimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);

        //
        // Now on to the real per-uid stats...
        //

        for (final Map.Entry<String,? extends BatteryStats.Uid.Wakelock> entry:
                uid.getWakelockStats().entrySet()) {
            final String key = entry.getKey();
            final BatteryStats.Uid.Wakelock wakelock = entry.getValue();

            // TIMERS_WAKELOCKS_FULL
            timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_FULL);
            addTimers(uidWriter, UidHealthStats.TIMERS_WAKELOCKS_FULL, key, timer);

            // TIMERS_WAKELOCKS_PARTIAL
            timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL);
            addTimers(uidWriter, UidHealthStats.TIMERS_WAKELOCKS_PARTIAL, key, timer);
            
            // TIMERS_WAKELOCKS_WINDOW
            timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_WINDOW);
            addTimers(uidWriter, UidHealthStats.TIMERS_WAKELOCKS_WINDOW, key, timer);
            
            // TIMERS_WAKELOCKS_DRAW
            timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_DRAW);
            addTimers(uidWriter, UidHealthStats.TIMERS_WAKELOCKS_DRAW, key, timer);
        }
        
        // TIMERS_SYNCS
        for (final Map.Entry<String,? extends BatteryStats.Timer> entry:
                uid.getSyncStats().entrySet()) {
            addTimers(uidWriter, UidHealthStats.TIMERS_SYNCS, entry.getKey(), entry.getValue());
        }

        // TIMERS_JOBS
        for (final Map.Entry<String,? extends BatteryStats.Timer> entry:
                uid.getJobStats().entrySet()) {
            addTimers(uidWriter, UidHealthStats.TIMERS_JOBS, entry.getKey(), entry.getValue());
        }

        // TIMERS_SENSORS
        sensors = uid.getSensorStats();
        N = sensors.size();
        for (int i=0; i<N; i++) {
            int sensorId = sensors.keyAt(i);
            // Battery Stats stores the GPS sensors with a bogus key in this API. Pull it out
            // as a separate metric here so as to not expose that in the API.
            if (sensorId == BatteryStats.Uid.Sensor.GPS) {
                addTimer(uidWriter, UidHealthStats.TIMER_GPS_SENSOR,
                        sensors.valueAt(i).getSensorTime());
            } else {
                addTimers(uidWriter, UidHealthStats.TIMERS_SENSORS, Integer.toString(sensorId),
                        sensors.valueAt(i).getSensorTime());
            }
        }

        // STATS_PIDS
        pids = uid.getPidStats();
        N = pids.size();
        for (int i=0; i<N; i++) {
            final HealthStatsWriter writer = new HealthStatsWriter(PidHealthStats.CONSTANTS);
            writePid(writer, pids.valueAt(i));
            uidWriter.addStats(UidHealthStats.STATS_PIDS, Integer.toString(pids.keyAt(i)), writer);
        }

        // STATS_PROCESSES
        for (final Map.Entry<String,? extends BatteryStats.Uid.Proc> entry:
                uid.getProcessStats().entrySet()) {
            final HealthStatsWriter writer = new HealthStatsWriter(ProcessHealthStats.CONSTANTS);
            writeProc(writer, entry.getValue());
            uidWriter.addStats(UidHealthStats.STATS_PROCESSES, entry.getKey(), writer);
        }

        // STATS_PACKAGES
        for (final Map.Entry<String,? extends BatteryStats.Uid.Pkg> entry:
                uid.getPackageStats().entrySet()) {
            final HealthStatsWriter writer = new HealthStatsWriter(PackageHealthStats.CONSTANTS);
            writePkg(writer, entry.getValue());
            uidWriter.addStats(UidHealthStats.STATS_PACKAGES, entry.getKey(), writer);
        }

        controller = uid.getWifiControllerActivity();
        if (controller != null) {
            // MEASUREMENT_WIFI_IDLE_MS
            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_IDLE_MS,
                    controller.getIdleTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
            // MEASUREMENT_WIFI_RX_MS
            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_RX_MS,
                    controller.getRxTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
            // MEASUREMENT_WIFI_TX_MS
            sum = 0;
            for (final BatteryStats.LongCounter counter: controller.getTxTimeCounters()) {
                sum += counter.getCountLocked(STATS_SINCE_UNPLUGGED);
            }
            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_TX_MS, sum);
            // MEASUREMENT_WIFI_POWER_MAMS
            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_POWER_MAMS,
                    controller.getPowerCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
        }

        controller = uid.getBluetoothControllerActivity();
        if (controller != null) {
            // MEASUREMENT_BLUETOOTH_IDLE_MS
            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_IDLE_MS,
                    controller.getIdleTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
            // MEASUREMENT_BLUETOOTH_RX_MS
            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_RX_MS,
                    controller.getRxTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
            // MEASUREMENT_BLUETOOTH_TX_MS
            sum = 0;
            for (final BatteryStats.LongCounter counter: controller.getTxTimeCounters()) {
                sum += counter.getCountLocked(STATS_SINCE_UNPLUGGED);
            }
            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_TX_MS, sum);
            // MEASUREMENT_BLUETOOTH_POWER_MAMS
            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_POWER_MAMS,
                    controller.getPowerCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
        }

        controller = uid.getModemControllerActivity();
        if (controller != null) {
            // MEASUREMENT_MOBILE_IDLE_MS
            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_IDLE_MS,
                    controller.getIdleTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
            // MEASUREMENT_MOBILE_RX_MS
            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_RX_MS,
                    controller.getRxTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
            // MEASUREMENT_MOBILE_TX_MS
            sum = 0;
            for (final BatteryStats.LongCounter counter: controller.getTxTimeCounters()) {
                sum += counter.getCountLocked(STATS_SINCE_UNPLUGGED);
            }
            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_TX_MS, sum);
            // MEASUREMENT_MOBILE_POWER_MAMS
            uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_POWER_MAMS,
                    controller.getPowerCounter().getCountLocked(STATS_SINCE_UNPLUGGED));
        }

        // MEASUREMENT_WIFI_RUNNING_MS
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_RUNNING_MS,
                uid.getWifiRunningTime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);

        // MEASUREMENT_WIFI_FULL_LOCK_MS
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_FULL_LOCK_MS,
                uid.getFullWifiLockTime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);

        // TIMER_WIFI_SCAN
        uidWriter.addTimer(UidHealthStats.TIMER_WIFI_SCAN,
                uid.getWifiScanCount(STATS_SINCE_UNPLUGGED),
                uid.getWifiScanTime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);

        // MEASUREMENT_WIFI_MULTICAST_MS
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_MULTICAST_MS,
                uid.getWifiMulticastTime(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED)/1000);

        // TIMER_AUDIO
        addTimer(uidWriter, UidHealthStats.TIMER_AUDIO, uid.getAudioTurnedOnTimer());

        // TIMER_VIDEO
        addTimer(uidWriter, UidHealthStats.TIMER_VIDEO, uid.getVideoTurnedOnTimer());

        // TIMER_FLASHLIGHT
        addTimer(uidWriter, UidHealthStats.TIMER_FLASHLIGHT, uid.getFlashlightTurnedOnTimer());

        // TIMER_CAMERA
        addTimer(uidWriter, UidHealthStats.TIMER_CAMERA, uid.getCameraTurnedOnTimer());

        // TIMER_FOREGROUND_ACTIVITY
        addTimer(uidWriter, UidHealthStats.TIMER_FOREGROUND_ACTIVITY,
                uid.getForegroundActivityTimer());

        // TIMER_BLUETOOTH_SCAN
        addTimer(uidWriter, UidHealthStats.TIMER_BLUETOOTH_SCAN, uid.getBluetoothScanTimer());

        // TIMER_PROCESS_STATE_TOP_MS
        addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_TOP_MS,
                uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_TOP));

        // TIMER_PROCESS_STATE_FOREGROUND_SERVICE_MS
        addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_FOREGROUND_SERVICE_MS,
                uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE));

        // TIMER_PROCESS_STATE_TOP_SLEEPING_MS
        addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_TOP_SLEEPING_MS,
                uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING));

        // TIMER_PROCESS_STATE_FOREGROUND_MS
        addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_FOREGROUND_MS,
                uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_FOREGROUND));

        // TIMER_PROCESS_STATE_BACKGROUND_MS
        addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_BACKGROUND_MS,
                uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_BACKGROUND));

        // TIMER_PROCESS_STATE_CACHED_MS
        addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_CACHED_MS,
                uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_CACHED));

        // TIMER_VIBRATOR
        addTimer(uidWriter, UidHealthStats.TIMER_VIBRATOR, uid.getVibratorOnTimer());

        // MEASUREMENT_OTHER_USER_ACTIVITY_COUNT
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_OTHER_USER_ACTIVITY_COUNT,
                uid.getUserActivityCount(PowerManager.USER_ACTIVITY_EVENT_OTHER,
                    STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_BUTTON_USER_ACTIVITY_COUNT
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BUTTON_USER_ACTIVITY_COUNT,
                uid.getUserActivityCount(PowerManager.USER_ACTIVITY_EVENT_BUTTON,
                    STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_TOUCH_USER_ACTIVITY_COUNT
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_TOUCH_USER_ACTIVITY_COUNT,
                uid.getUserActivityCount(PowerManager.USER_ACTIVITY_EVENT_TOUCH,
                    STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_MOBILE_RX_BYTES
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_RX_BYTES,
                uid.getNetworkActivityBytes(BatteryStats.NETWORK_MOBILE_RX_DATA,
                    STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_MOBILE_TX_BYTES
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_TX_BYTES,
                uid.getNetworkActivityBytes(BatteryStats.NETWORK_MOBILE_TX_DATA,
                    STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_WIFI_RX_BYTES
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_RX_BYTES,
                uid.getNetworkActivityBytes(BatteryStats.NETWORK_WIFI_RX_DATA,
                    STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_WIFI_TX_BYTES
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_TX_BYTES,
                uid.getNetworkActivityBytes(BatteryStats.NETWORK_WIFI_TX_DATA,
                    STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_BLUETOOTH_RX_BYTES
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_RX_BYTES,
                uid.getNetworkActivityBytes(BatteryStats.NETWORK_BT_RX_DATA,
                    STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_BLUETOOTH_TX_BYTES
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_TX_BYTES,
                uid.getNetworkActivityBytes(BatteryStats.NETWORK_BT_TX_DATA,
                    STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_MOBILE_RX_PACKETS
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_RX_PACKETS,
                uid.getNetworkActivityPackets(BatteryStats.NETWORK_MOBILE_RX_DATA,
                    STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_MOBILE_TX_PACKETS
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_TX_PACKETS,
                uid.getNetworkActivityPackets(BatteryStats.NETWORK_MOBILE_TX_DATA,
                    STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_WIFI_RX_PACKETS
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_RX_PACKETS,
                uid.getNetworkActivityPackets(BatteryStats.NETWORK_WIFI_RX_DATA,
                    STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_WIFI_TX_PACKETS
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_TX_PACKETS,
                uid.getNetworkActivityPackets(BatteryStats.NETWORK_WIFI_TX_DATA,
                    STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_BLUETOOTH_RX_PACKETS
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_RX_PACKETS,
                uid.getNetworkActivityPackets(BatteryStats.NETWORK_BT_RX_DATA,
                    STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_BLUETOOTH_TX_PACKETS
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_TX_PACKETS,
                uid.getNetworkActivityPackets(BatteryStats.NETWORK_BT_TX_DATA,
                    STATS_SINCE_UNPLUGGED));

        // TIMER_MOBILE_RADIO_ACTIVE
        uidWriter.addTimer(UidHealthStats.TIMER_MOBILE_RADIO_ACTIVE,
                uid.getMobileRadioActiveCount(STATS_SINCE_UNPLUGGED),
                uid.getMobileRadioActiveTime(STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_USER_CPU_TIME_MS
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_USER_CPU_TIME_MS,
                uid.getUserCpuTimeUs(STATS_SINCE_UNPLUGGED)/1000);

        // MEASUREMENT_SYSTEM_CPU_TIME_MS
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_SYSTEM_CPU_TIME_MS,
                uid.getSystemCpuTimeUs(STATS_SINCE_UNPLUGGED)/1000);

        // MEASUREMENT_CPU_POWER_MAMS
        uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_CPU_POWER_MAMS,
                uid.getCpuPowerMaUs(STATS_SINCE_UNPLUGGED)/1000);
    }

    /**
     * Writes the contents of a BatteryStats.Uid.Pid into a HealthStatsWriter.
     */
    public void writePid(HealthStatsWriter pidWriter, BatteryStats.Uid.Pid pid) {
        if (pid == null) {
            return;
        }

        // MEASUREMENT_WAKE_NESTING_COUNT
        pidWriter.addMeasurement(PidHealthStats.MEASUREMENT_WAKE_NESTING_COUNT, pid.mWakeNesting);

        // MEASUREMENT_WAKE_SUM_MS
        pidWriter.addMeasurement(PidHealthStats.MEASUREMENT_WAKE_SUM_MS, pid.mWakeSumMs);

        // MEASUREMENT_WAKE_START_MS
        pidWriter.addMeasurement(PidHealthStats.MEASUREMENT_WAKE_SUM_MS, pid.mWakeStartMs);
    }

    /**
     * Writes the contents of a BatteryStats.Uid.Proc into a HealthStatsWriter.
     */
    public void writeProc(HealthStatsWriter procWriter, BatteryStats.Uid.Proc proc) {
        // MEASUREMENT_USER_TIME_MS
        procWriter.addMeasurement(ProcessHealthStats.MEASUREMENT_USER_TIME_MS,
                proc.getUserTime(STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_SYSTEM_TIME_MS
        procWriter.addMeasurement(ProcessHealthStats.MEASUREMENT_SYSTEM_TIME_MS,
                proc.getSystemTime(STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_STARTS_COUNT
        procWriter.addMeasurement(ProcessHealthStats.MEASUREMENT_STARTS_COUNT,
                proc.getStarts(STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_CRASHES_COUNT
        procWriter.addMeasurement(ProcessHealthStats.MEASUREMENT_CRASHES_COUNT,
                proc.getNumCrashes(STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_ANR_COUNT
        procWriter.addMeasurement(ProcessHealthStats.MEASUREMENT_ANR_COUNT,
                proc.getNumAnrs(STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_FOREGROUND_MS
        procWriter.addMeasurement(ProcessHealthStats.MEASUREMENT_FOREGROUND_MS,
                proc.getForegroundTime(STATS_SINCE_UNPLUGGED));
    }

    /**
     * Writes the contents of a BatteryStats.Uid.Pkg into a HealthStatsWriter.
     */
    public void writePkg(HealthStatsWriter pkgWriter, BatteryStats.Uid.Pkg pkg) {
        // STATS_SERVICES
        for (final Map.Entry<String,? extends BatteryStats.Uid.Pkg.Serv> entry:
                pkg.getServiceStats().entrySet()) {
            final HealthStatsWriter writer = new HealthStatsWriter(ServiceHealthStats.CONSTANTS);
            writeServ(writer, entry.getValue());
            pkgWriter.addStats(PackageHealthStats.STATS_SERVICES, entry.getKey(), writer);
        }

        // MEASUREMENTS_WAKEUP_ALARMS_COUNT
        for (final Map.Entry<String,? extends BatteryStats.Counter> entry:
                pkg.getWakeupAlarmStats().entrySet()) {
            final BatteryStats.Counter counter = entry.getValue();
            if (counter != null) {
                pkgWriter.addMeasurements(PackageHealthStats.MEASUREMENTS_WAKEUP_ALARMS_COUNT,
                        entry.getKey(), counter.getCountLocked(STATS_SINCE_UNPLUGGED));
            }
        }
    }

    /**
     * Writes the contents of a BatteryStats.Uid.Pkg.Serv into a HealthStatsWriter.
     */
    public void writeServ(HealthStatsWriter servWriter, BatteryStats.Uid.Pkg.Serv serv) {
        // MEASUREMENT_START_SERVICE_COUNT
        servWriter.addMeasurement(ServiceHealthStats.MEASUREMENT_START_SERVICE_COUNT,
                serv.getStarts(STATS_SINCE_UNPLUGGED));

        // MEASUREMENT_LAUNCH_COUNT
        servWriter.addMeasurement(ServiceHealthStats.MEASUREMENT_LAUNCH_COUNT,
                serv.getLaunches(STATS_SINCE_UNPLUGGED));
    }

    /**
     * Adds a BatteryStats.Timer into a HealthStatsWriter. Safe to pass a null timer.
     */
    private void addTimer(HealthStatsWriter writer, int key, BatteryStats.Timer timer) {
        if (timer != null) {
            writer.addTimer(key, timer.getCountLocked(STATS_SINCE_UNPLUGGED),
                    timer.getTotalTimeLocked(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED) / 1000);
        }
    }

    /**
     * Adds a named BatteryStats.Timer into a HealthStatsWriter. Safe to pass a null timer.
     */
    private void addTimers(HealthStatsWriter writer, int key, String name,
            BatteryStats.Timer timer) {
        if (timer != null) {
            writer.addTimers(key, name, new TimerStat(timer.getCountLocked(STATS_SINCE_UNPLUGGED),
                    timer.getTotalTimeLocked(mNowRealtimeMs*1000, STATS_SINCE_UNPLUGGED) / 1000));
        }
    }
}

