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

Commit 8ac63071 authored by Michael Wachenschwanz's avatar Michael Wachenschwanz
Browse files

Update PowerProfile to support multidisplay devices

Replaced the display related power constants with new ones that support
multidisply.

The legacy constants are marked as UnsupportedAppUsage, so they have not
been removed yet and they attempting to read them will return the power
constant values for the first display.

Fixes: 200226329
Test: atest com.android.internal.os.PowerProfileTest#testPowerProfile
Test: atest FrameworksCoreTests:com.android.internal.os.BatteryStatsTests
Change-Id: Id181443bd6f553ee37fc4a1647d31644fcad7912
parent 782a906e
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.internal.os;

import static com.android.internal.os.PowerProfile.POWER_GROUP_DISPLAY_AMBIENT;

import android.os.BatteryConsumer;
import android.os.BatteryStats;
import android.os.BatteryUsageStats;
@@ -32,8 +34,9 @@ public class AmbientDisplayPowerCalculator extends PowerCalculator {
    private final UsageBasedPowerEstimator mPowerEstimator;

    public AmbientDisplayPowerCalculator(PowerProfile powerProfile) {
        // TODO(b/200239964): update to support multidisplay.
        mPowerEstimator = new UsageBasedPowerEstimator(
                powerProfile.getAveragePower(PowerProfile.POWER_AMBIENT_DISPLAY));
                powerProfile.getAveragePowerForOrdinal(POWER_GROUP_DISPLAY_AMBIENT, 0));
    }

    /**
+122 −0
Original line number Diff line number Diff line
@@ -17,10 +17,12 @@
package com.android.internal.os;


import android.annotation.StringDef;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.VisibleForTesting;
@@ -30,6 +32,8 @@ import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.HashMap;

@@ -40,6 +44,8 @@ import java.util.HashMap;
 */
public class PowerProfile {

    public static final String TAG = "PowerProfile";

    /*
     * POWER_CPU_SUSPEND: Power consumption when CPU is in power collapse mode.
     * POWER_CPU_IDLE: Power consumption when CPU is awake (when a wake lock is held). This should
@@ -145,12 +151,18 @@ public class PowerProfile {

    /**
     * Power consumption when screen is in doze/ambient/always-on mode, including backlight power.
     *
     * @deprecated Use {@link #POWER_GROUP_DISPLAY_AMBIENT} instead.
     */
    @Deprecated
    public static final String POWER_AMBIENT_DISPLAY = "ambient.on";

