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.ArrayMap; 20e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinskiimport android.util.Log; 21e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski 22e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinskipublic class WakelockPowerCalculator extends PowerCalculator { 23e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski private static final String TAG = "WakelockPowerCalculator"; 24e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski private static final boolean DEBUG = BatteryStatsHelper.DEBUG; 25e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski private final double mPowerWakelock; 26e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski private long mTotalAppWakelockTimeMs = 0; 27e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski 28e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski public WakelockPowerCalculator(PowerProfile profile) { 29e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski mPowerWakelock = profile.getAveragePower(PowerProfile.POWER_CPU_AWAKE); 30e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski } 31e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski 32e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski @Override 33f7808b7cf073175eb34a95760ef01e3dd61dd3eeAdam Lesinski public void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs, 34f7808b7cf073175eb34a95760ef01e3dd61dd3eeAdam Lesinski long rawUptimeUs, int statsType) { 35e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski long wakeLockTimeUs = 0; 36e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelockStats = 37e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski u.getWakelockStats(); 38e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski final int wakelockStatsCount = wakelockStats.size(); 39e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski for (int i = 0; i < wakelockStatsCount; i++) { 40e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski final BatteryStats.Uid.Wakelock wakelock = wakelockStats.valueAt(i); 41e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski 42e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski // Only care about partial wake locks since full wake locks 43e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski // are canceled when the user turns the screen off. 44e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski BatteryStats.Timer timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL); 45e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski if (timer != null) { 46e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski wakeLockTimeUs += timer.getTotalTimeLocked(rawRealtimeUs, statsType); 47e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski } 48e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski } 49e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski app.wakeLockTimeMs = wakeLockTimeUs / 1000; // convert to millis 50e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski mTotalAppWakelockTimeMs += app.wakeLockTimeMs; 51e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski 52e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski // Add cost of holding a wake lock. 53e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski app.wakeLockPowerMah = (app.wakeLockTimeMs * mPowerWakelock) / (1000*60*60); 54e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski if (DEBUG && app.wakeLockPowerMah != 0) { 55e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski Log.d(TAG, "UID " + u.getUid() + ": wake " + app.wakeLockTimeMs 56e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski + " power=" + BatteryStatsHelper.makemAh(app.wakeLockPowerMah)); 57e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski } 58e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski } 59e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski 60e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski @Override 61e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski public void calculateRemaining(BatterySipper app, BatteryStats stats, long rawRealtimeUs, 62e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski long rawUptimeUs, int statsType) { 63e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski long wakeTimeMillis = stats.getBatteryUptime(rawUptimeUs) / 1000; 64e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski wakeTimeMillis -= mTotalAppWakelockTimeMs 65e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski + (stats.getScreenOnTime(rawRealtimeUs, statsType) / 1000); 66e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski if (wakeTimeMillis > 0) { 67e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski final double power = (wakeTimeMillis * mPowerWakelock) / (1000*60*60); 68e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski if (DEBUG) { 69e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski Log.d(TAG, "OS wakeLockTime " + wakeTimeMillis + " power " 70e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski + BatteryStatsHelper.makemAh(power)); 71e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski } 72e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski app.wakeLockTimeMs += wakeTimeMillis; 73e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski app.wakeLockPowerMah += power; 74e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski } 75e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski } 76e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski 77e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski @Override 78e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski public void reset() { 79e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski mTotalAppWakelockTimeMs = 0; 80e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski } 81e08af19fcc7b13d526f3dfd24d58300947cf1146Adam Lesinski} 82