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

Commit e280aaca authored by Michael Wachenschwanz's avatar Michael Wachenschwanz
Browse files

Update Screen and AmbientDisplay Power Calculators for multi-display

Bug: 200239964
Test: atest ScreenPowerCalculatorTest
Test: atest AmbientDisplayPowerCalculatorTest
Change-Id: I45abcf872de7239040f84b26bd9aa2af07cfaa7c
parent e031d509
Loading
Loading
Loading
Loading
+33 −9
Original line number Diff line number Diff line
@@ -31,12 +31,15 @@ import java.util.List;
 * Estimates power consumed by the ambient display
 */
public class AmbientDisplayPowerCalculator extends PowerCalculator {
    private final UsageBasedPowerEstimator mPowerEstimator;
    private final UsageBasedPowerEstimator[] mPowerEstimators;

    public AmbientDisplayPowerCalculator(PowerProfile powerProfile) {
        // TODO(b/200239964): update to support multidisplay.
        mPowerEstimator = new UsageBasedPowerEstimator(
                powerProfile.getAveragePowerForOrdinal(POWER_GROUP_DISPLAY_AMBIENT, 0));
        final int numDisplays = powerProfile.getNumDisplays();
        mPowerEstimators = new UsageBasedPowerEstimator[numDisplays];
        for (int display = 0; display < numDisplays; display++) {
            mPowerEstimators[display] = new UsageBasedPowerEstimator(
                    powerProfile.getAveragePowerForOrdinal(POWER_GROUP_DISPLAY_AMBIENT, display));
        }
    }

    /**
@@ -50,8 +53,8 @@ public class AmbientDisplayPowerCalculator extends PowerCalculator {
        final int powerModel = getPowerModel(measuredEnergyUC, query);
        final long durationMs = calculateDuration(batteryStats, rawRealtimeUs,
                BatteryStats.STATS_SINCE_CHARGED);
        final double powerMah = getMeasuredOrEstimatedPower(powerModel,
                measuredEnergyUC, mPowerEstimator, durationMs);
        final double powerMah = calculateTotalPower(powerModel, batteryStats, rawRealtimeUs,
                measuredEnergyUC);
        builder.getAggregateBatteryConsumerBuilder(
                BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
                .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY, durationMs)
@@ -71,9 +74,8 @@ public class AmbientDisplayPowerCalculator extends PowerCalculator {
        final long measuredEnergyUC = batteryStats.getScreenDozeMeasuredBatteryConsumptionUC();
        final long durationMs = calculateDuration(batteryStats, rawRealtimeUs, statsType);
        final int powerModel = getPowerModel(measuredEnergyUC);
        final double powerMah = getMeasuredOrEstimatedPower(powerModel,
                batteryStats.getScreenDozeMeasuredBatteryConsumptionUC(),
                mPowerEstimator, durationMs);
        final double powerMah = calculateTotalPower(powerModel, batteryStats, rawRealtimeUs,
                measuredEnergyUC);
        if (powerMah > 0) {
            BatterySipper bs = new BatterySipper(BatterySipper.DrainType.AMBIENT_DISPLAY, null, 0);
            bs.usagePowerMah = powerMah;
@@ -86,4 +88,26 @@ public class AmbientDisplayPowerCalculator extends PowerCalculator {
    private long calculateDuration(BatteryStats batteryStats, long rawRealtimeUs, int statsType) {
        return batteryStats.getScreenDozeTime(rawRealtimeUs, statsType) / 1000;
    }

    private double calculateTotalPower(@BatteryConsumer.PowerModel int powerModel,
            BatteryStats batteryStats, long rawRealtimeUs, long consumptionUC) {
        switch (powerModel) {
            case BatteryConsumer.POWER_MODEL_MEASURED_ENERGY:
                return uCtoMah(consumptionUC);
            case BatteryConsumer.POWER_MODEL_POWER_PROFILE:
            default:
                return calculateEstimatedPower(batteryStats, rawRealtimeUs);
        }
    }

    private double calculateEstimatedPower(BatteryStats batteryStats, long rawRealtimeUs) {
        final int numDisplays = mPowerEstimators.length;
        double power = 0;
        for (int display = 0; display < numDisplays; display++) {
            final long dozeTime = batteryStats.getDisplayScreenDozeTime(display, rawRealtimeUs)
                    / 1000;
            power += mPowerEstimators[display].calculatePower(dozeTime);
        }
        return power;
    }
}
+0 −26
Original line number Diff line number Diff line
@@ -132,32 +132,6 @@ public abstract class PowerCalculator {
                : BatteryConsumer.POWER_MODEL_POWER_PROFILE;
    }

    /**
     * Returns either the measured energy converted to mAh or a usage-based estimate.
     */
    protected static double getMeasuredOrEstimatedPower(@BatteryConsumer.PowerModel int powerModel,
            long measuredEnergyUC, UsageBasedPowerEstimator powerEstimator, long durationMs) {
        switch (powerModel) {
            case BatteryConsumer.POWER_MODEL_MEASURED_ENERGY:
                return uCtoMah(measuredEnergyUC);
            case BatteryConsumer.POWER_MODEL_POWER_PROFILE:
            default:
                return powerEstimator.calculatePower(durationMs);
        }
    }

