1 /* 2 * Copyright (C) 2020 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 17 package com.android.internal.os; 18 19 import android.os.BatteryConsumer; 20 import android.os.BatteryStats; 21 import android.os.BatteryUsageStats; 22 import android.os.BatteryUsageStatsQuery; 23 import android.util.Log; 24 25 /** 26 * Estimates the amount of power consumed when the device is idle. 27 */ 28 public class IdlePowerCalculator extends PowerCalculator { 29 private static final String TAG = "IdlePowerCalculator"; 30 private static final boolean DEBUG = PowerCalculator.DEBUG; 31 private final double mAveragePowerCpuSuspendMahPerUs; 32 private final double mAveragePowerCpuIdleMahPerUs; 33 public long mDurationMs; 34 public double mPowerMah; 35 IdlePowerCalculator(PowerProfile powerProfile)36 public IdlePowerCalculator(PowerProfile powerProfile) { 37 mAveragePowerCpuSuspendMahPerUs = 38 powerProfile.getAveragePower(PowerProfile.POWER_CPU_SUSPEND) 39 / (60 * 60 * 1_000_000.0); 40 mAveragePowerCpuIdleMahPerUs = 41 powerProfile.getAveragePower(PowerProfile.POWER_CPU_IDLE) 42 / (60 * 60 * 1_000_000.0); 43 } 44 45 @Override isPowerComponentSupported(@atteryConsumer.PowerComponent int powerComponent)46 public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { 47 return powerComponent == BatteryConsumer.POWER_COMPONENT_IDLE; 48 } 49 50 @Override calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query)51 public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, 52 long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { 53 calculatePowerAndDuration(batteryStats, rawRealtimeUs, rawUptimeUs, 54 BatteryStats.STATS_SINCE_CHARGED); 55 if (mPowerMah != 0) { 56 builder.getAggregateBatteryConsumerBuilder( 57 BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) 58 .setConsumedPower(BatteryConsumer.POWER_COMPONENT_IDLE, mPowerMah) 59 .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_IDLE, mDurationMs); 60 } 61 } 62 63 /** 64 * Calculates the baseline power usage for the device when it is in suspend and idle. 65 * The device is drawing POWER_CPU_SUSPEND power at its lowest power state. 66 * The device is drawing POWER_CPU_SUSPEND + POWER_CPU_IDLE power when a wakelock is held. 67 */ calculatePowerAndDuration(BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, int statsType)68 private void calculatePowerAndDuration(BatteryStats batteryStats, long rawRealtimeUs, 69 long rawUptimeUs, int statsType) { 70 long batteryRealtimeUs = batteryStats.computeBatteryRealtime(rawRealtimeUs, statsType); 71 long batteryUptimeUs = batteryStats.computeBatteryUptime(rawUptimeUs, statsType); 72 if (DEBUG) { 73 Log.d(TAG, "Battery type time: realtime=" + (batteryRealtimeUs / 1000) + " uptime=" 74 + (batteryUptimeUs / 1000)); 75 } 76 77 final double suspendPowerMah = batteryRealtimeUs * mAveragePowerCpuSuspendMahPerUs; 78 final double idlePowerMah = batteryUptimeUs * mAveragePowerCpuIdleMahPerUs; 79 mPowerMah = suspendPowerMah + idlePowerMah; 80 if (DEBUG && mPowerMah != 0) { 81 Log.d(TAG, "Suspend: time=" + (batteryRealtimeUs / 1000) 82 + " power=" + BatteryStats.formatCharge(suspendPowerMah)); 83 Log.d(TAG, "Idle: time=" + (batteryUptimeUs / 1000) 84 + " power=" + BatteryStats.formatCharge(idlePowerMah)); 85 } 86 mDurationMs = batteryRealtimeUs / 1000; 87 } 88 } 89