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 */ 16 package com.android.internal.os; 17 18 import android.os.BatteryStats; 19 import android.util.Log; 20 21 /** 22 * WiFi power calculator for when BatteryStats supports energy reporting 23 * from the WiFi controller. 24 */ 25 public class WifiPowerCalculator extends PowerCalculator { 26 private static final boolean DEBUG = BatteryStatsHelper.DEBUG; 27 private static final String TAG = "WifiPowerCalculator"; 28 private final double mIdleCurrentMa; 29 private final double mTxCurrentMa; 30 private final double mRxCurrentMa; 31 private double mTotalAppPowerDrain = 0; 32 private long mTotalAppRunningTime = 0; 33 WifiPowerCalculator(PowerProfile profile)34 public WifiPowerCalculator(PowerProfile profile) { 35 mIdleCurrentMa = profile.getAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_IDLE); 36 mTxCurrentMa = profile.getAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_TX); 37 mRxCurrentMa = profile.getAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_RX); 38 } 39 40 @Override calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs, long rawUptimeUs, int statsType)41 public void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs, 42 long rawUptimeUs, int statsType) { 43 final BatteryStats.ControllerActivityCounter counter = u.getWifiControllerActivity(); 44 if (counter == null) { 45 return; 46 } 47 48 final long idleTime = counter.getIdleTimeCounter().getCountLocked(statsType); 49 final long txTime = counter.getTxTimeCounters()[0].getCountLocked(statsType); 50 final long rxTime = counter.getRxTimeCounter().getCountLocked(statsType); 51 app.wifiRunningTimeMs = idleTime + rxTime + txTime; 52 mTotalAppRunningTime += app.wifiRunningTimeMs; 53 54 app.wifiPowerMah = 55 ((idleTime * mIdleCurrentMa) + (txTime * mTxCurrentMa) + (rxTime * mRxCurrentMa)) 56 / (1000*60*60); 57 mTotalAppPowerDrain += app.wifiPowerMah; 58 59 app.wifiRxPackets = u.getNetworkActivityPackets(BatteryStats.NETWORK_WIFI_RX_DATA, 60 statsType); 61 app.wifiTxPackets = u.getNetworkActivityPackets(BatteryStats.NETWORK_WIFI_TX_DATA, 62 statsType); 63 app.wifiRxBytes = u.getNetworkActivityBytes(BatteryStats.NETWORK_WIFI_RX_DATA, 64 statsType); 65 app.wifiTxBytes = u.getNetworkActivityBytes(BatteryStats.NETWORK_WIFI_TX_DATA, 66 statsType); 67 68 if (DEBUG && app.wifiPowerMah != 0) { 69 Log.d(TAG, "UID " + u.getUid() + ": idle=" + idleTime + "ms rx=" + rxTime + "ms tx=" + 70 txTime + "ms power=" + BatteryStatsHelper.makemAh(app.wifiPowerMah)); 71 } 72 } 73 74 @Override calculateRemaining(BatterySipper app, BatteryStats stats, long rawRealtimeUs, long rawUptimeUs, int statsType)75 public void calculateRemaining(BatterySipper app, BatteryStats stats, long rawRealtimeUs, 76 long rawUptimeUs, int statsType) { 77 final BatteryStats.ControllerActivityCounter counter = stats.getWifiControllerActivity(); 78 79 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(statsType); 80 final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(statsType); 81 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(statsType); 82 83 app.wifiRunningTimeMs = Math.max(0, 84 (idleTimeMs + rxTimeMs + txTimeMs) - mTotalAppRunningTime); 85 86 double powerDrainMah = counter.getPowerCounter().getCountLocked(statsType) 87 / (double)(1000*60*60); 88 if (powerDrainMah == 0) { 89 // Some controllers do not report power drain, so we can calculate it here. 90 powerDrainMah = ((idleTimeMs * mIdleCurrentMa) + (txTimeMs * mTxCurrentMa) 91 + (rxTimeMs * mRxCurrentMa)) / (1000*60*60); 92 } 93 app.wifiPowerMah = Math.max(0, powerDrainMah - mTotalAppPowerDrain); 94 95 if (DEBUG) { 96 Log.d(TAG, "left over WiFi power: " + BatteryStatsHelper.makemAh(app.wifiPowerMah)); 97 } 98 } 99 100 @Override reset()101 public void reset() { 102 mTotalAppPowerDrain = 0; 103 mTotalAppRunningTime = 0; 104 } 105 } 106