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 public class BluetoothPowerCalculator extends PowerCalculator {
22     private static final boolean DEBUG = BatteryStatsHelper.DEBUG;
23     private static final String TAG = "BluetoothPowerCalculator";
24     private final double mIdleMa;
25     private final double mRxMa;
26     private final double mTxMa;
27     private double mAppTotalPowerMah = 0;
28     private long mAppTotalTimeMs = 0;
29 
BluetoothPowerCalculator(PowerProfile profile)30     public BluetoothPowerCalculator(PowerProfile profile) {
31         mIdleMa = profile.getAveragePower(PowerProfile.POWER_BLUETOOTH_CONTROLLER_IDLE);
32         mRxMa = profile.getAveragePower(PowerProfile.POWER_BLUETOOTH_CONTROLLER_RX);
33         mTxMa = profile.getAveragePower(PowerProfile.POWER_BLUETOOTH_CONTROLLER_TX);
34     }
35 
36     @Override
calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs, long rawUptimeUs, int statsType)37     public void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
38                              long rawUptimeUs, int statsType) {
39 
40         final BatteryStats.ControllerActivityCounter counter = u.getBluetoothControllerActivity();
41         if (counter == null) {
42             return;
43         }
44 
45         final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(statsType);
46         final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(statsType);
47         final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(statsType);
48         final long totalTimeMs = idleTimeMs + txTimeMs + rxTimeMs;
49         double powerMah = counter.getPowerCounter().getCountLocked(statsType)
50                 / (double)(1000*60*60);
51 
52         if (powerMah == 0) {
53             powerMah = ((idleTimeMs * mIdleMa) + (rxTimeMs * mRxMa) + (txTimeMs * mTxMa))
54                     / (1000*60*60);
55         }
56 
57         app.bluetoothPowerMah = powerMah;
58         app.bluetoothRunningTimeMs = totalTimeMs;
59         app.btRxBytes = u.getNetworkActivityBytes(BatteryStats.NETWORK_BT_RX_DATA, statsType);
60         app.btTxBytes = u.getNetworkActivityBytes(BatteryStats.NETWORK_BT_TX_DATA, statsType);
61 
62         mAppTotalPowerMah += powerMah;
63         mAppTotalTimeMs += totalTimeMs;
64     }
65 
66     @Override
calculateRemaining(BatterySipper app, BatteryStats stats, long rawRealtimeUs, long rawUptimeUs, int statsType)67     public void calculateRemaining(BatterySipper app, BatteryStats stats, long rawRealtimeUs,
68                                    long rawUptimeUs, int statsType) {
69         final BatteryStats.ControllerActivityCounter counter =
70                 stats.getBluetoothControllerActivity();
71 
72         final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(statsType);
73         final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(statsType);
74         final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(statsType);
75         final long totalTimeMs = idleTimeMs + txTimeMs + rxTimeMs;
76         double powerMah = counter.getPowerCounter().getCountLocked(statsType)
77                  / (double)(1000*60*60);
78 
79         if (powerMah == 0) {
80             // Some devices do not report the power, so calculate it.
81             powerMah = ((idleTimeMs * mIdleMa) + (rxTimeMs * mRxMa) + (txTimeMs * mTxMa))
82                     / (1000*60*60);
83         }
84 
85         // Subtract what the apps used, but clamp to 0.
86         powerMah = Math.max(0, powerMah - mAppTotalPowerMah);
87 
88         if (DEBUG && powerMah != 0) {
89             Log.d(TAG, "Bluetooth active: time=" + (totalTimeMs)
90                     + " power=" + BatteryStatsHelper.makemAh(powerMah));
91         }
92 
93         app.bluetoothPowerMah = powerMah;
94         app.bluetoothRunningTimeMs = Math.max(0, totalTimeMs - mAppTotalTimeMs);
95     }
96 
97     @Override
reset()98     public void reset() {
99         mAppTotalPowerMah = 0;
100         mAppTotalTimeMs = 0;
101     }
102 }
103