diff options
6 files changed, 74 insertions, 28 deletions
diff --git a/core/java/android/os/BatteryUsageStatsQuery.java b/core/java/android/os/BatteryUsageStatsQuery.java index 5b5fe1d15a82..17cb735eea49 100644 --- a/core/java/android/os/BatteryUsageStatsQuery.java +++ b/core/java/android/os/BatteryUsageStatsQuery.java @@ -79,6 +79,14 @@ public final class BatteryUsageStatsQuery implements Parcelable { return mUserIds; } + /** + * Returns true if the power calculations must be based on the PowerProfile constants, + * even if measured energy data is available. + */ + public boolean shouldForceUsePowerProfileModel() { + return (mFlags & FLAG_BATTERY_USAGE_STATS_POWER_PROFILE_MODEL) != 0; + } + private BatteryUsageStatsQuery(Parcel in) { mFlags = in.readInt(); mUserIds = new int[in.readInt()]; diff --git a/core/java/com/android/internal/os/AmbientDisplayPowerCalculator.java b/core/java/com/android/internal/os/AmbientDisplayPowerCalculator.java index 13130902feb8..e153eb2f0933 100644 --- a/core/java/com/android/internal/os/AmbientDisplayPowerCalculator.java +++ b/core/java/com/android/internal/os/AmbientDisplayPowerCalculator.java @@ -46,14 +46,12 @@ public class AmbientDisplayPowerCalculator extends PowerCalculator { long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { final long durationMs = calculateDuration(batteryStats, rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED); - final double powerMah = mPowerEstimator.calculatePower(durationMs); - if (powerMah > 0) { - builder.getOrCreateSystemBatteryConsumerBuilder( - SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY) - .setConsumedPower(BatteryConsumer.POWER_COMPONENT_USAGE, powerMah) - .setUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_USAGE, durationMs); - } - // TODO(b/178140704): Attribute *measured* total usage for BatteryUsageStats. + final double powerMah = getMeasuredOrEstimatedPower(batteryStats.getScreenDozeEnergy(), + mPowerEstimator, durationMs, query.shouldForceUsePowerProfileModel()); + builder.getOrCreateSystemBatteryConsumerBuilder( + SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_USAGE, powerMah) + .setUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_USAGE, durationMs); } /** @@ -66,8 +64,8 @@ public class AmbientDisplayPowerCalculator extends PowerCalculator { public void calculate(List<BatterySipper> sippers, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, int statsType, SparseArray<UserHandle> asUsers) { final long durationMs = calculateDuration(batteryStats, rawRealtimeUs, statsType); - final double powerMah = getMeasuredOrEstimatedPower( - batteryStats.getScreenDozeEnergy(), durationMs); + final double powerMah = getMeasuredOrEstimatedPower(batteryStats.getScreenDozeEnergy(), + mPowerEstimator, durationMs, false); if (powerMah > 0) { BatterySipper bs = new BatterySipper(BatterySipper.DrainType.AMBIENT_DISPLAY, null, 0); bs.usagePowerMah = powerMah; @@ -81,11 +79,4 @@ public class AmbientDisplayPowerCalculator extends PowerCalculator { return batteryStats.getScreenDozeTime(rawRealtimeUs, statsType) / 1000; } - private double getMeasuredOrEstimatedPower(long measuredEnergyUJ, long durationMs) { - if (measuredEnergyUJ != BatteryStats.ENERGY_DATA_UNAVAILABLE) { - return uJtoMah(measuredEnergyUJ); - } else { - return mPowerEstimator.calculatePower(durationMs); - } - } } diff --git a/core/java/com/android/internal/os/PowerCalculator.java b/core/java/com/android/internal/os/PowerCalculator.java index 7c45cc09e18c..fe4fb7afa1f5 100644 --- a/core/java/com/android/internal/os/PowerCalculator.java +++ b/core/java/com/android/internal/os/PowerCalculator.java @@ -113,6 +113,19 @@ public abstract class PowerCalculator { } /** + * Returns either the measured energy converted to mAh or a usage-based estimate. + */ + protected static double getMeasuredOrEstimatedPower(long measuredEnergyUj, + UsageBasedPowerEstimator powerEstimator, long durationMs, + boolean forceUsePowerProfileModel) { + if (measuredEnergyUj != BatteryStats.ENERGY_DATA_UNAVAILABLE + && !forceUsePowerProfileModel) { + return uJtoMah(measuredEnergyUj); + } + return powerEstimator.calculatePower(durationMs); + } + + /** * Converts charge in mAh to string. */ public static String formatCharge(double power) { diff --git a/core/java/com/android/internal/os/ScreenPowerCalculator.java b/core/java/com/android/internal/os/ScreenPowerCalculator.java index c1dd7ce662f7..5dca8d5e70fa 100644 --- a/core/java/com/android/internal/os/ScreenPowerCalculator.java +++ b/core/java/com/android/internal/os/ScreenPowerCalculator.java @@ -61,12 +61,10 @@ public class ScreenPowerCalculator extends PowerCalculator { public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { final PowerAndDuration totalPowerAndDuration = new PowerAndDuration(); - final boolean forceUsePowerProfileModel = (query.getFlags() - & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_POWER_PROFILE_MODEL) != 0; final boolean useEnergyData = calculateTotalDurationAndPower(totalPowerAndDuration, batteryStats, rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED, - forceUsePowerProfileModel); + query.shouldForceUsePowerProfileModel()); builder.getOrCreateSystemBatteryConsumerBuilder(SystemBatteryConsumer.DRAIN_TYPE_SCREEN) .setUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_USAGE, diff --git a/core/tests/coretests/src/com/android/internal/os/AmbientDisplayPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/AmbientDisplayPowerCalculatorTest.java index e2a106484848..add04698e372 100644 --- a/core/tests/coretests/src/com/android/internal/os/AmbientDisplayPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/AmbientDisplayPowerCalculatorTest.java @@ -19,6 +19,7 @@ package com.android.internal.os; import static com.google.common.truth.Truth.assertThat; import android.os.BatteryConsumer; +import android.os.BatteryUsageStatsQuery; import android.os.SystemBatteryConsumer; import android.view.Display; @@ -33,18 +34,29 @@ import org.junit.runner.RunWith; @SmallTest public class AmbientDisplayPowerCalculatorTest { private static final double PRECISION = 0.00001; + private static final long MINUTE_IN_MS = 60 * 1000; @Rule public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() - .setAveragePower(PowerProfile.POWER_AMBIENT_DISPLAY, 360.0); + .setAveragePower(PowerProfile.POWER_AMBIENT_DISPLAY, 10.0); @Test - public void testTimerBasedModel() { + public void testMeasuredEnergyBasedModel() { BatteryStatsImpl stats = mStatsRule.getBatteryStats(); - stats.noteScreenStateLocked(Display.STATE_ON, 1000, 1000, 1000); - stats.noteScreenStateLocked(Display.STATE_DOZE, 2000, 2000, 2000); - stats.noteScreenStateLocked(Display.STATE_OFF, 3000, 3000, 3000); + stats.updateDisplayEnergyLocked(300_000_000, Display.STATE_ON, 0); + + stats.noteScreenStateLocked(Display.STATE_DOZE, 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS, + 30 * MINUTE_IN_MS); + + stats.updateDisplayEnergyLocked(200_000_000, Display.STATE_DOZE, + 30 * MINUTE_IN_MS); + + stats.noteScreenStateLocked(Display.STATE_OFF, 120 * MINUTE_IN_MS, 120 * MINUTE_IN_MS, + 120 * MINUTE_IN_MS); + + stats.updateDisplayEnergyLocked(100_000_000, Display.STATE_OFF, + 120 * MINUTE_IN_MS); AmbientDisplayPowerCalculator calculator = new AmbientDisplayPowerCalculator(mStatsRule.getPowerProfile()); @@ -55,8 +67,32 @@ public class AmbientDisplayPowerCalculatorTest { mStatsRule.getSystemBatteryConsumer( SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY); assertThat(consumer.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_USAGE)) - .isEqualTo(1000); + .isEqualTo(90 * MINUTE_IN_MS); + assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_USAGE)) + .isWithin(PRECISION).of(7.5075075); + } + + @Test + public void testPowerProfileBasedModel() { + BatteryStatsImpl stats = mStatsRule.getBatteryStats(); + + stats.noteScreenStateLocked(Display.STATE_DOZE, 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS, + 30 * MINUTE_IN_MS); + stats.noteScreenStateLocked(Display.STATE_OFF, 120 * MINUTE_IN_MS, 120 * MINUTE_IN_MS, + 120 * MINUTE_IN_MS); + + AmbientDisplayPowerCalculator calculator = + new AmbientDisplayPowerCalculator(mStatsRule.getPowerProfile()); + + mStatsRule.apply(new BatteryUsageStatsQuery.Builder().powerProfileModeledOnly().build(), + calculator); + + SystemBatteryConsumer consumer = + mStatsRule.getSystemBatteryConsumer( + SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY); + assertThat(consumer.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_USAGE)) + .isEqualTo(90 * MINUTE_IN_MS); assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_USAGE)) - .isWithin(PRECISION).of(0.1); + .isWithin(PRECISION).of(15.0); } } diff --git a/core/tests/coretests/src/com/android/internal/os/ScreenPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/ScreenPowerCalculatorTest.java index 717fac0c7bf8..86e615c035c7 100644 --- a/core/tests/coretests/src/com/android/internal/os/ScreenPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/ScreenPowerCalculatorTest.java @@ -48,7 +48,7 @@ public class ScreenPowerCalculatorTest { .setAveragePower(PowerProfile.POWER_SCREEN_FULL, 48.0); @Test - public void testEnergyBasedModel() { + public void testMeasuredEnergyBasedModel() { BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats(); batteryStats.noteScreenStateLocked(Display.STATE_ON, 0, 0, 0); |