Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8c2e375c authored by Dmitri Plotnikov's avatar Dmitri Plotnikov
Browse files

Measured energy for Ambient Display in BatteryUsageStats

Bug: 178140704
Test: atest FrameworksCoreTests:com.android.internal.os.AmbientDisplayPowerCalculatorTest

Change-Id: I1a573c3e380777637b7c0466aa78a4cab4c05887
parent 8093735b
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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()];
+8 −17
Original line number Diff line number Diff line
@@ -46,15 +46,13 @@ 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) {
        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);
    }
        // TODO(b/178140704): Attribute *measured* total usage for BatteryUsageStats.
    }

    /**
     * Ambient display power is the additional power the screen takes while in ambient display/
@@ -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);
        }
    }
}
+13 −0
Original line number Diff line number Diff line
@@ -112,6 +112,19 @@ public abstract class PowerCalculator {
    public void reset() {
    }

    /**
     * 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.
     */
+1 −3
Original line number Diff line number Diff line
@@ -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,
+43 −7
Original line number Diff line number Diff line
@@ -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);
    }
}
Loading