    /**
     * Returns either the measured energy converted to mAh or a usage-based estimate.
     */
    protected static double getMeasuredOrEstimatedPower(
            long measuredEnergyUC, UsageBasedPowerEstimator powerEstimator, long durationMs) {
        if (measuredEnergyUC != BatteryStats.POWER_DATA_UNAVAILABLE) {
            return uCtoMah(measuredEnergyUC);
        } else {
            return powerEstimator.calculatePower(durationMs);
        }
    }

    /**
     * Prints formatted amount of power in milli-amp-hours.
     */
+31 −20
Original line number Diff line number Diff line
@@ -44,8 +44,8 @@ public class ScreenPowerCalculator extends PowerCalculator {
    // Minimum amount of time the screen should be on to start smearing drain to apps
    public static final long MIN_ACTIVE_TIME_FOR_SMEARING = 10 * DateUtils.MINUTE_IN_MILLIS;

    private final UsageBasedPowerEstimator mScreenOnPowerEstimator;
    private final UsageBasedPowerEstimator mScreenFullPowerEstimator;
    private final UsageBasedPowerEstimator[] mScreenOnPowerEstimators;
    private final UsageBasedPowerEstimator[] mScreenFullPowerEstimators;

    private static class PowerAndDuration {
        public long durationMs;
@@ -53,11 +53,16 @@ public class ScreenPowerCalculator extends PowerCalculator {
    }

    public ScreenPowerCalculator(PowerProfile powerProfile) {
        // TODO(b/200239964): update to support multidisplay.
        mScreenOnPowerEstimator = new UsageBasedPowerEstimator(
                powerProfile.getAveragePowerForOrdinal(POWER_GROUP_DISPLAY_SCREEN_ON, 0));
        mScreenFullPowerEstimator = new UsageBasedPowerEstimator(
                powerProfile.getAveragePowerForOrdinal(POWER_GROUP_DISPLAY_SCREEN_FULL, 0));
        final int numDisplays = powerProfile.getNumDisplays();
        mScreenOnPowerEstimators = new UsageBasedPowerEstimator[numDisplays];
        mScreenFullPowerEstimators = new UsageBasedPowerEstimator[numDisplays];
        for (int display = 0; display < numDisplays; display++) {
            mScreenOnPowerEstimators[display] = new UsageBasedPowerEstimator(
                    powerProfile.getAveragePowerForOrdinal(POWER_GROUP_DISPLAY_SCREEN_ON, display));
            mScreenFullPowerEstimators[display] = new UsageBasedPowerEstimator(
                    powerProfile.getAveragePowerForOrdinal(POWER_GROUP_DISPLAY_SCREEN_FULL,
                            display));
        }
    }

    @Override
@@ -172,7 +177,7 @@ public class ScreenPowerCalculator extends PowerCalculator {
            case BatteryConsumer.POWER_MODEL_POWER_PROFILE:
            default:
                totalPowerAndDuration.powerMah = calculateTotalPowerFromBrightness(batteryStats,
                        rawRealtimeUs, statsType, totalPowerAndDuration.durationMs);
                        rawRealtimeUs);
        }
    }

@@ -194,20 +199,26 @@ public class ScreenPowerCalculator extends PowerCalculator {
        return batteryStats.getScreenOnTime(rawRealtimeUs, statsType) / 1000;
    }