    /**
     * Power consumption when screen is on, not including the backlight power.
     *
     * @deprecated Use {@link #POWER_GROUP_DISPLAY_SCREEN_ON} instead.
     */
    @Deprecated
    @UnsupportedAppUsage
    public static final String POWER_SCREEN_ON = "screen.on";

@@ -175,7 +187,10 @@ public class PowerProfile {
    /**
     * Power consumption at full backlight brightness. If the backlight is at
     * 50% brightness, then this should be multiplied by 0.5
     *
     * @deprecated Use {@link #POWER_GROUP_DISPLAY_SCREEN_FULL} instead.
     */
    @Deprecated
    @UnsupportedAppUsage
    public static final String POWER_SCREEN_FULL = "screen.full";

@@ -220,6 +235,29 @@ public class PowerProfile {
     */
    public static final String POWER_BATTERY_CAPACITY = "battery.capacity";

    /**
     * Power consumption when a screen is in doze/ambient/always-on mode, including backlight power.
     */
    public static final String POWER_GROUP_DISPLAY_AMBIENT = "ambient.on.display";

    /**
     * Power consumption when a screen is on, not including the backlight power.
     */
    public static final String POWER_GROUP_DISPLAY_SCREEN_ON = "screen.on.display";

    /**
     * Power consumption of a screen at full backlight brightness.
     */
    public static final String POWER_GROUP_DISPLAY_SCREEN_FULL = "screen.full.display";

    @StringDef(prefix = { "POWER_GROUP_" }, value = {
            POWER_GROUP_DISPLAY_AMBIENT,
            POWER_GROUP_DISPLAY_SCREEN_ON,
            POWER_GROUP_DISPLAY_SCREEN_FULL,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface PowerGroup {}

    /**
     * A map from Power Use Item to its power consumption.
     */
@@ -255,6 +293,7 @@ public class PowerProfile {
                readPowerValuesFromXml(context, forTest);
            }
            initCpuClusters();
            initDisplays();
        }
    }

@@ -424,6 +463,58 @@ public class PowerProfile {
        return 0;
    }

    private int mNumDisplays;

    private void initDisplays() {
        // Figure out how many displays are listed in the power profile.
        mNumDisplays = 0;
        while (!Double.isNaN(
                getAveragePowerForOrdinal(POWER_GROUP_DISPLAY_AMBIENT, mNumDisplays, Double.NaN))
                || !Double.isNaN(
                getAveragePowerForOrdinal(POWER_GROUP_DISPLAY_SCREEN_ON, mNumDisplays, Double.NaN))
                || !Double.isNaN(
                getAveragePowerForOrdinal(POWER_GROUP_DISPLAY_SCREEN_FULL, mNumDisplays,
                        Double.NaN))) {
            mNumDisplays++;
        }

        // Handle legacy display power constants.
        final Double deprecatedAmbientDisplay = sPowerItemMap.get(POWER_AMBIENT_DISPLAY);
        boolean legacy = false;
        if (deprecatedAmbientDisplay != null && mNumDisplays == 0) {
            final String key = getOrdinalPowerType(POWER_GROUP_DISPLAY_AMBIENT, 0);
            Slog.w(TAG, POWER_AMBIENT_DISPLAY + " is deprecated! Use " + key + " instead.");
            sPowerItemMap.put(key, deprecatedAmbientDisplay);
            legacy = true;
        }

        final Double deprecatedScreenOn = sPowerItemMap.get(POWER_SCREEN_ON);
        if (deprecatedScreenOn != null && mNumDisplays == 0) {
            final String key = getOrdinalPowerType(POWER_GROUP_DISPLAY_SCREEN_ON, 0);
            Slog.w(TAG, POWER_SCREEN_ON + " is deprecated! Use " + key + " instead.");
            sPowerItemMap.put(key, deprecatedScreenOn);
            legacy = true;
        }

        final Double deprecatedScreenFull = sPowerItemMap.get(POWER_SCREEN_FULL);
        if (deprecatedScreenFull != null && mNumDisplays == 0) {
            final String key = getOrdinalPowerType(POWER_GROUP_DISPLAY_SCREEN_FULL, 0);
            Slog.w(TAG, POWER_SCREEN_FULL + " is deprecated! Use " + key + " instead.");
            sPowerItemMap.put(key, deprecatedScreenFull);
            legacy = true;
        }
        if (legacy) {
            mNumDisplays = 1;
        }
    }

    /**
     * Returns the number built in displays on the device as defined in the power_profile.xml.
     */
    public int getNumDisplays() {
        return mNumDisplays;
    }

    /**
     * Returns the number of memory bandwidth buckets defined in power_profile.xml, or a
     * default value if the subsystem has no recorded value.
@@ -495,6 +586,32 @@ public class PowerProfile {
        }
    }

    /**
     * Returns the average current in mA consumed by an ordinaled subsystem, or the given
     * default value if the subsystem has no recorded value.
     *
     * @param group        the subsystem {@link PowerGroup}.
     * @param ordinal      which entity in the {@link PowerGroup}.
     * @param defaultValue the value to return if the subsystem has no recorded value.
     * @return the average current in milliAmps.
     */
    public double getAveragePowerForOrdinal(@PowerGroup String group, int ordinal,
            double defaultValue) {
        final String type = getOrdinalPowerType(group, ordinal);
        return getAveragePowerOrDefault(type, defaultValue);
    }

    /**
     * Returns the average current in mA consumed by an ordinaled subsystem.
     *
     * @param group        the subsystem {@link PowerGroup}.
     * @param ordinal      which entity in the {@link PowerGroup}.
     * @return the average current in milliAmps.
     */
    public double getAveragePowerForOrdinal(@PowerGroup String group, int ordinal) {
        return getAveragePowerForOrdinal(group, ordinal, 0);
    }

    /**
     * Returns the battery capacity, if available, in milli Amp Hours. If not available,
     * it returns zero.
@@ -682,4 +799,9 @@ public class PowerProfile {
            }
        }
    }

    // Creates the key for an ordinaled power constant from the group and ordinal.
    private static String getOrdinalPowerType(@PowerGroup String group, int ordinal) {
        return group + ordinal;
    }
}
+6 −2
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.internal.os;

import static com.android.internal.os.PowerProfile.POWER_GROUP_DISPLAY_SCREEN_FULL;
import static com.android.internal.os.PowerProfile.POWER_GROUP_DISPLAY_SCREEN_ON;

import android.os.BatteryConsumer;
import android.os.BatteryStats;
import android.os.BatteryUsageStats;
@@ -50,10 +53,11 @@ public class ScreenPowerCalculator extends PowerCalculator {
    }

    public ScreenPowerCalculator(PowerProfile powerProfile) {
        // TODO(b/200239964): update to support multidisplay.
        mScreenOnPowerEstimator = new UsageBasedPowerEstimator(
                powerProfile.getAveragePower(PowerProfile.POWER_SCREEN_ON));
                powerProfile.getAveragePowerForOrdinal(POWER_GROUP_DISPLAY_SCREEN_ON, 0));
        mScreenFullPowerEstimator = new UsageBasedPowerEstimator(
                powerProfile.getAveragePower(PowerProfile.POWER_SCREEN_FULL));
                powerProfile.getAveragePowerForOrdinal(POWER_GROUP_DISPLAY_SCREEN_FULL, 0));
    }

    @Override
+27 −3
Original line number Diff line number Diff line
@@ -27,9 +27,33 @@
       are totally dependent on the platform and can vary
       significantly, so should be measured on the shipping platform
       with a power meter. -->
  <item name="ambient.on">0.1</item>  <!-- ~100mA -->
  <item name="screen.on">0.1</item>  <!-- ~100mA -->
  <item name="screen.full">0.1</item>  <!-- ~100mA -->

  <!-- Display related values. -->
  <!-- Average battery current draw of display0 while in ambient mode, including backlight.
       There must be one of these for each display, labeled:
       ambient.on.display0, ambient.on.display1, etc...

       Each display suffix number should match it's ordinal in its display device config.
  -->
  <item name="ambient.on.display0">0.1</item>  <!-- ~100mA -->
  <!-- Average battery current draw of display0 while on without backlight.
       There must be one of these for each display, labeled:
       screen.on.display0, screen.on.display1, etc...

       Each display suffix number should match it's ordinal in its display device config.
  -->
  <item name="screen.on.display0">0.1</item>  <!-- ~100mA -->
  <!-- Average battery current draw of the backlight at full brightness.
       The full current draw of display N at full brightness should be the sum of screen.on.displayN
       and screen.full.displayN

       There must be one of these for each display, labeled:
       screen.full.display0, screen.full.display1, etc...

       Each display suffix number should match it's ordinal in its display device config.
  -->
  <item name="screen.full.display0">0.1</item>  <!-- ~100mA -->

  <item name="bluetooth.active">0.1</item> <!-- Bluetooth data transfer, ~10mA -->
  <item name="bluetooth.on">0.1</item>  <!-- Bluetooth on & connectable, but not connected, ~0.1mA -->
  <item name="wifi.on">0.1</item>  <!-- ~3mA -->
+3 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.internal.os;

import static com.android.internal.os.PowerProfile.POWER_GROUP_DISPLAY_AMBIENT;

import static com.google.common.truth.Truth.assertThat;

import android.os.BatteryConsumer;
@@ -36,7 +38,7 @@ public class AmbientDisplayPowerCalculatorTest {

    @Rule
    public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
            .setAveragePower(PowerProfile.POWER_AMBIENT_DISPLAY, 10.0);
            .setAveragePowerForOrdinal(POWER_GROUP_DISPLAY_AMBIENT, 0, 10.0);

    @Test
    public void testMeasuredEnergyBasedModel() {
Loading