1e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski/* 2e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski * Copyright (C) 2015 The Android Open Source Project 3e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski * 4e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski * you may not use this file except in compliance with the License. 6e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski * You may obtain a copy of the License at 7e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski * 8e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski * 10e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski * Unless required by applicable law or agreed to in writing, software 11e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski * See the License for the specific language governing permissions and 14e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski * limitations under the License. 15e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski */ 16e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinskipackage com.android.internal.os; 17e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski 18e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinskiimport android.os.BatteryStats; 19e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinskiimport android.util.Log; 20e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski 21e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinskipublic class BluetoothPowerCalculator extends PowerCalculator { 22e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski private static final boolean DEBUG = BatteryStatsHelper.DEBUG; 23e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski private static final String TAG = "BluetoothPowerCalculator"; 248576cf941dc20b64d60b6b7f5d0879b823628393Adam Lesinski private final double mIdleMa; 258576cf941dc20b64d60b6b7f5d0879b823628393Adam Lesinski private final double mRxMa; 268576cf941dc20b64d60b6b7f5d0879b823628393Adam Lesinski private final double mTxMa; 279f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski private double mAppTotalPowerMah = 0; 289f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski private long mAppTotalTimeMs = 0; 298576cf941dc20b64d60b6b7f5d0879b823628393Adam Lesinski 308576cf941dc20b64d60b6b7f5d0879b823628393Adam Lesinski public BluetoothPowerCalculator(PowerProfile profile) { 318576cf941dc20b64d60b6b7f5d0879b823628393Adam Lesinski mIdleMa = profile.getAveragePower(PowerProfile.POWER_BLUETOOTH_CONTROLLER_IDLE); 328576cf941dc20b64d60b6b7f5d0879b823628393Adam Lesinski mRxMa = profile.getAveragePower(PowerProfile.POWER_BLUETOOTH_CONTROLLER_RX); 338576cf941dc20b64d60b6b7f5d0879b823628393Adam Lesinski mTxMa = profile.getAveragePower(PowerProfile.POWER_BLUETOOTH_CONTROLLER_TX); 348576cf941dc20b64d60b6b7f5d0879b823628393Adam Lesinski } 35e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski 36e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski @Override 37e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski public void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs, 38e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski long rawUptimeUs, int statsType) { 399f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski 409f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski final BatteryStats.ControllerActivityCounter counter = u.getBluetoothControllerActivity(); 419f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski if (counter == null) { 429f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski return; 439f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski } 449f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski 459f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(statsType); 469f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(statsType); 479f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(statsType); 489f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski final long totalTimeMs = idleTimeMs + txTimeMs + rxTimeMs; 499f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski double powerMah = counter.getPowerCounter().getCountLocked(statsType) 509f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski / (double)(1000*60*60); 519f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski 529f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski if (powerMah == 0) { 539f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski powerMah = ((idleTimeMs * mIdleMa) + (rxTimeMs * mRxMa) + (txTimeMs * mTxMa)) 549f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski / (1000*60*60); 559f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski } 569f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski 579f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski app.bluetoothPowerMah = powerMah; 589f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski app.bluetoothRunningTimeMs = totalTimeMs; 599f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski app.btRxBytes = u.getNetworkActivityBytes(BatteryStats.NETWORK_BT_RX_DATA, statsType); 609f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski app.btTxBytes = u.getNetworkActivityBytes(BatteryStats.NETWORK_BT_TX_DATA, statsType); 619f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski 629f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski mAppTotalPowerMah += powerMah; 639f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski mAppTotalTimeMs += totalTimeMs; 64e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski } 65e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski 66e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski @Override 67e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski public void calculateRemaining(BatterySipper app, BatteryStats stats, long rawRealtimeUs, 68e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski long rawUptimeUs, int statsType) { 6921f76aa77075be5e057c36040d7d6e695c669b72Adam Lesinski final BatteryStats.ControllerActivityCounter counter = 7021f76aa77075be5e057c36040d7d6e695c669b72Adam Lesinski stats.getBluetoothControllerActivity(); 7121f76aa77075be5e057c36040d7d6e695c669b72Adam Lesinski 7221f76aa77075be5e057c36040d7d6e695c669b72Adam Lesinski final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(statsType); 7321f76aa77075be5e057c36040d7d6e695c669b72Adam Lesinski final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(statsType); 7421f76aa77075be5e057c36040d7d6e695c669b72Adam Lesinski final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(statsType); 75e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski final long totalTimeMs = idleTimeMs + txTimeMs + rxTimeMs; 7621f76aa77075be5e057c36040d7d6e695c669b72Adam Lesinski double powerMah = counter.getPowerCounter().getCountLocked(statsType) 7721f76aa77075be5e057c36040d7d6e695c669b72Adam Lesinski / (double)(1000*60*60); 788576cf941dc20b64d60b6b7f5d0879b823628393Adam Lesinski 798576cf941dc20b64d60b6b7f5d0879b823628393Adam Lesinski if (powerMah == 0) { 808576cf941dc20b64d60b6b7f5d0879b823628393Adam Lesinski // Some devices do not report the power, so calculate it. 818576cf941dc20b64d60b6b7f5d0879b823628393Adam Lesinski powerMah = ((idleTimeMs * mIdleMa) + (rxTimeMs * mRxMa) + (txTimeMs * mTxMa)) 828576cf941dc20b64d60b6b7f5d0879b823628393Adam Lesinski / (1000*60*60); 838576cf941dc20b64d60b6b7f5d0879b823628393Adam Lesinski } 84e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski 859f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski // Subtract what the apps used, but clamp to 0. 869f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski powerMah = Math.max(0, powerMah - mAppTotalPowerMah); 879f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski 88e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski if (DEBUG && powerMah != 0) { 89e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski Log.d(TAG, "Bluetooth active: time=" + (totalTimeMs) 90e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski + " power=" + BatteryStatsHelper.makemAh(powerMah)); 91e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski } 92e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski 939f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski app.bluetoothPowerMah = powerMah; 949f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski app.bluetoothRunningTimeMs = Math.max(0, totalTimeMs - mAppTotalTimeMs); 959f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski } 969f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski 979f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski @Override 989f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski public void reset() { 999f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski mAppTotalPowerMah = 0; 1009f55cc71b9b0a27604d448b5c54e3c377b7a067fAdam Lesinski mAppTotalTimeMs = 0; 101e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski } 102e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski} 103