WifiPowerEstimator.java revision e283d33feda27f54672f90512c25304842cd7eb4
1/*
2 * Copyright (C) 2015 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 */
16package com.android.internal.os;
17
18import android.os.BatteryStats;
19
20/**
21 * Estimates WiFi power usage based on timers in BatteryStats.
22 */
23public class WifiPowerEstimator extends PowerCalculator {
24    private final double mWifiPowerPerPacket;
25    private final double mWifiPowerOn;
26    private final double mWifiPowerScan;
27    private final double mWifiPowerBatchScan;
28    private long mTotalAppWifiRunningTimeMs = 0;
29
30    public WifiPowerEstimator(PowerProfile profile) {
31        mWifiPowerPerPacket = getWifiPowerPerPacket(profile);
32        mWifiPowerOn = profile.getAveragePower(PowerProfile.POWER_WIFI_ON);
33        mWifiPowerScan = profile.getAveragePower(PowerProfile.POWER_WIFI_SCAN);
34        mWifiPowerBatchScan = profile.getAveragePower(PowerProfile.POWER_WIFI_BATCHED_SCAN);
35    }
36
37    /**
38     * Return estimated power (in mAs) of sending a byte with the Wi-Fi radio.
39     */
40    private static double getWifiPowerPerPacket(PowerProfile profile) {
41        final long WIFI_BPS = 1000000; // TODO: Extract average bit rates from system
42        final double WIFI_POWER = profile.getAveragePower(PowerProfile.POWER_WIFI_ACTIVE)
43                / 3600;
44        return (WIFI_POWER / (((double)WIFI_BPS) / 8 / 2048)) / (60*60);
45    }
46
47    @Override
48    public void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
49                             long rawUptimeUs, int statsType) {
50        app.wifiRxPackets = u.getNetworkActivityPackets(BatteryStats.NETWORK_WIFI_RX_DATA,
51                statsType);
52        app.wifiTxPackets = u.getNetworkActivityPackets(BatteryStats.NETWORK_WIFI_TX_DATA,
53                statsType);
54        app.wifiRxBytes = u.getNetworkActivityBytes(BatteryStats.NETWORK_WIFI_RX_DATA,
55                statsType);
56        app.wifiTxBytes = u.getNetworkActivityBytes(BatteryStats.NETWORK_WIFI_TX_DATA,
57                statsType);
58
59        final double wifiPacketPower = (app.wifiRxPackets + app.wifiTxPackets)
60                * mWifiPowerPerPacket;
61
62        app.wifiRunningTimeMs = u.getWifiRunningTime(rawRealtimeUs, statsType) / 1000;
63        mTotalAppWifiRunningTimeMs += app.wifiRunningTimeMs;
64        final double wifiLockPower = (app.wifiRunningTimeMs * mWifiPowerOn) / (1000*60*60);
65
66        final long wifiScanTimeMs = u.getWifiScanTime(rawRealtimeUs, statsType) / 1000;
67        final double wifiScanPower = (wifiScanTimeMs * mWifiPowerScan) / (1000*60*60);
68
69        double wifiBatchScanPower = 0;
70        for (int bin = 0; bin < BatteryStats.Uid.NUM_WIFI_BATCHED_SCAN_BINS; bin++) {
71            final long batchScanTimeMs =
72                    u.getWifiBatchedScanTime(bin, rawRealtimeUs, statsType) / 1000;
73            final double batchScanPower = (batchScanTimeMs * mWifiPowerBatchScan) / (1000*60*60);
74            wifiBatchScanPower += batchScanPower;
75        }
76
77        app.wifiPowerMah = wifiPacketPower + wifiLockPower + wifiScanPower + wifiBatchScanPower;
78    }
79
80    @Override
81    public void calculateRemaining(BatterySipper app, BatteryStats stats, long rawRealtimeUs,
82                                   long rawUptimeUs, int statsType) {
83        final long totalRunningTimeMs = stats.getGlobalWifiRunningTime(rawRealtimeUs, statsType)
84                / 1000;
85        final double powerDrain = ((totalRunningTimeMs - mTotalAppWifiRunningTimeMs) * mWifiPowerOn)
86                / (1000*60*60);
87        app.wifiRunningTimeMs = totalRunningTimeMs;
88        app.wifiPowerMah = Math.max(0, powerDrain);
89    }
90
91    @Override
92    public void reset() {
93        mTotalAppWifiRunningTimeMs = 0;
94    }
95}
96