    private double calculateTotalPowerFromBrightness(BatteryStats batteryStats, long rawRealtimeUs,
            int statsType, long durationMs) {
        double power = mScreenOnPowerEstimator.calculatePower(durationMs);
        for (int i = 0; i < BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS; i++) {
            final long brightnessTime =
                    batteryStats.getScreenBrightnessTime(i, rawRealtimeUs, statsType) / 1000;
            final double binPowerMah = mScreenFullPowerEstimator.calculatePower(brightnessTime)
                    * (i + 0.5f) / BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS;
    private double calculateTotalPowerFromBrightness(BatteryStats batteryStats,
            long rawRealtimeUs) {
        final int numDisplays = mScreenOnPowerEstimators.length;
        double power = 0;
        for (int display = 0; display < numDisplays; display++) {
            final long displayTime = batteryStats.getDisplayScreenOnTime(display, rawRealtimeUs)
                    / 1000;
            power += mScreenOnPowerEstimators[display].calculatePower(displayTime);
            for (int bin = 0; bin < BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS; bin++) {
                final long brightnessTime = batteryStats.getDisplayScreenBrightnessTime(display,
                        bin, rawRealtimeUs) / 1000;
                final double binPowerMah = mScreenFullPowerEstimators[display].calculatePower(
                        brightnessTime) * (bin + 0.5f) / BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS;
                if (DEBUG && binPowerMah != 0) {
                Slog.d(TAG, "Screen bin #" + i + ": time=" + brightnessTime
                    Slog.d(TAG, "Screen bin #" + bin + ": time=" + brightnessTime
                            + " power=" + formatCharge(binPowerMah));
                }
                power += binPowerMah;
            }
        }
        return power;
    }

+34 −1
Original line number Diff line number Diff line
@@ -38,7 +38,8 @@ public class AmbientDisplayPowerCalculatorTest {

    @Rule
    public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
            .setAveragePowerForOrdinal(POWER_GROUP_DISPLAY_AMBIENT, 0, 10.0);
            .setAveragePowerForOrdinal(POWER_GROUP_DISPLAY_AMBIENT, 0, 10.0)
            .setNumDisplays(1);

    @Test
    public void testMeasuredEnergyBasedModel() {
@@ -96,4 +97,36 @@ public class AmbientDisplayPowerCalculatorTest {
        assertThat(consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY))
                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
    }

    @Test
    public void testPowerProfileBasedModel_multiDisplay() {
        mStatsRule.setAveragePowerForOrdinal(POWER_GROUP_DISPLAY_AMBIENT, 1, 20.0)
                .setNumDisplays(2);

        BatteryStatsImpl stats = mStatsRule.getBatteryStats();

        stats.noteScreenStateLocked(1, Display.STATE_OFF, 0, 0, 0);
        stats.noteScreenStateLocked(0, Display.STATE_DOZE, 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS,
                30 * MINUTE_IN_MS);
        stats.noteScreenStateLocked(1, Display.STATE_DOZE, 90 * MINUTE_IN_MS, 90 * MINUTE_IN_MS,
                90 * MINUTE_IN_MS);
        stats.noteScreenStateLocked(0, Display.STATE_OFF, 120 * MINUTE_IN_MS, 120 * MINUTE_IN_MS,
                120 * MINUTE_IN_MS);
        stats.noteScreenStateLocked(1, Display.STATE_OFF, 150 * MINUTE_IN_MS, 150 * MINUTE_IN_MS,
                150 * MINUTE_IN_MS);

        AmbientDisplayPowerCalculator calculator =
                new AmbientDisplayPowerCalculator(mStatsRule.getPowerProfile());

        mStatsRule.apply(BatteryUsageStatsRule.POWER_PROFILE_MODEL_ONLY, calculator);

        BatteryConsumer consumer = mStatsRule.getDeviceBatteryConsumer();
        // Duration should only be the union of
        assertThat(consumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY))
                .isEqualTo(120 * MINUTE_IN_MS);
        assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY))
                .isWithin(PRECISION).of(35.0);
        assertThat(consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY))
                .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -118,6 +118,12 @@ public class BatteryUsageStatsRule implements TestRule {
        return this;
    }

    public BatteryUsageStatsRule setNumDisplays(int value) {
        when(mPowerProfile.getNumDisplays()).thenReturn(value);
        mBatteryStats.setDisplayCountLocked(value);
        return this;
    }

    /** Call only after setting the power profile information. */
    public BatteryUsageStatsRule initMeasuredEnergyStatsLocked() {
        return initMeasuredEnergyStatsLocked(new String[0]);
Loading