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