Home | History | Annotate | Download | only in os
      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 
     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
     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
     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
    101     public void reset() {
    102         mTotalAppPowerDrain = 0;
    103         mTotalAppRunningTime = 0;
    104     }
    105 }
    106