diff options
author | 2024-07-30 17:33:25 -0700 | |
---|---|---|
committer | 2024-08-19 15:39:16 -0700 | |
commit | a406aec7c5afbdcea043ba1f0b825c049159bb5d (patch) | |
tree | 2321ba86ce377e12a999e9226b5ef406bbfbe39c | |
parent | f28c6040e47e7682141a260982f5bc2028be2072 (diff) |
Add support for power and screen state for custom power components
Bug: 352833173
Bug: 352835319
Test: atest PowerStatsTests; atest PowerStatsTestRavenwood
Flag: com.android.server.power.optimization.battery_usage_stats_by_power_and_screen_state
Change-Id: I8db026a4838024574b9357fda4ddbaca0da4522c
18 files changed, 767 insertions, 780 deletions
diff --git a/core/java/android/os/BatteryConsumer.java b/core/java/android/os/BatteryConsumer.java index 623196b637f6..492b82543fcc 100644 --- a/core/java/android/os/BatteryConsumer.java +++ b/core/java/android/os/BatteryConsumer.java @@ -71,7 +71,7 @@ public abstract class BatteryConsumer { POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS, }) @Retention(RetentionPolicy.SOURCE) - public static @interface PowerComponent { + public @interface PowerComponent { } public static final int POWER_COMPONENT_ANY = -1; @@ -132,6 +132,16 @@ public abstract class BatteryConsumer { } /** + * An integer that is either one of @PowerComponent constants or a custom component ID + * between FIRST_CUSTOM_POWER_COMPONENT_ID and LAST_CUSTOM_POWER_COMPONENT_ID. + * + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + public @interface PowerComponentId { + } + + /** * Identifiers of models used for power estimation. * * @hide @@ -178,8 +188,8 @@ public abstract class BatteryConsumer { public @interface ProcessState { } + public static final int PROCESS_STATE_ANY = -1; public static final int PROCESS_STATE_UNSPECIFIED = 0; - public static final int PROCESS_STATE_ANY = PROCESS_STATE_UNSPECIFIED; public static final int PROCESS_STATE_FOREGROUND = 1; public static final int PROCESS_STATE_BACKGROUND = 2; public static final int PROCESS_STATE_FOREGROUND_SERVICE = 3; @@ -216,16 +226,14 @@ public abstract class BatteryConsumer { }; static final int COLUMN_INDEX_BATTERY_CONSUMER_TYPE = 0; - static final int COLUMN_COUNT = 1; - /** * Identifiers of consumed power aggregations per SCREEN state. * * @hide */ @IntDef(prefix = {"SCREEN_STATE_"}, value = { - SCREEN_STATE_UNSPECIFIED, SCREEN_STATE_ANY, + SCREEN_STATE_UNSPECIFIED, SCREEN_STATE_ON, SCREEN_STATE_OTHER, }) @@ -233,8 +241,10 @@ public abstract class BatteryConsumer { public @interface ScreenState { } + static final int COLUMN_COUNT = 1; + + public static final int SCREEN_STATE_ANY = 0; public static final int SCREEN_STATE_UNSPECIFIED = 0; - public static final int SCREEN_STATE_ANY = SCREEN_STATE_UNSPECIFIED; public static final int SCREEN_STATE_ON = 1; public static final int SCREEN_STATE_OTHER = 2; // Off, doze etc @@ -255,8 +265,8 @@ public abstract class BatteryConsumer { * @hide */ @IntDef(prefix = {"POWER_STATE_"}, value = { - POWER_STATE_UNSPECIFIED, POWER_STATE_ANY, + POWER_STATE_UNSPECIFIED, POWER_STATE_BATTERY, POWER_STATE_OTHER, }) @@ -264,8 +274,8 @@ public abstract class BatteryConsumer { public @interface PowerState { } + public static final int POWER_STATE_ANY = 0; public static final int POWER_STATE_UNSPECIFIED = 0; - public static final int POWER_STATE_ANY = POWER_STATE_UNSPECIFIED; public static final int POWER_STATE_BATTERY = 1; public static final int POWER_STATE_OTHER = 2; // Plugged in, or on wireless charger, etc. @@ -284,18 +294,18 @@ public abstract class BatteryConsumer { * Identifies power attribution dimensions that a caller is interested in. */ public static final class Dimensions { - public final @PowerComponent int powerComponent; + public final @PowerComponentId int powerComponentId; public final @ProcessState int processState; public final @ScreenState int screenState; public final @PowerState int powerState; - public Dimensions(@PowerComponent int powerComponent, @ProcessState int processState) { - this(powerComponent, processState, SCREEN_STATE_UNSPECIFIED, POWER_STATE_UNSPECIFIED); + public Dimensions(@PowerComponentId int powerComponentId, @ProcessState int processState) { + this(powerComponentId, processState, SCREEN_STATE_ANY, POWER_STATE_ANY); } - public Dimensions(@PowerComponent int powerComponent, int processState, + public Dimensions(@PowerComponentId int powerComponentId, int processState, @ScreenState int screenState, @PowerState int powerState) { - this.powerComponent = powerComponent; + this.powerComponentId = powerComponentId; this.processState = processState; this.screenState = screenState; this.powerState = powerState; @@ -305,11 +315,16 @@ public abstract class BatteryConsumer { public String toString() { boolean dimensionSpecified = false; StringBuilder sb = new StringBuilder(); - if (powerComponent != POWER_COMPONENT_ANY) { - sb.append("powerComponent=").append(sPowerComponentNames[powerComponent]); + if (powerComponentId != POWER_COMPONENT_ANY) { + sb.append("powerComponent="); + if (powerComponentId < POWER_COMPONENT_COUNT) { + sb.append(sPowerComponentNames[powerComponentId]); + } else { + sb.append("CUSTOM/").append(powerComponentId); + } dimensionSpecified = true; } - if (processState != PROCESS_STATE_UNSPECIFIED) { + if (processState != PROCESS_STATE_ANY) { if (dimensionSpecified) { sb.append(", "); } @@ -353,7 +368,7 @@ public abstract class BatteryConsumer { * in the same BatteryUsageStats. */ public static final class Key { - public final @PowerComponent int powerComponent; + public final @PowerComponentId int powerComponentId; public final @ProcessState int processState; public final @ScreenState int screenState; public final @PowerState int powerState; @@ -362,10 +377,10 @@ public abstract class BatteryConsumer { final int mPowerColumnIndex; final int mDurationColumnIndex; - private Key(@PowerComponent int powerComponent, @ProcessState int processState, + private Key(@PowerComponentId int powerComponentId, @ProcessState int processState, @ScreenState int screenState, @PowerState int powerState, int powerModelColumnIndex, int powerColumnIndex, int durationColumnIndex) { - this.powerComponent = powerComponent; + this.powerComponentId = powerComponentId; this.processState = processState; this.screenState = screenState; this.powerState = powerState; @@ -379,9 +394,13 @@ public abstract class BatteryConsumer { * Returns true if this key should be included in an enumeration parameterized with * the supplied dimensions. */ - boolean matches(@PowerComponent int powerComponent, @ProcessState int processState, + boolean matches(@PowerComponentId int powerComponent, @ProcessState int processState, @ScreenState int screenState, @PowerState int powerState) { - if (powerComponent != POWER_COMPONENT_ANY && this.powerComponent != powerComponent) { + if (powerComponent != POWER_COMPONENT_ANY && this.powerComponentId != powerComponent) { + return false; + } + if (this.processState == PROCESS_STATE_UNSPECIFIED) { + // PROCESS_STATE_UNSPECIFIED is used for storing a precomputed total return false; } if (processState != PROCESS_STATE_ANY && this.processState != processState) { @@ -401,7 +420,7 @@ public abstract class BatteryConsumer { public boolean equals(Object o) { // Skipping null and class check for performance final Key key = (Key) o; - return powerComponent == key.powerComponent + return powerComponentId == key.powerComponentId && processState == key.processState && screenState == key.screenState && powerState == key.powerState; @@ -409,7 +428,7 @@ public abstract class BatteryConsumer { @Override public int hashCode() { - int result = powerComponent; + int result = powerComponentId; result = 31 * result + processState; result = 31 * result + screenState; result = 31 * result + powerState; @@ -419,11 +438,15 @@ public abstract class BatteryConsumer { /** * Returns a string suitable for use in dumpsys. */ - public static String toString(@PowerComponent int powerComponent, + public static String toString(@PowerComponentId int powerComponent, @ProcessState int processState, @ScreenState int screenState, @PowerState int powerState) { StringBuilder sb = new StringBuilder(); - sb.append(powerComponentIdToString(powerComponent)); + if (powerComponent < POWER_COMPONENT_COUNT) { + sb.append(powerComponentIdToString(powerComponent)); + } else { + sb.append("CUSTOM/").append(powerComponent); + } if (processState != PROCESS_STATE_UNSPECIFIED) { sb.append(':'); sb.append(processStateToString(processState)); @@ -441,7 +464,7 @@ public abstract class BatteryConsumer { @Override public String toString() { - return toString(powerComponent, processState, screenState, powerState); + return toString(powerComponentId, processState, screenState, powerState); } } @@ -459,6 +482,13 @@ public abstract class BatteryConsumer { } /** + * Returns the name of the specified power component, e.g. "CPU", "GPU" etc. + */ + public String getPowerComponentName(@PowerComponentId int powerComponent) { + return mData.layout.getPowerComponentName(powerComponent); + } + + /** * Total power consumed by this consumer, in mAh. */ public double getConsumedPower() { @@ -480,10 +510,18 @@ public abstract class BatteryConsumer { } /** + * Returns indexes of all included power components. + */ + @PowerComponentId + public int[] getPowerComponentIds() { + return mData.layout.powerComponentIds; + } + + /** * Returns keys for various power values attributed to the specified component * held by this BatteryUsageStats object. */ - public Key[] getKeys(@PowerComponent int componentId) { + public Key[] getKeys(@PowerComponentId int componentId) { return mData.layout.getKeys(componentId); } @@ -491,7 +529,7 @@ public abstract class BatteryConsumer { * Returns the key for the power attributed to the specified component, * for all values of other dimensions such as process state. */ - public Key getKey(@PowerComponent int componentId) { + public Key getKey(@PowerComponentId int componentId) { return mData.layout.getKey(componentId, PROCESS_STATE_UNSPECIFIED, SCREEN_STATE_UNSPECIFIED, POWER_STATE_UNSPECIFIED); } @@ -499,7 +537,7 @@ public abstract class BatteryConsumer { /** * Returns the key for the power attributed to the specified component and process state. */ - public Key getKey(@PowerComponent int componentId, @ProcessState int processState) { + public Key getKey(@PowerComponentId int componentId, @ProcessState int processState) { return mData.layout.getKey(componentId, processState, SCREEN_STATE_UNSPECIFIED, POWER_STATE_UNSPECIFIED); } @@ -511,9 +549,9 @@ public abstract class BatteryConsumer { * {@link BatteryConsumer#POWER_COMPONENT_CPU}. * @return Amount of consumed power in mAh. */ - public double getConsumedPower(@PowerComponent int componentId) { - return mPowerComponents.getConsumedPower(componentId, PROCESS_STATE_UNSPECIFIED, - SCREEN_STATE_UNSPECIFIED, POWER_STATE_UNSPECIFIED); + public double getConsumedPower(@PowerComponentId int componentId) { + return mPowerComponents.getConsumedPower(componentId, PROCESS_STATE_ANY, + SCREEN_STATE_ANY, POWER_STATE_ANY); } /** @@ -533,7 +571,7 @@ public abstract class BatteryConsumer { * @param componentId The ID of the power component, e.g. * {@link BatteryConsumer#POWER_COMPONENT_CPU}. */ - public @PowerModel int getPowerModel(@BatteryConsumer.PowerComponent int componentId) { + public @PowerModel int getPowerModel(@PowerComponentId int componentId) { return mPowerComponents.getPowerModel( mData.layout.getKeyOrThrow(componentId, PROCESS_STATE_UNSPECIFIED, SCREEN_STATE_UNSPECIFIED, POWER_STATE_UNSPECIFIED)); @@ -554,9 +592,12 @@ public abstract class BatteryConsumer { * * @param componentId The ID of the custom power component. * @return Amount of consumed power in mAh. + * + * @deprecated Use getConsumedPower instead */ + @Deprecated public double getConsumedPowerForCustomComponent(int componentId) { - return mPowerComponents.getConsumedPowerForCustomComponent(componentId); + return getConsumedPower(componentId); } public int getCustomPowerComponentCount() { @@ -580,8 +621,9 @@ public abstract class BatteryConsumer { * {@link UidBatteryConsumer#POWER_COMPONENT_CPU}. * @return Amount of time in milliseconds. */ - public long getUsageDurationMillis(@PowerComponent int componentId) { - return mPowerComponents.getUsageDurationMillis(getKey(componentId)); + public long getUsageDurationMillis(@PowerComponentId int componentId) { + return mPowerComponents.getUsageDurationMillis(componentId, PROCESS_STATE_ANY, + SCREEN_STATE_ANY, POWER_STATE_ANY); } /** @@ -598,17 +640,6 @@ public abstract class BatteryConsumer { } /** - * Returns the amount of usage time attributed to the specified custom component - * since BatteryStats reset. - * - * @param componentId The ID of the custom power component. - * @return Amount of time in milliseconds. - */ - public long getUsageDurationForCustomComponentMillis(int componentId) { - return mPowerComponents.getUsageDurationForCustomComponentMillis(componentId); - } - - /** * Returns the name of the specified component. Intended for logging and debugging. */ public static String powerComponentIdToString(@BatteryConsumer.PowerComponent int componentId) { @@ -826,13 +857,12 @@ public abstract class BatteryConsumer { public final boolean processStateDataIncluded; public final boolean screenStateDataIncluded; public final boolean powerStateDataIncluded; + public final @PowerComponentId int[] powerComponentIds; public final Key[] keys; public final SparseArray<Key> indexedKeys; public final int totalConsumedPowerColumnIndex; - public final int firstCustomConsumedPowerColumn; - public final int firstCustomUsageDurationColumn; public final int columnCount; - private Key[][] mPerComponentKeys; + private SparseArray<Key[]> mPerComponentKeys; private BatteryConsumerDataLayout(int firstColumn, String[] customPowerComponentNames, boolean powerModelsIncluded, boolean includeProcessStateData, @@ -844,6 +874,15 @@ public abstract class BatteryConsumer { this.screenStateDataIncluded = includeScreenState; this.powerStateDataIncluded = includePowerState; + powerComponentIds = new int[POWER_COMPONENT_COUNT + customPowerComponentCount]; + int id = 0; + for (int componentId = 0; componentId < POWER_COMPONENT_COUNT; componentId++) { + powerComponentIds[id++] = componentId; + } + for (int i = 0; i < customPowerComponentCount; i++) { + powerComponentIds[id++] = FIRST_CUSTOM_POWER_COMPONENT_ID + i; + } + int columnIndex = firstColumn; totalConsumedPowerColumnIndex = columnIndex++; @@ -857,35 +896,41 @@ public abstract class BatteryConsumer { if (!includePowerState && powerState != POWER_STATE_UNSPECIFIED) { continue; } - for (int componentId = 0; componentId < POWER_COMPONENT_COUNT; componentId++) { + for (int i = 0; i < powerComponentIds.length; i++) { columnIndex = addKeys(keyList, powerModelsIncluded, includeProcessStateData, - componentId, screenState, powerState, columnIndex); + powerComponentIds[i], screenState, powerState, columnIndex); } } } - firstCustomConsumedPowerColumn = columnIndex; - columnIndex += customPowerComponentCount; - - firstCustomUsageDurationColumn = columnIndex; - columnIndex += customPowerComponentCount; - columnCount = columnIndex; keys = keyList.toArray(KEY_ARRAY); indexedKeys = new SparseArray<>(keys.length); for (int i = 0; i < keys.length; i++) { Key key = keys[i]; - int index = keyIndex(key.powerComponent, key.processState, key.screenState, - key.powerState); - indexedKeys.put(index, key); + indexedKeys.put(keyIndex(key.powerComponentId, key.processState, key.screenState, + key.powerState), key); + } + } + + public String getPowerComponentName(@PowerComponentId int powerComponentId) { + if (powerComponentId < POWER_COMPONENT_COUNT) { + return BatteryConsumer.powerComponentIdToString(powerComponentId); + } else if (powerComponentId >= FIRST_CUSTOM_POWER_COMPONENT_ID && powerComponentId + < FIRST_CUSTOM_POWER_COMPONENT_ID + customPowerComponentCount) { + return customPowerComponentNames[powerComponentId + - FIRST_CUSTOM_POWER_COMPONENT_ID]; + } else { + throw new IllegalArgumentException( + "Unsupported power component " + powerComponentId); } } private int addKeys(List<Key> keys, boolean powerModelsIncluded, - boolean includeProcessStateData, int componentId, + boolean includeProcessStateData, @PowerComponentId int componentId, int screenState, int powerState, int columnIndex) { - keys.add(new Key(componentId, PROCESS_STATE_ANY, screenState, powerState, + keys.add(new Key(componentId, PROCESS_STATE_UNSPECIFIED, screenState, powerState, powerModelsIncluded ? columnIndex++ : POWER_MODEL_NOT_INCLUDED, // power model @@ -896,14 +941,13 @@ public abstract class BatteryConsumer { // Declare Keys for all process states, if needed if (includeProcessStateData) { boolean isSupported = SUPPORTED_POWER_COMPONENTS_PER_PROCESS_STATE - .binarySearch(componentId) >= 0; + .binarySearch(componentId) >= 0 + || componentId >= FIRST_CUSTOM_POWER_COMPONENT_ID; if (isSupported) { - for (int processState = 0; processState < PROCESS_STATE_COUNT; - processState++) { - if (processState == PROCESS_STATE_UNSPECIFIED) { + for (int processState = 0; processState < PROCESS_STATE_COUNT; processState++) { + if (processState == PROCESS_STATE_UNSPECIFIED) { // Already added above continue; } - keys.add(new Key(componentId, processState, screenState, powerState, powerModelsIncluded ? columnIndex++ @@ -917,12 +961,12 @@ public abstract class BatteryConsumer { return columnIndex; } - Key getKey(@PowerComponent int componentId, @ProcessState int processState, + Key getKey(@PowerComponentId int componentId, @ProcessState int processState, @ScreenState int screenState, @PowerState int powerState) { return indexedKeys.get(keyIndex(componentId, processState, screenState, powerState)); } - Key getKeyOrThrow(@PowerComponent int componentId, @ProcessState int processState, + Key getKeyOrThrow(@PowerComponentId int componentId, @ProcessState int processState, @ScreenState int screenState, @PowerState int powerState) { Key key = getKey(componentId, processState, screenState, powerState); if (key == null) { @@ -933,21 +977,21 @@ public abstract class BatteryConsumer { return key; } - public Key[] getKeys(@PowerComponent int componentId) { + public Key[] getKeys(@PowerComponentId int componentId) { synchronized (this) { if (mPerComponentKeys == null) { - mPerComponentKeys = new Key[BatteryConsumer.POWER_COMPONENT_COUNT][]; + mPerComponentKeys = new SparseArray<>(powerComponentIds.length); } - Key[] componentKeys = mPerComponentKeys[componentId]; + Key[] componentKeys = mPerComponentKeys.get(componentId); if (componentKeys == null) { ArrayList<Key> out = new ArrayList<>(); for (Key key : keys) { - if (key.powerComponent == componentId) { + if (key.powerComponentId == componentId) { out.add(key); } } componentKeys = out.toArray(new Key[out.size()]); - mPerComponentKeys[componentId] = componentKeys; + mPerComponentKeys.put(componentId, componentKeys); } return componentKeys; } @@ -991,18 +1035,18 @@ public abstract class BatteryConsumer { } @Nullable - public Key[] getKeys(@PowerComponent int componentId) { + public Key[] getKeys(@PowerComponentId int componentId) { return mData.layout.getKeys(componentId); } @Nullable - public Key getKey(@PowerComponent int componentId, @ProcessState int processState) { + public Key getKey(@PowerComponentId int componentId, @ProcessState int processState) { return mData.layout.getKey(componentId, processState, SCREEN_STATE_UNSPECIFIED, POWER_STATE_UNSPECIFIED); } @Nullable - public Key getKey(@PowerComponent int componentId, @ProcessState int processState, + public Key getKey(@PowerComponentId int componentId, @ProcessState int processState, @ScreenState int screenState, @PowerState int powerState) { return mData.layout.getKey(componentId, processState, screenState, powerState); } @@ -1015,7 +1059,7 @@ public abstract class BatteryConsumer { * @param componentPower Amount of consumed power in mAh. */ @NonNull - public T setConsumedPower(@PowerComponent int componentId, double componentPower) { + public T setConsumedPower(@PowerComponentId int componentId, double componentPower) { return setConsumedPower(componentId, componentPower, POWER_MODEL_POWER_PROFILE); } @@ -1028,7 +1072,7 @@ public abstract class BatteryConsumer { */ @SuppressWarnings("unchecked") @NonNull - public T setConsumedPower(@PowerComponent int componentId, double componentPower, + public T setConsumedPower(@PowerComponentId int componentId, double componentPower, @PowerModel int powerModel) { mPowerComponentsBuilder.setConsumedPower(getKey(componentId, PROCESS_STATE_UNSPECIFIED), componentPower, powerModel); @@ -1037,7 +1081,7 @@ public abstract class BatteryConsumer { @SuppressWarnings("unchecked") @NonNull - public T addConsumedPower(@PowerComponent int componentId, double componentPower, + public T addConsumedPower(@PowerComponentId int componentId, double componentPower, @PowerModel int powerModel) { mPowerComponentsBuilder.addConsumedPower(getKey(componentId, PROCESS_STATE_UNSPECIFIED), componentPower, powerModel); @@ -1059,26 +1103,6 @@ public abstract class BatteryConsumer { } /** - * Sets the amount of drain attributed to the specified custom drain type. - * - * @param componentId The ID of the custom power component. - * @param componentPower Amount of consumed power in mAh. - */ - @SuppressWarnings("unchecked") - @NonNull - public T setConsumedPowerForCustomComponent(int componentId, double componentPower) { - mPowerComponentsBuilder.setConsumedPowerForCustomComponent(componentId, componentPower); - return (T) this; - } - - @SuppressWarnings("unchecked") - @NonNull - public T addConsumedPowerForCustomComponent(int componentId, double componentPower) { - mPowerComponentsBuilder.addConsumedPowerForCustomComponent(componentId, componentPower); - return (T) this; - } - - /** * Sets the amount of time used by the specified component, e.g. CPU, WiFi etc. * * @param componentId The ID of the power component, e.g. @@ -1087,7 +1111,7 @@ public abstract class BatteryConsumer { */ @SuppressWarnings("unchecked") @NonNull - public T setUsageDurationMillis(@UidBatteryConsumer.PowerComponent int componentId, + public T setUsageDurationMillis(@PowerComponentId int componentId, long componentUsageTimeMillis) { mPowerComponentsBuilder .setUsageDurationMillis(getKey(componentId, PROCESS_STATE_UNSPECIFIED), @@ -1095,7 +1119,6 @@ public abstract class BatteryConsumer { return (T) this; } - @SuppressWarnings("unchecked") @NonNull public T setUsageDurationMillis(Key key, long componentUsageTimeMillis) { @@ -1104,21 +1127,6 @@ public abstract class BatteryConsumer { } /** - * Sets the amount of time used by the specified custom component. - * - * @param componentId The ID of the custom power component. - * @param componentUsageTimeMillis Amount of time in microseconds. - */ - @SuppressWarnings("unchecked") - @NonNull - public T setUsageDurationForCustomComponentMillis(int componentId, - long componentUsageTimeMillis) { - mPowerComponentsBuilder.setUsageDurationForCustomComponentMillis(componentId, - componentUsageTimeMillis); - return (T) this; - } - - /** * Returns the total power accumulated by this builder so far. It may change * by the time the {@code build()} method is called. */ diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java index e039953f83b5..1fef602b8dd7 100644 --- a/core/java/android/os/BatteryUsageStats.java +++ b/core/java/android/os/BatteryUsageStats.java @@ -95,7 +95,6 @@ public final class BatteryUsageStats implements Parcelable, Closeable { static final String XML_TAG_USER = "user"; static final String XML_TAG_POWER_COMPONENTS = "power_components"; static final String XML_TAG_COMPONENT = "component"; - static final String XML_TAG_CUSTOM_COMPONENT = "custom_component"; static final String XML_ATTR_ID = "id"; static final String XML_ATTR_UID = "uid"; static final String XML_ATTR_USER_ID = "user_id"; @@ -610,94 +609,107 @@ public final class BatteryUsageStats implements Parcelable, Closeable { final BatteryConsumer appsConsumer = getAggregateBatteryConsumer( AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS); - for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT; - componentId++) { - final double devicePowerMah = deviceConsumer.getConsumedPower(componentId); - final double appsPowerMah = appsConsumer.getConsumedPower(componentId); + for (@BatteryConsumer.PowerComponentId int powerComponent : + mBatteryConsumerDataLayout.powerComponentIds) { + final double devicePowerMah = deviceConsumer.getConsumedPower(powerComponent); + final double appsPowerMah = appsConsumer.getConsumedPower(powerComponent); if (devicePowerMah == 0 && appsPowerMah == 0) { continue; } - printPowerComponent(pw, prefix, BatteryConsumer.powerComponentIdToString(componentId), - devicePowerMah, appsPowerMah, - BatteryConsumer.POWER_MODEL_UNDEFINED, - deviceConsumer.getUsageDurationMillis(componentId)); + printPowerComponent(pw, prefix, + mBatteryConsumerDataLayout.getPowerComponentName(powerComponent), + devicePowerMah, appsPowerMah, BatteryConsumer.POWER_MODEL_UNDEFINED, + deviceConsumer.getUsageDurationMillis(powerComponent)); } - for (int componentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID; - componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID - + mCustomPowerComponentNames.length; - componentId++) { - final double devicePowerMah = - deviceConsumer.getConsumedPowerForCustomComponent(componentId); - final double appsPowerMah = - appsConsumer.getConsumedPowerForCustomComponent(componentId); - if (devicePowerMah == 0 && appsPowerMah == 0) { - continue; + String prefixPlus = prefix + " "; + if (mIncludesPowerStateData && !mIncludesScreenStateData) { + for (@BatteryConsumer.PowerState int powerState = 0; + powerState < BatteryConsumer.POWER_STATE_COUNT; + powerState++) { + if (powerState != BatteryConsumer.POWER_STATE_UNSPECIFIED) { + dumpPowerComponents(pw, BatteryConsumer.SCREEN_STATE_ANY, powerState, + prefixPlus); + } } - - printPowerComponent(pw, prefix, deviceConsumer.getCustomPowerComponentName(componentId), - devicePowerMah, appsPowerMah, - BatteryConsumer.POWER_MODEL_UNDEFINED, - deviceConsumer.getUsageDurationForCustomComponentMillis(componentId)); - } - - if (mIncludesScreenStateData || mIncludesPowerStateData) { - String prefixPlus = prefix + " "; - StringBuilder stateLabel = new StringBuilder(); - int screenState = BatteryConsumer.SCREEN_STATE_UNSPECIFIED; - int powerState = BatteryConsumer.POWER_STATE_UNSPECIFIED; - for (BatteryConsumer.Key key : mBatteryConsumerDataLayout.keys) { - if (key.processState != BatteryConsumer.PROCESS_STATE_UNSPECIFIED) { - continue; + } else if (!mIncludesPowerStateData && mIncludesScreenStateData) { + for (@BatteryConsumer.ScreenState int screenState = 0; + screenState < BatteryConsumer.SCREEN_STATE_COUNT; + screenState++) { + if (screenState != BatteryConsumer.SCREEN_STATE_UNSPECIFIED) { + dumpPowerComponents(pw, screenState, BatteryConsumer.POWER_STATE_ANY, + prefixPlus); } - - if (key.screenState == BatteryConsumer.SCREEN_STATE_UNSPECIFIED - && key.powerState == BatteryConsumer.POWER_STATE_UNSPECIFIED) { - // Totals already printed earlier in this method - continue; + } + } else if (mIncludesPowerStateData && mIncludesScreenStateData) { + for (@BatteryConsumer.PowerState int powerState = 0; + powerState < BatteryConsumer.POWER_STATE_COUNT; + powerState++) { + if (powerState != BatteryConsumer.POWER_STATE_UNSPECIFIED) { + for (@BatteryConsumer.ScreenState int screenState = 0; + screenState < BatteryConsumer.SCREEN_STATE_COUNT; screenState++) { + if (screenState != BatteryConsumer.SCREEN_STATE_UNSPECIFIED) { + dumpPowerComponents(pw, screenState, powerState, prefixPlus); + } + } } + } + } - final double devicePowerMah = deviceConsumer.getConsumedPower(key); - final double appsPowerMah = appsConsumer.getConsumedPower(key); - if (devicePowerMah == 0 && appsPowerMah == 0) { - continue; - } + dumpSortedBatteryConsumers(pw, prefix, getUidBatteryConsumers()); + dumpSortedBatteryConsumers(pw, prefix, getUserBatteryConsumers()); + pw.println(); + } - if (key.screenState != screenState || key.powerState != powerState) { - screenState = key.screenState; - powerState = key.powerState; + private void dumpPowerComponents(PrintWriter pw, + @BatteryConsumer.ScreenState int screenState, + @BatteryConsumer.PowerState int powerState, String prefix) { + final BatteryConsumer deviceConsumer = getAggregateBatteryConsumer( + AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE); + final BatteryConsumer appsConsumer = getAggregateBatteryConsumer( + AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS); - boolean empty = true; - stateLabel.setLength(0); - stateLabel.append(" ("); - if (powerState != BatteryConsumer.POWER_STATE_UNSPECIFIED) { - stateLabel.append(BatteryConsumer.powerStateToString(powerState)); - empty = false; - } - if (screenState != BatteryConsumer.SCREEN_STATE_UNSPECIFIED) { - if (!empty) { - stateLabel.append(", "); - } - stateLabel.append("screen ").append( - BatteryConsumer.screenStateToString(screenState)); - empty = false; - } + boolean labelPrinted = false; + for (@BatteryConsumer.PowerComponentId int powerComponent : + mBatteryConsumerDataLayout.powerComponentIds) { + BatteryConsumer.Dimensions dimensions = new BatteryConsumer.Dimensions( + powerComponent, BatteryConsumer.PROCESS_STATE_ANY, screenState, powerState); + final double devicePowerMah = deviceConsumer.getConsumedPower(dimensions); + final double appsPowerMah = appsConsumer.getConsumedPower(dimensions); + if (devicePowerMah == 0 && appsPowerMah == 0) { + continue; + } + + if (!labelPrinted) { + boolean empty = true; + StringBuilder stateLabel = new StringBuilder(); + stateLabel.append(" ("); + if (powerState != BatteryConsumer.POWER_STATE_ANY) { + stateLabel.append(BatteryConsumer.powerStateToString(powerState)); + empty = false; + } + if (screenState != BatteryConsumer.SCREEN_STATE_ANY) { if (!empty) { - stateLabel.append(")"); - pw.println(stateLabel); + stateLabel.append(", "); } + stateLabel.append("screen ") + .append(BatteryConsumer.screenStateToString(screenState)); + empty = false; + } + if (!empty) { + stateLabel.append(")"); + pw.println(stateLabel); + labelPrinted = true; } - String label = BatteryConsumer.powerComponentIdToString(key.powerComponent); - printPowerComponent(pw, prefixPlus, label, devicePowerMah, appsPowerMah, - mIncludesPowerModels ? deviceConsumer.getPowerModel(key) - : BatteryConsumer.POWER_MODEL_UNDEFINED, - deviceConsumer.getUsageDurationMillis(key)); } + printPowerComponent(pw, prefix, + mBatteryConsumerDataLayout.getPowerComponentName(powerComponent), + devicePowerMah, appsPowerMah, + mIncludesPowerModels ? deviceConsumer.getPowerModel(powerComponent) + : BatteryConsumer.POWER_MODEL_UNDEFINED, + deviceConsumer.getUsageDurationMillis(dimensions)); } - dumpSortedBatteryConsumers(pw, prefix, getUidBatteryConsumers()); - dumpSortedBatteryConsumers(pw, prefix, getUserBatteryConsumers()); - pw.println(); } private void printPowerComponent(PrintWriter pw, String prefix, String label, @@ -951,12 +963,14 @@ public final class BatteryUsageStats implements Parcelable, Closeable { /** * Returns true if this Builder is configured to hold data for the specified - * custom power component ID. + * power component index. */ - public boolean isSupportedCustomPowerComponent(int componentId) { - return componentId >= BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + public boolean isSupportedPowerComponent( + @BatteryConsumer.PowerComponentId int componentId) { + return componentId < BatteryConsumer.POWER_COMPONENT_COUNT + || (componentId >= BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID && componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID - + mBatteryConsumerDataLayout.customPowerComponentCount; + + mBatteryConsumerDataLayout.customPowerComponentCount); } /** diff --git a/core/java/android/os/BatteryUsageStatsQuery.java b/core/java/android/os/BatteryUsageStatsQuery.java index d0ed297d2bda..a12606bc2e66 100644 --- a/core/java/android/os/BatteryUsageStatsQuery.java +++ b/core/java/android/os/BatteryUsageStatsQuery.java @@ -86,7 +86,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { private final long mFromTimestamp; private final long mToTimestamp; private final double mMinConsumedPowerThreshold; - private final @BatteryConsumer.PowerComponent int[] mPowerComponents; + private final @BatteryConsumer.PowerComponentId int[] mPowerComponents; private BatteryUsageStatsQuery(@NonNull Builder builder) { mFlags = builder.mFlags; @@ -139,6 +139,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { * Returns the power components that should be estimated or null if all power components * are being requested. */ + @BatteryConsumer.PowerComponentId public int[] getPowerComponents() { return mPowerComponents; } @@ -228,7 +229,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { private long mFromTimestamp; private long mToTimestamp; private double mMinConsumedPowerThreshold = 0; - private @BatteryConsumer.PowerComponent int[] mPowerComponents; + private @BatteryConsumer.PowerComponentId int[] mPowerComponents; /** * Builds a read-only BatteryUsageStatsQuery object. @@ -294,7 +295,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { * is all power components. */ public Builder includePowerComponents( - @BatteryConsumer.PowerComponent int[] powerComponents) { + @BatteryConsumer.PowerComponentId int[] powerComponents) { mPowerComponents = powerComponents; return this; } diff --git a/core/java/android/os/PowerComponents.java b/core/java/android/os/PowerComponents.java index f22e1eac9643..9200db31279a 100644 --- a/core/java/android/os/PowerComponents.java +++ b/core/java/android/os/PowerComponents.java @@ -60,14 +60,14 @@ class PowerComponents { * Total power consumed by this consumer, aggregated over the specified dimensions, in mAh. */ public double getConsumedPower(@NonNull BatteryConsumer.Dimensions dimensions) { - return getConsumedPower(dimensions.powerComponent, dimensions.processState, + return getConsumedPower(dimensions.powerComponentId, dimensions.processState, dimensions.screenState, dimensions.powerState); } /** * Total power consumed by this consumer, aggregated over the specified dimensions, in mAh. */ - public double getConsumedPower(@BatteryConsumer.PowerComponent int powerComponent, + public double getConsumedPower(@BatteryConsumer.PowerComponentId int powerComponent, @BatteryConsumer.ProcessState int processState, @BatteryConsumer.ScreenState int screenState, @BatteryConsumer.PowerState int powerState) { @@ -76,85 +76,64 @@ class PowerComponents { return mData.getDouble(mData.layout.totalConsumedPowerColumnIndex); } - if (powerComponent != POWER_COMPONENT_ANY - && ((mData.layout.screenStateDataIncluded && screenState != SCREEN_STATE_ANY) - || (mData.layout.powerStateDataIncluded && powerState != POWER_STATE_ANY))) { - BatteryConsumer.Key key = mData.layout.getKey(powerComponent, - processState, screenState, powerState); - if (key != null) { - return mData.getDouble(key.mPowerColumnIndex); - } + if (!mData.layout.processStateDataIncluded && !(processState == PROCESS_STATE_UNSPECIFIED + || processState == PROCESS_STATE_ANY)) { return 0; } - if (mData.layout.processStateDataIncluded || mData.layout.screenStateDataIncluded - || mData.layout.powerStateDataIncluded) { - double total = 0; - for (BatteryConsumer.Key key : mData.layout.keys) { - if (key.processState != PROCESS_STATE_UNSPECIFIED - && key.matches(powerComponent, processState, screenState, powerState)) { - total += mData.getDouble(key.mPowerColumnIndex); - } - } - if (total != 0) { - return total; - } + BatteryConsumer.Key key = mData.layout.getKey(powerComponent, + mData.layout.processStateDataIncluded && processState != PROCESS_STATE_ANY + ? processState : PROCESS_STATE_UNSPECIFIED, + mData.layout.screenStateDataIncluded && screenState != SCREEN_STATE_ANY + ? screenState : SCREEN_STATE_UNSPECIFIED, + mData.layout.powerStateDataIncluded && powerState != POWER_STATE_ANY + ? powerState : POWER_STATE_UNSPECIFIED); + if (key != null && mData.hasValue(key.mPowerColumnIndex)) { + return mData.getDouble(key.mPowerColumnIndex); } - BatteryConsumer.Key key = mData.layout.getKey(powerComponent, processState, - SCREEN_STATE_UNSPECIFIED, POWER_STATE_UNSPECIFIED); - if (key != null) { - return mData.getDouble(key.mPowerColumnIndex); - } else { - return 0; + double total = 0; + for (BatteryConsumer.Key k : mData.layout.keys) { + if (k.matches(powerComponent, processState, screenState, powerState)) { + total += mData.getDouble(k.mPowerColumnIndex); + } } + return total; } /** * Total usage duration by this consumer, aggregated over the specified dimensions, in ms. */ public long getUsageDurationMillis(@NonNull BatteryConsumer.Dimensions dimensions) { - return getUsageDurationMillis(dimensions.powerComponent, dimensions.processState, + return getUsageDurationMillis(dimensions.powerComponentId, dimensions.processState, dimensions.screenState, dimensions.powerState); } /** * Total usage duration by this consumer, aggregated over the specified dimensions, in ms. */ - public long getUsageDurationMillis(@BatteryConsumer.PowerComponent int powerComponent, + public long getUsageDurationMillis(@BatteryConsumer.PowerComponentId int powerComponent, @BatteryConsumer.ProcessState int processState, @BatteryConsumer.ScreenState int screenState, @BatteryConsumer.PowerState int powerState) { - if ((mData.layout.screenStateDataIncluded && screenState != SCREEN_STATE_ANY) - || (mData.layout.powerStateDataIncluded && powerState != POWER_STATE_ANY)) { - BatteryConsumer.Key key = mData.layout.getKey(powerComponent, - processState, screenState, powerState); - if (key != null) { - return mData.getLong(key.mDurationColumnIndex); - } - return 0; + BatteryConsumer.Key key = mData.layout.getKey(powerComponent, + mData.layout.processStateDataIncluded && processState != PROCESS_STATE_ANY + ? processState : PROCESS_STATE_UNSPECIFIED, + mData.layout.screenStateDataIncluded && screenState != SCREEN_STATE_ANY + ? screenState : SCREEN_STATE_UNSPECIFIED, + mData.layout.powerStateDataIncluded && powerState != POWER_STATE_ANY + ? powerState : POWER_STATE_UNSPECIFIED); + if (key != null && mData.hasValue(key.mDurationColumnIndex)) { + return mData.getLong(key.mDurationColumnIndex); } - if (mData.layout.screenStateDataIncluded || mData.layout.powerStateDataIncluded) { - long total = 0; - for (BatteryConsumer.Key key : mData.layout.keys) { - if (key.processState != PROCESS_STATE_UNSPECIFIED - && key.matches(powerComponent, processState, screenState, powerState)) { - total += mData.getLong(key.mDurationColumnIndex); - } - } - if (total != 0) { - return total; + long total = 0; + for (BatteryConsumer.Key k : mData.layout.keys) { + if (k.matches(powerComponent, processState, screenState, powerState)) { + total += mData.getLong(k.mDurationColumnIndex); } } - - BatteryConsumer.Key key = mData.layout.getKey(powerComponent, processState, - SCREEN_STATE_UNSPECIFIED, POWER_STATE_UNSPECIFIED); - if (key != null) { - return mData.getLong(key.mDurationColumnIndex); - } else { - return 0; - } + return total; } /** @@ -168,39 +147,12 @@ class PowerComponents { if (mData.hasValue(key.mPowerColumnIndex)) { return mData.getDouble(key.mPowerColumnIndex); } - return getConsumedPower(key.powerComponent, key.processState, key.screenState, + return getConsumedPower(key.powerComponentId, key.processState, key.screenState, key.powerState); } - /** - * Returns the amount of drain attributed to the specified custom drain type. - * - * @param componentId The ID of the custom power component. - * @return Amount of consumed power in mAh. - */ - public double getConsumedPowerForCustomComponent(int componentId) { - final int index = componentId - BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID; - if (index >= 0 && index < mData.layout.customPowerComponentCount) { - return mData.getDouble(mData.layout.firstCustomConsumedPowerColumn + index); - } else { - throw new IllegalArgumentException( - "Unsupported custom power component ID: " + componentId); - } - } - public String getCustomPowerComponentName(int componentId) { - final int index = componentId - BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID; - if (index >= 0 && index < mData.layout.customPowerComponentCount) { - try { - return mData.layout.customPowerComponentNames[index]; - } catch (ArrayIndexOutOfBoundsException e) { - throw new IllegalArgumentException( - "Unsupported custom power component ID: " + componentId); - } - } else { - throw new IllegalArgumentException( - "Unsupported custom power component ID: " + componentId); - } + return mData.layout.getPowerComponentName(componentId); } @BatteryConsumer.PowerModel @@ -224,63 +176,26 @@ class PowerComponents { return mData.getLong(key.mDurationColumnIndex); } - return getUsageDurationMillis(key.powerComponent, key.processState, key.screenState, + return getUsageDurationMillis(key.powerComponentId, key.processState, key.screenState, key.powerState); } - /** - * Returns the amount of usage time attributed to the specified custom component. - * - * @param componentId The ID of the custom power component. - * @return Amount of time in milliseconds. - */ - public long getUsageDurationForCustomComponentMillis(int componentId) { - final int index = componentId - BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID; - if (index >= 0 && index < mData.layout.customPowerComponentCount) { - return mData.getLong(mData.layout.firstCustomUsageDurationColumn + index); - } else { - throw new IllegalArgumentException( - "Unsupported custom power component ID: " + componentId); - } - } - void dump(PrintWriter pw, @BatteryConsumer.ScreenState int screenState, @BatteryConsumer.PowerState int powerState, boolean skipEmptyComponents) { StringBuilder sb = new StringBuilder(); - for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT; - componentId++) { - dump(sb, componentId, PROCESS_STATE_ANY, screenState, powerState, skipEmptyComponents); + for (@BatteryConsumer.PowerComponentId int id : mData.layout.powerComponentIds) { + dump(sb, id, PROCESS_STATE_ANY, screenState, powerState, skipEmptyComponents); if (mData.layout.processStateDataIncluded) { for (int processState = 0; processState < BatteryConsumer.PROCESS_STATE_COUNT; processState++) { if (processState == PROCESS_STATE_UNSPECIFIED) { continue; } - dump(sb, componentId, processState, screenState, powerState, - skipEmptyComponents); + dump(sb, id, processState, screenState, powerState, skipEmptyComponents); } } } - // TODO(b/352835319): take into account screen and power states - if (screenState == SCREEN_STATE_ANY && powerState == POWER_STATE_ANY) { - final int customComponentCount = mData.layout.customPowerComponentCount; - for (int customComponentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID; - customComponentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID - + customComponentCount; - customComponentId++) { - final double customComponentPower = - getConsumedPowerForCustomComponent(customComponentId); - if (skipEmptyComponents && customComponentPower == 0) { - continue; - } - sb.append(getCustomPowerComponentName(customComponentId)); - sb.append("="); - sb.append(BatteryStats.formatCharge(customComponentPower)); - sb.append(" "); - } - } - // Remove trailing spaces while (!sb.isEmpty() && Character.isWhitespace(sb.charAt(sb.length() - 1))) { sb.setLength(sb.length() - 1); @@ -289,25 +204,25 @@ class PowerComponents { pw.println(sb); } - private void dump(StringBuilder sb, @BatteryConsumer.PowerComponent int powerComponent, + private void dump(StringBuilder sb, @BatteryConsumer.PowerComponentId int powerComponent, @BatteryConsumer.ProcessState int processState, @BatteryConsumer.ScreenState int screenState, @BatteryConsumer.PowerState int powerState, boolean skipEmptyComponents) { - final double componentPower = getConsumedPower(powerComponent, processState, screenState, + final double power = getConsumedPower(powerComponent, processState, screenState, powerState); final long durationMs = getUsageDurationMillis(powerComponent, processState, screenState, powerState); - if (skipEmptyComponents && componentPower == 0 && durationMs == 0) { + if (skipEmptyComponents && power == 0 && durationMs == 0) { return; } - sb.append(BatteryConsumer.powerComponentIdToString(powerComponent)); - if (processState != PROCESS_STATE_UNSPECIFIED) { + sb.append(mData.layout.getPowerComponentName(powerComponent)); + if (processState != PROCESS_STATE_ANY) { sb.append(':'); sb.append(BatteryConsumer.processStateToString(processState)); } sb.append("="); - sb.append(BatteryStats.formatCharge(componentPower)); + sb.append(BatteryStats.formatCharge(power)); if (durationMs != 0) { sb.append(" ("); @@ -334,15 +249,14 @@ class PowerComponents { private boolean writeStatsProtoImpl(@Nullable ProtoOutputStream proto) { boolean interestingData = false; - for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT; - componentId++) { + for (@BatteryConsumer.PowerComponentId int componentId : mData.layout.powerComponentIds) { final BatteryConsumer.Key[] keys = mData.layout.getKeys(componentId); for (BatteryConsumer.Key key : keys) { final long powerDeciCoulombs = convertMahToDeciCoulombs( - getConsumedPower(key.powerComponent, key.processState, key.screenState, + getConsumedPower(key.powerComponentId, key.processState, key.screenState, key.powerState)); - final long durationMs = getUsageDurationMillis(key.powerComponent, key.processState, - key.screenState, key.powerState); + final long durationMs = getUsageDurationMillis(key.powerComponentId, + key.processState, key.screenState, key.powerState); if (powerDeciCoulombs == 0 && durationMs == 0) { // No interesting data. Make sure not to even write the COMPONENT int. @@ -356,7 +270,7 @@ class PowerComponents { return true; } - if (key.processState == PROCESS_STATE_ANY) { + if (key.processState == PROCESS_STATE_UNSPECIFIED) { writePowerComponentUsage(proto, BatteryUsageStatsAtomsProto.BatteryConsumerData.POWER_COMPONENTS, componentId, powerDeciCoulombs, durationMs); @@ -366,27 +280,6 @@ class PowerComponents { } } } - for (int idx = 0; idx < mData.layout.customPowerComponentCount; idx++) { - final int componentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + idx; - final long powerDeciCoulombs = - convertMahToDeciCoulombs(getConsumedPowerForCustomComponent(componentId)); - final long durationMs = getUsageDurationForCustomComponentMillis(componentId); - - if (powerDeciCoulombs == 0 && durationMs == 0) { - // No interesting data. Make sure not to even write the COMPONENT int. - continue; - } - - interestingData = true; - if (proto == null) { - // We're just asked whether there is data, not to actually write it. And there is. - return true; - } - - writePowerComponentUsage(proto, - BatteryUsageStatsAtomsProto.BatteryConsumerData.POWER_COMPONENTS, - componentId, powerDeciCoulombs, durationMs); - } return interestingData; } @@ -427,8 +320,9 @@ class PowerComponents { proto.end(slicesToken); } - private void writePowerComponentUsage(ProtoOutputStream proto, long tag, int componentId, - long powerDeciCoulombs, long durationMs) { + private void writePowerComponentUsage(ProtoOutputStream proto, long tag, + @BatteryConsumer.PowerComponentId int componentId, long powerDeciCoulombs, + long durationMs) { final long token = proto.start(tag); proto.write( BatteryUsageStatsAtomsProto.BatteryConsumerData.PowerComponentUsage @@ -460,7 +354,7 @@ class PowerComponents { } serializer.startTag(null, BatteryUsageStats.XML_TAG_COMPONENT); - serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_ID, key.powerComponent); + serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_ID, key.powerComponentId); if (key.processState != PROCESS_STATE_UNSPECIFIED) { serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_PROCESS_STATE, key.processState); @@ -485,32 +379,11 @@ class PowerComponents { } serializer.endTag(null, BatteryUsageStats.XML_TAG_COMPONENT); } - - final int customComponentEnd = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID - + mData.layout.customPowerComponentCount; - for (int componentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID; - componentId < customComponentEnd; - componentId++) { - final double powerMah = getConsumedPowerForCustomComponent(componentId); - final long durationMs = getUsageDurationForCustomComponentMillis(componentId); - if (powerMah == 0 && durationMs == 0) { - continue; - } - - serializer.startTag(null, BatteryUsageStats.XML_TAG_CUSTOM_COMPONENT); - serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_ID, componentId); - if (powerMah != 0) { - serializer.attributeDouble(null, BatteryUsageStats.XML_ATTR_POWER, powerMah); - } - if (durationMs != 0) { - serializer.attributeLong(null, BatteryUsageStats.XML_ATTR_DURATION, durationMs); - } - serializer.endTag(null, BatteryUsageStats.XML_TAG_CUSTOM_COMPONENT); - } - serializer.endTag(null, BatteryUsageStats.XML_TAG_POWER_COMPONENTS); } + // No longer part of the BatteryUsageStats XML format. Preserved for compatibility + private static final String XML_TAG_CUSTOM_COMPONENT_COMPAT = "custom_component"; static void parseXml(TypedXmlPullParser parser, PowerComponents.Builder builder) throws XmlPullParserException, IOException { @@ -525,7 +398,8 @@ class PowerComponents { && eventType != XmlPullParser.END_DOCUMENT) { if (eventType == XmlPullParser.START_TAG) { switch (parser.getName()) { - case BatteryUsageStats.XML_TAG_COMPONENT: { + case BatteryUsageStats.XML_TAG_COMPONENT: + case XML_TAG_CUSTOM_COMPONENT_COMPAT: { int componentId = -1; int processState = PROCESS_STATE_UNSPECIFIED; int screenState = SCREEN_STATE_UNSPECIFIED; @@ -564,27 +438,6 @@ class PowerComponents { builder.setUsageDurationMillis(key, durationMs); break; } - case BatteryUsageStats.XML_TAG_CUSTOM_COMPONENT: { - int componentId = -1; - double powerMah = 0; - long durationMs = 0; - for (int i = 0; i < parser.getAttributeCount(); i++) { - switch (parser.getAttributeName(i)) { - case BatteryUsageStats.XML_ATTR_ID: - componentId = parser.getAttributeInt(i); - break; - case BatteryUsageStats.XML_ATTR_POWER: - powerMah = parser.getAttributeDouble(i); - break; - case BatteryUsageStats.XML_ATTR_DURATION: - durationMs = parser.getAttributeLong(i); - break; - } - } - builder.setConsumedPowerForCustomComponent(componentId, powerMah); - builder.setUsageDurationForCustomComponentMillis(componentId, durationMs); - break; - } } } eventType = parser.next(); @@ -631,36 +484,6 @@ class PowerComponents { return this; } - /** - * Sets the amount of drain attributed to the specified custom drain type. - * - * @param componentId The ID of the custom power component. - * @param componentPower Amount of consumed power in mAh. - */ - @NonNull - public Builder setConsumedPowerForCustomComponent(int componentId, double componentPower) { - final int index = componentId - BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID; - if (index < 0 || index >= mData.layout.customPowerComponentCount) { - throw new IllegalArgumentException( - "Unsupported custom power component ID: " + componentId); - } - mData.putDouble(mData.layout.firstCustomConsumedPowerColumn + index, componentPower); - return this; - } - - @NonNull - public Builder addConsumedPowerForCustomComponent(int componentId, double componentPower) { - final int index = componentId - BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID; - if (index < 0 || index >= mData.layout.customPowerComponentCount) { - throw new IllegalArgumentException( - "Unsupported custom power component ID: " + componentId); - } - mData.putDouble(mData.layout.firstCustomConsumedPowerColumn + index, - mData.getDouble(mData.layout.firstCustomConsumedPowerColumn + index) - + componentPower); - return this; - } - @NonNull public Builder setUsageDurationMillis(BatteryConsumer.Key key, long componentUsageDurationMillis) { @@ -668,26 +491,6 @@ class PowerComponents { return this; } - /** - * Sets the amount of time used by the specified custom component. - * - * @param componentId The ID of the custom power component. - * @param componentUsageDurationMillis Amount of time in milliseconds. - */ - @NonNull - public Builder setUsageDurationForCustomComponentMillis(int componentId, - long componentUsageDurationMillis) { - final int index = componentId - BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID; - if (index < 0 || index >= mData.layout.customPowerComponentCount) { - throw new IllegalArgumentException( - "Unsupported custom power component ID: " + componentId); - } - - mData.putLong(mData.layout.firstCustomUsageDurationColumn + index, - componentUsageDurationMillis); - return this; - } - public void addPowerAndDuration(PowerComponents.Builder other) { addPowerAndDuration(other.mData); } @@ -706,19 +509,23 @@ class PowerComponents { } for (BatteryConsumer.Key key : mData.layout.keys) { - BatteryConsumer.Key otherKey = otherData.layout.getKey(key.powerComponent, + BatteryConsumer.Key otherKey = otherData.layout.getKey(key.powerComponentId, key.processState, key.screenState, key.powerState); if (otherKey == null) { continue; } - - mData.putDouble(key.mPowerColumnIndex, - mData.getDouble(key.mPowerColumnIndex) - + otherData.getDouble(otherKey.mPowerColumnIndex)); - mData.putLong(key.mDurationColumnIndex, - mData.getLong(key.mDurationColumnIndex) - + otherData.getLong(otherKey.mDurationColumnIndex)); - + if (mData.hasValue(key.mPowerColumnIndex) + || otherData.hasValue(otherKey.mPowerColumnIndex)) { + mData.putDouble(key.mPowerColumnIndex, + mData.getDouble(key.mPowerColumnIndex) + + otherData.getDouble(otherKey.mPowerColumnIndex)); + } + if (mData.hasValue(key.mDurationColumnIndex) + || otherData.hasValue(otherKey.mDurationColumnIndex)) { + mData.putLong(key.mDurationColumnIndex, + mData.getLong(key.mDurationColumnIndex) + + otherData.getLong(otherKey.mDurationColumnIndex)); + } if (key.mPowerModelColumnIndex == POWER_MODEL_NOT_INCLUDED) { continue; } @@ -742,21 +549,6 @@ class PowerComponents { BatteryConsumer.POWER_MODEL_UNDEFINED); } } - - for (int i = mData.layout.customPowerComponentCount - 1; i >= 0; i--) { - final int powerColumnIndex = mData.layout.firstCustomConsumedPowerColumn + i; - final int otherPowerColumnIndex = - otherData.layout.firstCustomConsumedPowerColumn + i; - mData.putDouble(powerColumnIndex, - mData.getDouble(powerColumnIndex) + otherData.getDouble( - otherPowerColumnIndex)); - - final int usageColumnIndex = mData.layout.firstCustomUsageDurationColumn + i; - final int otherDurationColumnIndex = - otherData.layout.firstCustomUsageDurationColumn + i; - mData.putLong(usageColumnIndex, mData.getLong(usageColumnIndex) - + otherData.getLong(otherDurationColumnIndex)); - } } /** @@ -765,15 +557,12 @@ class PowerComponents { */ public double getTotalPower() { double totalPowerMah = 0; - for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT; - componentId++) { - totalPowerMah += mData.getDouble( - mData.layout.getKeyOrThrow(componentId, PROCESS_STATE_ANY, SCREEN_STATE_ANY, - POWER_STATE_ANY).mPowerColumnIndex); - } - for (int i = 0; i < mData.layout.customPowerComponentCount; i++) { - totalPowerMah += mData.getDouble( - mData.layout.firstCustomConsumedPowerColumn + i); + for (BatteryConsumer.Key key : mData.layout.keys) { + if (key.processState == PROCESS_STATE_UNSPECIFIED + && key.screenState == SCREEN_STATE_UNSPECIFIED + && key.powerState == POWER_STATE_UNSPECIFIED) { + totalPowerMah += mData.getDouble(key.mPowerColumnIndex); + } } return totalPowerMah; } @@ -783,7 +572,7 @@ class PowerComponents { */ @NonNull public PowerComponents build() { - for (BatteryConsumer.Key key: mData.layout.keys) { + for (BatteryConsumer.Key key : mData.layout.keys) { if (key.mPowerModelColumnIndex != POWER_MODEL_NOT_INCLUDED) { if (mData.getInt(key.mPowerModelColumnIndex) == POWER_MODEL_UNINITIALIZED) { mData.putInt(key.mPowerModelColumnIndex, @@ -798,9 +587,7 @@ class PowerComponents { } } - if (mData.getDouble(mData.layout.totalConsumedPowerColumnIndex) == 0) { - mData.putDouble(mData.layout.totalConsumedPowerColumnIndex, getTotalPower()); - } + mData.putDouble(mData.layout.totalConsumedPowerColumnIndex, getTotalPower()); return new PowerComponents(this); } } diff --git a/core/java/com/android/internal/os/PowerStats.java b/core/java/com/android/internal/os/PowerStats.java index 488e06f9a1ad..aafef6c8b5fd 100644 --- a/core/java/com/android/internal/os/PowerStats.java +++ b/core/java/com/android/internal/os/PowerStats.java @@ -100,6 +100,7 @@ public final class PowerStats { * to; or a custom power component ID (if the value * is >= {@link BatteryConsumer#FIRST_CUSTOM_POWER_COMPONENT_ID}). */ + @BatteryConsumer.PowerComponentId public final int powerComponentId; public final String name; @@ -142,9 +143,10 @@ public final class PowerStats { extras); } - public Descriptor(int customPowerComponentId, String name, int statsArrayLength, - @Nullable SparseArray<String> stateLabels, int stateStatsArrayLength, - int uidStatsArrayLength, @NonNull PersistableBundle extras) { + public Descriptor(@BatteryConsumer.PowerComponentId int powerComponentId, String name, + int statsArrayLength, @Nullable SparseArray<String> stateLabels, + int stateStatsArrayLength, int uidStatsArrayLength, + @NonNull PersistableBundle extras) { if (statsArrayLength > MAX_STATS_ARRAY_LENGTH) { throw new IllegalArgumentException( "statsArrayLength is too high. Max = " + MAX_STATS_ARRAY_LENGTH); @@ -157,7 +159,7 @@ public final class PowerStats { throw new IllegalArgumentException( "uidStatsArrayLength is too high. Max = " + MAX_UID_STATS_ARRAY_LENGTH); } - this.powerComponentId = customPowerComponentId; + this.powerComponentId = powerComponentId; this.name = name; this.statsArrayLength = statsArrayLength; this.stateLabels = stateLabels != null ? stateLabels : new SparseArray<>(); diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 63331598ad68..4aac7a0a04eb 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -1347,7 +1347,6 @@ public final class BatteryStatsService extends IBatteryStats.Stub bus.getStatsDuration(), bus.getDischargePercentage(), bus.getDischargeDurationMs()); - if (DBG) { Slog.d(TAG, "BatteryUsageStats dump = " + bus); } @@ -1357,45 +1356,25 @@ public final class BatteryStatsService extends IBatteryStats.Stub final float totalDeviceConsumedPowerMah = (float) deviceConsumer.getConsumedPower(); - for (@BatteryConsumer.PowerComponent int componentId = 0; - componentId < BatteryConsumer.POWER_COMPONENT_COUNT; - componentId++) { + for (@BatteryConsumer.PowerComponentId int componentIndex : + deviceConsumer.getPowerComponentIds()) { for (@BatteryConsumer.ProcessState int processState : UID_PROCESS_STATES) { - if (!addStatsForPredefinedComponent( + if (!addStatsForPowerComponent( data, sessionInfo, Process.INVALID_UID, processState, totalDeviceConsumedPowerMah, + 0, deviceConsumer, - componentId)) { + componentIndex)) { return StatsManager.PULL_SUCCESS; } } } - final int customPowerComponentCount = deviceConsumer.getCustomPowerComponentCount(); - for (int componentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID; - componentId - < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID - + customPowerComponentCount; - componentId++) { - - if (!addStatsForCustomComponent( - data, - sessionInfo, - Process.INVALID_UID, - BatteryConsumer.PROCESS_STATE_UNSPECIFIED, - 0, - totalDeviceConsumedPowerMah, - deviceConsumer, - componentId)) { - return StatsManager.PULL_SUCCESS; - } - } - final List<UidBatteryConsumer> uidConsumers = bus.getUidBatteryConsumers(); uidConsumers.sort( Comparator.<BatteryConsumer>comparingDouble(BatteryConsumer::getConsumedPower) @@ -1406,47 +1385,22 @@ public final class BatteryStatsService extends IBatteryStats.Stub final int uid = uidConsumer.getUid(); final float totalConsumedPowerMah = (float) uidConsumer.getConsumedPower(); - for (@BatteryConsumer.PowerComponent int componentId = 0; - componentId < BatteryConsumer.POWER_COMPONENT_COUNT; - componentId++) { - - for (@BatteryConsumer.ProcessState int processState : UID_PROCESS_STATES) { - - if (!addStatsForPredefinedComponent( - data, - sessionInfo, - uid, - processState, - totalConsumedPowerMah, - uidConsumer, - componentId)) { - return StatsManager.PULL_SUCCESS; - } - } - } + for (@BatteryConsumer.PowerComponentId int componentIndex : + uidConsumer.getPowerComponentIds()) { - // looping over custom components - for (int componentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID; - componentId - < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID - + customPowerComponentCount; - componentId++) { for (@BatteryConsumer.ProcessState int processState : UID_PROCESS_STATES) { - final long timeInStateMillis = - uidConsumer.getTimeInProcessStateMs(processState); - if (timeInStateMillis <= 0) { - continue; - } - if (!addStatsForCustomComponent( + long timeInProcessStateMs = uidConsumer.getTimeInProcessStateMs( + processState); + if (!addStatsForPowerComponent( data, sessionInfo, uid, processState, - timeInStateMillis, totalConsumedPowerMah, + timeInProcessStateMs, uidConsumer, - componentId)) { + componentIndex)) { return StatsManager.PULL_SUCCESS; } } @@ -1455,20 +1409,21 @@ public final class BatteryStatsService extends IBatteryStats.Stub return StatsManager.PULL_SUCCESS; } - private boolean addStatsForPredefinedComponent( + private boolean addStatsForPowerComponent( List<StatsEvent> data, SessionInfo sessionInfo, int uid, @BatteryConsumer.ProcessState int processState, float totalConsumedPowerMah, + long timeInState, BatteryConsumer batteryConsumer, - @BatteryConsumer.PowerComponent int componentId) { + @BatteryConsumer.PowerComponentId int componentId) { final BatteryConsumer.Key key = batteryConsumer.getKey(componentId, processState); if (key == null) { return true; } - final String powerComponentName = BatteryConsumer.powerComponentIdToString(componentId); + final String powerComponentName = batteryConsumer.getPowerComponentName(componentId); final float powerMah = (float) batteryConsumer.getConsumedPower(key); final long powerComponentDurationMillis = batteryConsumer.getUsageDurationMillis(key); @@ -1476,13 +1431,6 @@ public final class BatteryStatsService extends IBatteryStats.Stub return true; } - long timeInState = 0; - if (batteryConsumer instanceof UidBatteryConsumer) { - timeInState = - ((UidBatteryConsumer) batteryConsumer) - .getTimeInProcessStateMs(processState); - } - return addStatsAtom( data, sessionInfo, @@ -1495,44 +1443,6 @@ public final class BatteryStatsService extends IBatteryStats.Stub powerComponentDurationMillis); } - private boolean addStatsForCustomComponent( - List<StatsEvent> data, - SessionInfo sessionInfo, - int uid, - @BatteryConsumer.ProcessState int processState, - long timeInStateMillis, - float totalConsumedPowerMah, - BatteryConsumer batteryConsumer, - int componentId) { - - if (componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID) { - throw new IllegalArgumentException("Invalid custom component id: " + componentId); - } - - final float powerMah = - (float) batteryConsumer.getConsumedPowerForCustomComponent(componentId); - if (powerMah == 0) { - return true; - } - - final String powerComponentName = - batteryConsumer.getCustomPowerComponentName(componentId); - - final long powerComponentDurationMillis = - batteryConsumer.getUsageDurationForCustomComponentMillis(componentId); - - return addStatsAtom( - data, - sessionInfo, - uid, - processState, - timeInStateMillis, - powerComponentName, - totalConsumedPowerMah, - powerMah, - powerComponentDurationMillis); - } - /** * Returns true on success and false if reached max atoms capacity and no more atoms should * be added diff --git a/services/core/java/com/android/server/power/stats/CustomEnergyConsumerPowerCalculator.java b/services/core/java/com/android/server/power/stats/CustomEnergyConsumerPowerCalculator.java index 5b7467e63c3a..c1f2ae8de96b 100644 --- a/services/core/java/com/android/server/power/stats/CustomEnergyConsumerPowerCalculator.java +++ b/services/core/java/com/android/server/power/stats/CustomEnergyConsumerPowerCalculator.java @@ -62,7 +62,7 @@ public class CustomEnergyConsumerPowerCalculator extends PowerCalculator { builder.getAggregateBatteryConsumerBuilder( BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE); for (int i = 0; i < customEnergyConsumerPowerMah.length; i++) { - deviceBatteryConsumerBuilder.setConsumedPowerForCustomComponent( + deviceBatteryConsumerBuilder.setConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i, customEnergyConsumerPowerMah[i]); } @@ -72,7 +72,7 @@ public class CustomEnergyConsumerPowerCalculator extends PowerCalculator { builder.getAggregateBatteryConsumerBuilder( BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS); for (int i = 0; i < totalAppPowerMah.length; i++) { - appsBatteryConsumerBuilder.setConsumedPowerForCustomComponent( + appsBatteryConsumerBuilder.setConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i, totalAppPowerMah[i]); } @@ -96,7 +96,7 @@ public class CustomEnergyConsumerPowerCalculator extends PowerCalculator { newTotalPowerMah = totalPowerMah; } for (int i = 0; i < customEnergyConsumerPowerMah.length; i++) { - app.setConsumedPowerForCustomComponent( + app.setConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i, customEnergyConsumerPowerMah[i]); if (!app.isVirtualUid()) { diff --git a/services/core/java/com/android/server/power/stats/PowerComponentAggregatedPowerStats.java b/services/core/java/com/android/server/power/stats/PowerComponentAggregatedPowerStats.java index 6820197fa0f2..950674147861 100644 --- a/services/core/java/com/android/server/power/stats/PowerComponentAggregatedPowerStats.java +++ b/services/core/java/com/android/server/power/stats/PowerComponentAggregatedPowerStats.java @@ -172,6 +172,9 @@ class PowerComponentAggregatedPowerStats { void setUidStats(int uid, int[] states, long[] values) { UidStats uidStats = getUidStats(uid); + if (uidStats.stats == null) { + createUidStats(uidStats, mPowerStatsTimestamp); + } uidStats.stats.setStats(states, values); } diff --git a/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java b/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java index 081e560bd74a..c734f683fff0 100644 --- a/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java +++ b/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java @@ -46,6 +46,10 @@ public class PowerStatsAggregator { mHistory = history; } + public AggregatedPowerStatsConfig getConfig() { + return mAggregatedPowerStatsConfig; + } + void setPowerComponentEnabled(int powerComponentId, boolean enabled) { synchronized (this) { if (mStats != null) { diff --git a/services/core/java/com/android/server/power/stats/PowerStatsExporter.java b/services/core/java/com/android/server/power/stats/PowerStatsExporter.java index 281faf139a60..c5bed245e287 100644 --- a/services/core/java/com/android/server/power/stats/PowerStatsExporter.java +++ b/services/core/java/com/android/server/power/stats/PowerStatsExporter.java @@ -16,12 +16,14 @@ package com.android.server.power.stats; +import android.annotation.Nullable; import android.os.AggregateBatteryConsumer; import android.os.BatteryConsumer; import android.os.BatteryUsageStats; import android.os.UidBatteryConsumer; import android.util.Slog; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.PowerStats; import java.util.ArrayList; @@ -59,7 +61,7 @@ public class PowerStatsExporter { */ public void exportAggregatedPowerStats(BatteryUsageStats.Builder batteryUsageStatsBuilder, long monotonicStartTime, long monotonicEndTime) { - synchronized (this) { + synchronized (mPowerStatsAggregator) { boolean hasStoredSpans = false; long maxEndTime = monotonicStartTime; List<PowerStatsSpan.Metadata> spans = mPowerStatsStore.getTableOfContents(); @@ -116,7 +118,8 @@ public class PowerStatsExporter { } } - private void populateBatteryUsageStatsBuilder( + @VisibleForTesting + void populateBatteryUsageStatsBuilder( BatteryUsageStats.Builder batteryUsageStatsBuilder, AggregatedPowerStats stats) { List<PowerComponentAggregatedPowerStats> powerComponentStats = stats.getPowerComponentStats(); @@ -125,15 +128,17 @@ public class PowerStatsExporter { } } - private static void populateBatteryUsageStatsBuilder( + private void populateBatteryUsageStatsBuilder( BatteryUsageStats.Builder batteryUsageStatsBuilder, PowerComponentAggregatedPowerStats powerComponentStats) { PowerStats.Descriptor descriptor = powerComponentStats.getPowerStatsDescriptor(); if (descriptor == null) { return; } - boolean isCustomComponent = - descriptor.powerComponentId >= BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID; + + if (!batteryUsageStatsBuilder.isSupportedPowerComponent(descriptor.powerComponentId)) { + return; + } PowerStatsLayout layout = new PowerStatsLayout(); layout.fromExtras(descriptor.extras); @@ -149,16 +154,17 @@ public class PowerStatsExporter { } for (int powerState = 0; powerState < BatteryConsumer.POWER_STATE_COUNT; powerState++) { - if (batteryUsageStatsBuilder.isPowerStateDataNeeded() && !isCustomComponent) { - if (powerState == BatteryConsumer.POWER_STATE_UNSPECIFIED) { - continue; + if (batteryUsageStatsBuilder.isPowerStateDataNeeded()) { + if (powerState != BatteryConsumer.POWER_STATE_UNSPECIFIED) { + populateAggregatedBatteryConsumer(batteryUsageStatsBuilder, + powerComponentStats, + layout, deviceStats, screenState, powerState); } - } else if (powerState != BatteryConsumer.POWER_STATE_BATTERY) { - continue; + } else if (powerState == BatteryConsumer.POWER_STATE_BATTERY) { + populateAggregatedBatteryConsumer(batteryUsageStatsBuilder, + powerComponentStats, + layout, deviceStats, screenState, powerState); } - - populateAggregatedBatteryConsumer(batteryUsageStatsBuilder, powerComponentStats, - layout, deviceStats, screenState, powerState); } } if (layout.isUidPowerAttributionSupported()) { @@ -167,15 +173,12 @@ public class PowerStatsExporter { } } - private static void populateAggregatedBatteryConsumer( + private void populateAggregatedBatteryConsumer( BatteryUsageStats.Builder batteryUsageStatsBuilder, PowerComponentAggregatedPowerStats powerComponentStats, PowerStatsLayout layout, long[] deviceStats, @BatteryConsumer.ScreenState int screenState, @BatteryConsumer.PowerState int powerState) { int powerComponentId = powerComponentStats.powerComponentId; - boolean isCustomComponent = - powerComponentId >= BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID; - double[] totalPower = new double[1]; MultiStateStats.States.forEachTrackedStateCombination( powerComponentStats.getConfig().getDeviceStateConfig(), @@ -194,38 +197,27 @@ public class PowerStatsExporter { AggregateBatteryConsumer.Builder deviceScope = batteryUsageStatsBuilder.getAggregateBatteryConsumerBuilder( BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE); - if (isCustomComponent) { - if (batteryUsageStatsBuilder.isSupportedCustomPowerComponent(powerComponentId)) { - deviceScope.addConsumedPowerForCustomComponent(powerComponentId, totalPower[0]); - } - } else { - BatteryConsumer.Key key = deviceScope.getKey(powerComponentId, - BatteryConsumer.PROCESS_STATE_ANY, screenState, powerState); - if (key != null) { - deviceScope.addConsumedPower(key, totalPower[0], - BatteryConsumer.POWER_MODEL_UNDEFINED); - } - deviceScope.addConsumedPower(powerComponentId, totalPower[0], + BatteryConsumer.Key key = getKeyForPartialTotal(batteryUsageStatsBuilder, deviceScope, + powerComponentId, screenState, powerState); + if (key != null) { + deviceScope.addConsumedPower(key, totalPower[0], BatteryConsumer.POWER_MODEL_UNDEFINED); } + deviceScope.addConsumedPower(powerComponentId, totalPower[0], + BatteryConsumer.POWER_MODEL_UNDEFINED); } - private static void populateBatteryConsumers( + private void populateBatteryConsumers( BatteryUsageStats.Builder batteryUsageStatsBuilder, PowerComponentAggregatedPowerStats powerComponentStats, PowerStatsLayout layout) { AggregatedPowerStatsConfig.PowerComponent powerComponent = powerComponentStats.getConfig(); - int powerComponentId = powerComponent.getPowerComponentId(); - boolean isCustomComponent = - powerComponentId >= BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID; PowerStats.Descriptor descriptor = powerComponentStats.getPowerStatsDescriptor(); long[] uidStats = new long[descriptor.uidStatsArrayLength]; - // TODO(b/347101393): add support for per-procstate breakdown for custom energy consumers boolean breakDownByProcState = batteryUsageStatsBuilder.isProcessStateDataNeeded() && powerComponent - .getUidStateConfig()[AggregatedPowerStatsConfig.STATE_PROCESS_STATE].isTracked() - && !isCustomComponent; + .getUidStateConfig()[AggregatedPowerStatsConfig.STATE_PROCESS_STATE].isTracked(); ArrayList<Integer> uids = new ArrayList<>(); powerComponentStats.collectUids(uids); @@ -239,7 +231,7 @@ public class PowerStatsExporter { } for (int powerState = 0; powerState < BatteryConsumer.POWER_STATE_COUNT; powerState++) { - if (batteryUsageStatsBuilder.isPowerStateDataNeeded() && !isCustomComponent) { + if (batteryUsageStatsBuilder.isPowerStateDataNeeded()) { if (powerState == BatteryConsumer.POWER_STATE_UNSPECIFIED) { continue; } @@ -254,14 +246,20 @@ public class PowerStatsExporter { } } - private static void populateUidBatteryConsumers( + private void populateUidBatteryConsumers( BatteryUsageStats.Builder batteryUsageStatsBuilder, PowerComponentAggregatedPowerStats powerComponentStats, PowerStatsLayout layout, List<Integer> uids, AggregatedPowerStatsConfig.PowerComponent powerComponent, long[] uidStats, boolean breakDownByProcState, @BatteryConsumer.ScreenState int screenState, @BatteryConsumer.PowerState int powerState) { - int powerComponentId = powerComponentStats.powerComponentId; + if (!batteryUsageStatsBuilder.isPowerStateDataNeeded() + && powerState != BatteryConsumer.POWER_STATE_BATTERY) { + return; + } + + @BatteryConsumer.PowerComponentId int powerComponentId = + powerComponentStats.powerComponentId; double[] powerByProcState = new double[breakDownByProcState ? BatteryConsumer.PROCESS_STATE_COUNT : 1]; double powerAllApps = 0; @@ -283,63 +281,81 @@ public class PowerStatsExporter { } double power = layout.getUidPowerEstimate(uidStats); - int procState = breakDownByProcState - ? states[AggregatedPowerStatsConfig.STATE_PROCESS_STATE] - : BatteryConsumer.PROCESS_STATE_UNSPECIFIED; - powerByProcState[procState] += power; + if (breakDownByProcState) { + int procState = states[AggregatedPowerStatsConfig.STATE_PROCESS_STATE]; + // There is a difference in how PowerComponentAggregatedPowerStats + // and BatteryUsageStats see the "unspecified" process state. + // PowerComponentAggregatedPowerStats preserves it as is. + // BatteryUsageStats uses PROCESS_STATE_UNSPECIFIED to hold the total + // across all states, and PROCESS_STATE_UNSPECIFIED is treated + // the same as PROCESS_STATE_BACKGROUND, which makes sense since + // PROCESS_STATE_UNSPECIFIED is only present for headless processes + // like Process.ROOT_UID, Process.WIFI_UID etc. + if (procState == BatteryConsumer.PROCESS_STATE_UNSPECIFIED) { + procState = BatteryConsumer.PROCESS_STATE_BACKGROUND; + } + powerByProcState[procState] += power; + } + powerByProcState[BatteryConsumer.PROCESS_STATE_UNSPECIFIED] += power; }); - double powerAllProcStates = 0; + int resultScreenState = batteryUsageStatsBuilder.isScreenStateDataNeeded() + ? screenState : BatteryConsumer.SCREEN_STATE_UNSPECIFIED; + int resultPowerState = batteryUsageStatsBuilder.isPowerStateDataNeeded() + ? powerState : BatteryConsumer.POWER_STATE_UNSPECIFIED; for (int procState = 0; procState < powerByProcState.length; procState++) { double power = powerByProcState[procState]; if (power == 0) { continue; } - powerAllProcStates += power; - if (breakDownByProcState - && procState != BatteryConsumer.PROCESS_STATE_UNSPECIFIED) { - if (batteryUsageStatsBuilder.isPowerStateDataNeeded()) { - builder.addConsumedPower( - builder.getKey(powerComponentId, procState, screenState, - powerState), - power, BatteryConsumer.POWER_MODEL_UNDEFINED); - } else { - builder.addConsumedPower( - builder.getKey(powerComponentId, procState, screenState, - BatteryConsumer.POWER_STATE_UNSPECIFIED), - power, BatteryConsumer.POWER_MODEL_UNDEFINED); - } - } + BatteryConsumer.Key key = builder.getKey(powerComponentId, procState, + resultScreenState, resultPowerState); + builder.addConsumedPower(key, power, BatteryConsumer.POWER_MODEL_UNDEFINED); } - if (powerComponentId >= BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID) { - if (batteryUsageStatsBuilder.isSupportedCustomPowerComponent(powerComponentId)) { - builder.addConsumedPowerForCustomComponent(powerComponentId, - powerAllProcStates); - } - } else { - builder.addConsumedPower(powerComponentId, powerAllProcStates, + + if (resultScreenState != BatteryConsumer.SCREEN_STATE_UNSPECIFIED + || resultPowerState != BatteryConsumer.POWER_STATE_UNSPECIFIED) { + builder.addConsumedPower(powerComponentId, + powerByProcState[BatteryConsumer.PROCESS_STATE_UNSPECIFIED], BatteryConsumer.POWER_MODEL_UNDEFINED); } - powerAllApps += powerAllProcStates; + powerAllApps += powerByProcState[BatteryConsumer.PROCESS_STATE_UNSPECIFIED]; } AggregateBatteryConsumer.Builder allAppsScope = batteryUsageStatsBuilder.getAggregateBatteryConsumerBuilder( BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS); - if (powerComponentId >= BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID) { - if (batteryUsageStatsBuilder.isSupportedCustomPowerComponent(powerComponentId)) { - allAppsScope.addConsumedPowerForCustomComponent(powerComponentId, powerAllApps); - } - } else { - BatteryConsumer.Key key = allAppsScope.getKey(powerComponentId, - BatteryConsumer.PROCESS_STATE_ANY, screenState, powerState); - if (key != null) { + BatteryConsumer.Key key = getKeyForPartialTotal(batteryUsageStatsBuilder, allAppsScope, + powerComponentId, screenState, powerState); + if (key != null) { allAppsScope.addConsumedPower(key, powerAllApps, BatteryConsumer.POWER_MODEL_UNDEFINED); - } - allAppsScope.addConsumedPower(powerComponentId, powerAllApps, - BatteryConsumer.POWER_MODEL_UNDEFINED); } + allAppsScope.addConsumedPower(powerComponentId, powerAllApps, + BatteryConsumer.POWER_MODEL_UNDEFINED); + } + + @Nullable + private BatteryConsumer.Key getKeyForPartialTotal( + BatteryUsageStats.Builder batteryUsageStatsBuilder, + AggregateBatteryConsumer.Builder builder, + @BatteryConsumer.PowerComponentId int powerComponentId, + @BatteryConsumer.ScreenState int screenState, + @BatteryConsumer.PowerState int powerState) { + if (!batteryUsageStatsBuilder.isScreenStateDataNeeded()) { + screenState = BatteryConsumer.SCREEN_STATE_UNSPECIFIED; + } + if (!batteryUsageStatsBuilder.isPowerStateDataNeeded()) { + powerState = BatteryConsumer.POWER_STATE_UNSPECIFIED; + } + + if (screenState == BatteryConsumer.SCREEN_STATE_UNSPECIFIED + && powerState == BatteryConsumer.POWER_STATE_UNSPECIFIED) { + return null; + } + + return builder.getKey(powerComponentId, BatteryConsumer.PROCESS_STATE_UNSPECIFIED, + screenState, powerState); } private static boolean areMatchingStates(int[] states, diff --git a/services/core/java/com/android/server/power/stats/ScreenPowerStatsProcessor.java b/services/core/java/com/android/server/power/stats/ScreenPowerStatsProcessor.java index 908c75155f42..8fb1fd6aedd3 100644 --- a/services/core/java/com/android/server/power/stats/ScreenPowerStatsProcessor.java +++ b/services/core/java/com/android/server/power/stats/ScreenPowerStatsProcessor.java @@ -16,7 +16,7 @@ package com.android.server.power.stats; -import static android.os.BatteryConsumer.PROCESS_STATE_ANY; +import static android.os.BatteryConsumer.PROCESS_STATE_UNSPECIFIED; import static com.android.internal.os.PowerProfile.POWER_GROUP_DISPLAY_AMBIENT; import static com.android.internal.os.PowerProfile.POWER_GROUP_DISPLAY_SCREEN_FULL; @@ -197,7 +197,7 @@ public class ScreenPowerStatsProcessor extends PowerStatsProcessor { List<Integer> uids) { int[] uidStateValues = new int[stats.getConfig().getUidStateConfig().length]; uidStateValues[STATE_SCREEN] = SCREEN_STATE_ON; - uidStateValues[STATE_PROCESS_STATE] = PROCESS_STATE_ANY; + uidStateValues[STATE_PROCESS_STATE] = PROCESS_STATE_UNSPECIFIED; for (int i = mPlan.uidStateEstimates.size() - 1; i >= 0; i--) { UidStateEstimate uidStateEstimate = mPlan.uidStateEstimates.get(i); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsAtomTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsAtomTest.java index 37d8f2f74850..c5157b373ee6 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsAtomTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsAtomTest.java @@ -206,8 +206,8 @@ public class BatteryUsageStatsAtomTest { 20, 1234L, UID_0, - BatteryConsumer.PROCESS_STATE_FOREGROUND, - 1000L, + BatteryConsumer.PROCESS_STATE_UNSPECIFIED, + 0L, "CustomConsumer1", 1650.0f, 450.0f, @@ -220,11 +220,11 @@ public class BatteryUsageStatsAtomTest { 20, 1234L, UID_0, - BatteryConsumer.PROCESS_STATE_BACKGROUND, - 2000L, + BatteryConsumer.PROCESS_STATE_FOREGROUND, + 1000L, "CustomConsumer1", 1650.0f, - 450.0f, + 100.0f, 0L ); verify(statsLogger).buildStatsEvent( @@ -234,12 +234,12 @@ public class BatteryUsageStatsAtomTest { 20, 1234L, UID_0, - BatteryConsumer.PROCESS_STATE_FOREGROUND, - 1000L, - "CustomConsumer2", + BatteryConsumer.PROCESS_STATE_BACKGROUND, + 2000L, + "CustomConsumer1", 1650.0f, - 500.0f, - 800L + 350.0f, + 0L ); verify(statsLogger).buildStatsEvent( 1000L, @@ -248,8 +248,8 @@ public class BatteryUsageStatsAtomTest { 20, 1234L, UID_0, - BatteryConsumer.PROCESS_STATE_BACKGROUND, - 2000L, + BatteryConsumer.PROCESS_STATE_UNSPECIFIED, + 0, "CustomConsumer2", 1650.0f, 500.0f, @@ -352,21 +352,12 @@ public class BatteryUsageStatsAtomTest { for (PowerComponentUsage componentProto : consumerProto.powerComponents) { final int componentId = componentProto.component; - if (componentId < BatteryConsumer.POWER_COMPONENT_COUNT) { - assertEquals(message + " for component " + componentId, - convertMahToDc(consumer.getConsumedPower(componentId)), - componentProto.powerDeciCoulombs); - assertEquals(message + " for component " + componentId, - consumer.getUsageDurationMillis(componentId), - componentProto.durationMillis); - } else { - assertEquals(message + " for custom component " + componentId, - convertMahToDc(consumer.getConsumedPowerForCustomComponent(componentId)), - componentProto.powerDeciCoulombs); - assertEquals(message + " for custom component " + componentId, - consumer.getUsageDurationForCustomComponentMillis(componentId), - componentProto.durationMillis); - } + assertEquals(message + " for component " + componentId, + convertMahToDc(consumer.getConsumedPower(componentId)), + componentProto.powerDeciCoulombs); + assertEquals(message + " for component " + componentId, + consumer.getUsageDurationMillis(componentId), + componentProto.durationMillis); } for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT; @@ -506,13 +497,13 @@ public class BatteryUsageStatsAtomTest { BatteryConsumer.POWER_COMPONENT_SCREEN, 300) .setConsumedPower( BatteryConsumer.POWER_COMPONENT_CPU, 400) - .setConsumedPowerForCustomComponent( + .setConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 450) - .setConsumedPowerForCustomComponent( + .setConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + 1, 500) .setUsageDurationMillis( BatteryConsumer.POWER_COMPONENT_CPU, 600) - .setUsageDurationForCustomComponentMillis( + .setUsageDurationMillis( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + 1, 800); final BatteryConsumer.Key keyFg = uidBuilder.getKey(BatteryConsumer.POWER_COMPONENT_CPU, @@ -533,6 +524,17 @@ public class BatteryUsageStatsAtomTest { .setConsumedPower(keyCached, 9400, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION) .setUsageDurationMillis(keyFgs, 8400); + final BatteryConsumer.Key keyCustomFg = uidBuilder.getKey( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, + BatteryConsumer.PROCESS_STATE_FOREGROUND); + final BatteryConsumer.Key keyCustomBg = uidBuilder.getKey( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, + BatteryConsumer.PROCESS_STATE_BACKGROUND); + uidBuilder.setConsumedPower( + keyCustomFg, 100, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION); + uidBuilder.setConsumedPower( + keyCustomBg, 350, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION); + builder.getOrCreateUidBatteryConsumerBuilder(UID_1) .setPackageWithHighestDrain("myPackage1") .setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_FOREGROUND, 1234); @@ -554,11 +556,11 @@ public class BatteryUsageStatsAtomTest { .setConsumedPower( BatteryConsumer.POWER_COMPONENT_CAMERA, 20150, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION) - .setConsumedPowerForCustomComponent( + .setConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20200) .setUsageDurationMillis( BatteryConsumer.POWER_COMPONENT_CPU, 20300) - .setUsageDurationForCustomComponentMillis( + .setUsageDurationMillis( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20400); // Not used; just to make sure extraneous data doesn't mess things up. @@ -567,7 +569,7 @@ public class BatteryUsageStatsAtomTest { .setConsumedPower( BatteryConsumer.POWER_COMPONENT_CPU, 10100, BatteryConsumer.POWER_MODEL_POWER_PROFILE) - .setConsumedPowerForCustomComponent( + .setConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10200); return builder.build(); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java index 374426ad67a1..17c7efa94869 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java @@ -532,15 +532,15 @@ public class BatteryUsageStatsProviderTest { BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE); assertThat(device.getCustomPowerComponentName(componentId0)).isEqualTo("FOO"); assertThat(device.getCustomPowerComponentName(componentId1)).isEqualTo("BAR"); - assertThat(device.getConsumedPowerForCustomComponent(componentId0)) + assertThat(device.getConsumedPower(componentId0)) .isWithin(PRECISION).of(27.77777); - assertThat(device.getConsumedPowerForCustomComponent(componentId1)) + assertThat(device.getConsumedPower(componentId1)) .isWithin(PRECISION).of(55.55555); UidBatteryConsumer uid = stats.getUidBatteryConsumers().get(0); - assertThat(uid.getConsumedPowerForCustomComponent(componentId0)) + assertThat(uid.getConsumedPower(componentId0)) .isWithin(PRECISION).of(8.33333); - assertThat(uid.getConsumedPowerForCustomComponent(componentId1)) + assertThat(uid.getConsumedPower(componentId1)) .isWithin(PRECISION).of(8.33333); return null; }).when(powerStatsStore).storeBatteryUsageStats(anyLong(), any()); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java index 52bb5e839ca2..3ae4c3245941 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java @@ -173,14 +173,15 @@ public class BatteryUsageStatsTest { assertThat(dump).containsMatch(quote("(not on battery, screen off/doze)") + "\\s*" + "cpu: 123 apps: 123 duration: 456ms"); assertThat(dump).containsMatch( - "UID 271: 1200 fg: 1777 bg: 1888 fgs: 1999 cached: 123\\s*" - + quote("screen=300 cpu=5787 (27s 99ms) cpu:fg=1777 (7s 771ms) " + "UID 271: 1200 fg: 1777 bg: 2388 fgs: 1999 cached: 123\\s*" + + quote("screen=300 cpu=400 (600ms) cpu:fg=1777 (7s 771ms) " + "cpu:bg=1888 (8s 881ms) cpu:fgs=1999 (9s 991ms) " - + "cpu:cached=123 (456ms) FOO=500") + "\\s*" + + "cpu:cached=123 (456ms) FOO=500 (800ms) FOO:bg=500 (800ms)") + "\\s*" + quote("(on battery, screen on)") + "\\s*" - + quote("cpu:fg=1777 (7s 771ms)")); + + quote("cpu=1777 (7s 771ms) cpu:fg=1777 (7s 771ms) " + + "FOO=500 (800ms) FOO:bg=500 (800ms)")); assertThat(dump).containsMatch("User 42: 30.0\\s*" - + quote("cpu=10.0 (30ms) FOO=20.0")); + + quote("cpu=10.0 (30ms) FOO=20.0 (40ms)")); } @Test @@ -198,10 +199,10 @@ public class BatteryUsageStatsTest { assertThat(dump).contains("cpu: 20100 apps: 10100 duration: 20s 300ms"); assertThat(dump).contains("FOO: 20200 apps: 10200 duration: 20s 400ms"); assertThat(dump).containsMatch( - "UID 271: 1200 fg: 1777 bg: 1888 fgs: 1999 cached: 123\\s*" - + quote("screen=300 cpu=5787 (600ms) cpu:fg=1777 (7s 771ms) " + "UID 271: 1200 fg: 1777 bg: 2388 fgs: 1999 cached: 123\\s*" + + quote("screen=300 cpu=400 (600ms) cpu:fg=1777 (7s 771ms) " + "cpu:bg=1888 (8s 881ms) cpu:fgs=1999 (9s 991ms) " - + "cpu:cached=123 (456ms) FOO=500")); + + "cpu:cached=123 (456ms) FOO=500 (800ms) FOO:bg=500 (800ms)")); assertThat(dump).containsMatch("User 42: 30.0\\s*" + quote("cpu=10.0 (30ms) FOO=20.0")); } @@ -225,25 +226,24 @@ public class BatteryUsageStatsTest { .add(stats1) .add(stats2) .build(); - assertBatteryUsageStats(sum, 42345, 50, 2234, 4345, 1234, 1000, 5000, 5000); final List<UidBatteryConsumer> uidBatteryConsumers = sum.getUidBatteryConsumers(); for (UidBatteryConsumer uidBatteryConsumer : uidBatteryConsumers) { if (uidBatteryConsumer.getUid() == APP_UID1) { - assertUidBatteryConsumer(uidBatteryConsumer, 2124, null, - 5321, 6900, 532, 423, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 11772, + assertUidBatteryConsumer(uidBatteryConsumer, 1200 + 924, null, + 5321, 6900, 532, 423, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 400 + 345, POWER_MODEL_UNDEFINED, - 956, 1167, 1478, - true, 3554, 3776, 3998, 444, 3554, 15542, 3776, 17762, 3998, 19982, + 500 + 456, 1167, 1478, + true, 3554, 4732, 3998, 444, 3554, 15542, 3776, 17762, 3998, 19982, 444, 1110); } else if (uidBatteryConsumer.getUid() == APP_UID2) { assertUidBatteryConsumer(uidBatteryConsumer, 1332, "bar", - 1111, 2220, 2, 333, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 5985, + 1111, 2220, 2, 333, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 444, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 555, 666, 777, - true, 1777, 1888, 1999, 321, 1777, 7771, 1888, 8881, 1999, 9991, + true, 1777, 2443, 1999, 321, 1777, 7771, 1888, 8881, 1999, 9991, 321, 654); } else { fail("Unexpected UID " + uidBatteryConsumer.getUid()); @@ -291,9 +291,6 @@ public class BatteryUsageStatsTest { TypedXmlPullParser parser = Xml.newBinaryPullParser(); parser.setInput(in, StandardCharsets.UTF_8.name()); final BatteryUsageStats fromXml = BatteryUsageStats.createFromXml(parser); - - System.out.println("stats = " + stats); - System.out.println("fromXml = " + fromXml); assertBatteryUsageStats1(fromXml, true); } @@ -336,11 +333,11 @@ public class BatteryUsageStatsTest { builder.getOrCreateUserBatteryConsumerBuilder(USER_ID) .setConsumedPower( BatteryConsumer.POWER_COMPONENT_CPU, 10) - .setConsumedPowerForCustomComponent( + .setConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20) .setUsageDurationMillis( BatteryConsumer.POWER_COMPONENT_CPU, 30) - .setUsageDurationForCustomComponentMillis( + .setUsageDurationMillis( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 40); } return builder; @@ -405,11 +402,11 @@ public class BatteryUsageStatsTest { BatteryConsumer.POWER_COMPONENT_SCREEN, screenPower, screenPowerModel) .setConsumedPower( BatteryConsumer.POWER_COMPONENT_CPU, cpuPower, cpuPowerModel) - .setConsumedPowerForCustomComponent( + .setConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, customComponentPower) .setUsageDurationMillis( BatteryConsumer.POWER_COMPONENT_CPU, cpuDuration) - .setUsageDurationForCustomComponentMillis( + .setUsageDurationMillis( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, customComponentDuration); if (builder.isProcessStateDataNeeded()) { final BatteryConsumer.Key cpuFgKey = builder.isScreenStateDataNeeded() @@ -430,6 +427,15 @@ public class BatteryUsageStatsTest { final BatteryConsumer.Key cachedKey = uidBuilder.getKey( BatteryConsumer.POWER_COMPONENT_CPU, BatteryConsumer.PROCESS_STATE_CACHED); + final BatteryConsumer.Key customBgKey = builder.isScreenStateDataNeeded() + ? uidBuilder.getKey( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, + BatteryConsumer.PROCESS_STATE_BACKGROUND, + BatteryConsumer.SCREEN_STATE_ON, + BatteryConsumer.POWER_STATE_BATTERY) + : uidBuilder.getKey( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, + BatteryConsumer.PROCESS_STATE_BACKGROUND); uidBuilder .setConsumedPower(cpuFgKey, cpuPowerForeground, BatteryConsumer.POWER_MODEL_POWER_PROFILE) @@ -442,7 +448,10 @@ public class BatteryUsageStatsTest { .setUsageDurationMillis(cpuFgsKey, cpuDurationFgs) .setConsumedPower(cachedKey, cpuPowerCached, BatteryConsumer.POWER_MODEL_POWER_PROFILE) - .setUsageDurationMillis(cachedKey, cpuDurationCached); + .setUsageDurationMillis(cachedKey, cpuDurationCached) + .setConsumedPower(customBgKey, customComponentPower, + BatteryConsumer.POWER_MODEL_UNDEFINED) + .setUsageDurationMillis(customBgKey, customComponentDuration); } } @@ -456,12 +465,12 @@ public class BatteryUsageStatsTest { .setConsumedPower(consumedPower) .setConsumedPower( BatteryConsumer.POWER_COMPONENT_CPU, cpuPower) - .setConsumedPowerForCustomComponent( + .setConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, customComponentPower) .setUsageDurationMillis( BatteryConsumer.POWER_COMPONENT_CPU, cpuDuration) - .setUsageDurationForCustomComponentMillis( + .setUsageDurationMillis( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, customComponentDuration); if (builder.isPowerStateDataNeeded() || builder.isScreenStateDataNeeded()) { @@ -511,10 +520,10 @@ public class BatteryUsageStatsTest { for (UidBatteryConsumer uidBatteryConsumer : uidBatteryConsumers) { if (uidBatteryConsumer.getUid() == APP_UID1) { assertUidBatteryConsumer(uidBatteryConsumer, 1200, "foo", - 1000, 1500, 500, 300, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 5787, + 1000, 1500, 500, 300, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 400, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 500, 600, 800, - true, 1777, 1888, 1999, 123, 1777, 7771, 1888, 8881, 1999, 9991, 123, 456); + true, 1777, 2388, 1999, 123, 1777, 7771, 1888, 8881, 1999, 9991, 123, 456); } else { fail("Unexpected UID " + uidBatteryConsumer.getUid()); } @@ -593,11 +602,11 @@ public class BatteryUsageStatsTest { BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuPower); assertThat(uidBatteryConsumer.getPowerModel( BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuPowerModel); - assertThat(uidBatteryConsumer.getConsumedPowerForCustomComponent( + assertThat(uidBatteryConsumer.getConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(customComponentPower); assertThat(uidBatteryConsumer.getUsageDurationMillis( BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuDuration); - assertThat(uidBatteryConsumer.getUsageDurationForCustomComponentMillis( + assertThat(uidBatteryConsumer.getUsageDurationMillis( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo( customComponentDuration); assertThat(uidBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1); @@ -678,11 +687,11 @@ public class BatteryUsageStatsTest { int cpuDuration, int customComponentDuration) { assertThat(userBatteryConsumer.getConsumedPower( BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuPower); - assertThat(userBatteryConsumer.getConsumedPowerForCustomComponent( + assertThat(userBatteryConsumer.getConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(customComponentPower); assertThat(userBatteryConsumer.getUsageDurationMillis( BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuDuration); - assertThat(userBatteryConsumer.getUsageDurationForCustomComponentMillis( + assertThat(userBatteryConsumer.getUsageDurationMillis( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo( customComponentDuration); assertThat(userBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1); @@ -697,11 +706,11 @@ public class BatteryUsageStatsTest { aggregateBatteryConsumerScopeAllApps); assertThat(appsBatteryConsumer.getConsumedPower( BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuPower); - assertThat(appsBatteryConsumer.getConsumedPowerForCustomComponent( + assertThat(appsBatteryConsumer.getConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(customComponentPower); assertThat(appsBatteryConsumer.getUsageDurationMillis( BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuDuration); - assertThat(appsBatteryConsumer.getUsageDurationForCustomComponentMillis( + assertThat(appsBatteryConsumer.getUsageDurationMillis( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo( customComponentDuration); assertThat(appsBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/CustomEnergyConsumerPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CustomEnergyConsumerPowerCalculatorTest.java index 4ab706e28cf8..56362429e1f5 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/CustomEnergyConsumerPowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CustomEnergyConsumerPowerCalculatorTest.java @@ -68,26 +68,26 @@ public class CustomEnergyConsumerPowerCalculatorTest { mStatsRule.apply(calculator); UidBatteryConsumer uid = mStatsRule.getUidBatteryConsumer(APP_UID); - assertThat(uid.getConsumedPowerForCustomComponent( + assertThat(uid.getConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)) .isWithin(PRECISION).of(8.333333); - assertThat(uid.getConsumedPowerForCustomComponent( + assertThat(uid.getConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + 1)) .isWithin(PRECISION).of(33.33333); final BatteryConsumer deviceBatteryConsumer = mStatsRule.getDeviceBatteryConsumer(); - assertThat(deviceBatteryConsumer.getConsumedPowerForCustomComponent( + assertThat(deviceBatteryConsumer.getConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)) .isWithin(PRECISION).of(27.77777); - assertThat(deviceBatteryConsumer.getConsumedPowerForCustomComponent( + assertThat(deviceBatteryConsumer.getConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + 1)) .isWithin(PRECISION).of(55.55555); final BatteryConsumer appsBatteryConsumer = mStatsRule.getDeviceBatteryConsumer(); - assertThat(appsBatteryConsumer.getConsumedPowerForCustomComponent( + assertThat(appsBatteryConsumer.getConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)) .isWithin(PRECISION).of(27.77777); - assertThat(appsBatteryConsumer.getConsumedPowerForCustomComponent( + assertThat(appsBatteryConsumer.getConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + 1)) .isWithin(PRECISION).of(55.55555); } diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsExporterTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsExporterTest.java index 7f7967ba4d7b..1f5fba6dd410 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsExporterTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsExporterTest.java @@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertWithMessage; import static org.mockito.Mockito.mock; +import android.annotation.NonNull; import android.os.AggregateBatteryConsumer; import android.os.BatteryConsumer; import android.os.BatteryStats; @@ -129,6 +130,218 @@ public class PowerStatsExporterTest { } @Test + public void breakdownByState_processScreenAndPower() throws Exception { + BatteryUsageStats actual = prepareBatteryUsageStats(true, true, true); + String message = "Actual BatteryUsageStats: " + actual; + + assertAggregatedPowerEstimate(message, actual, + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE, + BatteryConsumer.POWER_COMPONENT_CPU, + 87600000); + assertAggregatedPowerEstimate(message, actual, + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS, + BatteryConsumer.POWER_COMPONENT_CPU, + 54321); + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_ANY, + BatteryConsumer.PROCESS_STATE_ANY, 54321); + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_ANY, 54321); + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_FOREGROUND, 50020); + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_BACKGROUND, + 4301); // Includes "unspecified" proc state + + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_ANY, BatteryConsumer.SCREEN_STATE_ON, + BatteryConsumer.POWER_STATE_BATTERY, 321); + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_FOREGROUND, BatteryConsumer.SCREEN_STATE_ON, + BatteryConsumer.POWER_STATE_BATTERY, 20); + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_BACKGROUND, BatteryConsumer.SCREEN_STATE_ON, + BatteryConsumer.POWER_STATE_BATTERY, 301); // bg + unsp + + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_ANY, BatteryConsumer.SCREEN_STATE_OTHER, + BatteryConsumer.POWER_STATE_BATTERY, 4000); + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_BACKGROUND, BatteryConsumer.SCREEN_STATE_OTHER, + BatteryConsumer.POWER_STATE_BATTERY, 4000); + + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_ANY, BatteryConsumer.SCREEN_STATE_OTHER, + BatteryConsumer.POWER_STATE_OTHER, 50000); + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_FOREGROUND, BatteryConsumer.SCREEN_STATE_OTHER, + BatteryConsumer.POWER_STATE_OTHER, 50000); + + actual.close(); + } + + @Test + public void breakdownByState_processAndScreen() throws Exception { + BatteryUsageStats actual = prepareBatteryUsageStats(true, true, false); + String message = "Actual BatteryUsageStats: " + actual; + + assertAggregatedPowerEstimate(message, actual, + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE, + BatteryConsumer.POWER_COMPONENT_CPU, + 7600000); // off-battery not included + assertAggregatedPowerEstimate(message, actual, + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE, + BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.SCREEN_STATE_ON, BatteryConsumer.POWER_STATE_ANY, + 600000); + assertAggregatedPowerEstimate(message, actual, + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE, + BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.SCREEN_STATE_OTHER, BatteryConsumer.POWER_STATE_ANY, + 7000000); + assertAggregatedPowerEstimate(message, actual, + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS, + BatteryConsumer.POWER_COMPONENT_CPU, + 4321); // off-battery not included + assertAggregatedPowerEstimate(message, actual, + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS, + BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.SCREEN_STATE_ON, BatteryConsumer.POWER_STATE_ANY, + 321); + assertAggregatedPowerEstimate(message, actual, + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS, + BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.SCREEN_STATE_OTHER, BatteryConsumer.POWER_STATE_ANY, + 4000); + + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_ANY, + BatteryConsumer.PROCESS_STATE_ANY, 4321); // off-battery not included + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_ANY, 4321); // off-battery not included + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_FOREGROUND, 20); // off-battery not included + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_BACKGROUND, + 4301); // includes unspecified proc state + + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_ANY, BatteryConsumer.SCREEN_STATE_ON, + BatteryConsumer.POWER_STATE_ANY, 321); + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_FOREGROUND, BatteryConsumer.SCREEN_STATE_ON, + BatteryConsumer.POWER_STATE_ANY, 20); + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_BACKGROUND, BatteryConsumer.SCREEN_STATE_ON, + BatteryConsumer.POWER_STATE_ANY, 301); + + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_ANY, BatteryConsumer.SCREEN_STATE_OTHER, + BatteryConsumer.POWER_STATE_ANY, 4000); + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_BACKGROUND, BatteryConsumer.SCREEN_STATE_OTHER, + BatteryConsumer.POWER_STATE_ANY, 4000); + + actual.close(); + } + + @Test + public void breakdownByState_processStateOnly() throws Exception { + BatteryUsageStats actual = prepareBatteryUsageStats(true, false, false); + String message = "Actual BatteryUsageStats: " + actual; + + assertAggregatedPowerEstimate(message, actual, + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE, + BatteryConsumer.POWER_COMPONENT_CPU, + 7600000); // off-battery not included + assertAggregatedPowerEstimate(message, actual, + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS, + BatteryConsumer.POWER_COMPONENT_CPU, + 4321); // off-battery not included + + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_ANY, + BatteryConsumer.PROCESS_STATE_ANY, 4321); // off-battery not included + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_ANY, 4321); // off-battery not included + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_FOREGROUND, 20); // off-battery not included + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, + BatteryConsumer.PROCESS_STATE_BACKGROUND, + 4301); // includes unspecified proc state + + actual.close(); + } + + private @NonNull BatteryUsageStats prepareBatteryUsageStats(boolean includeProcessStateData, + boolean includeScreenStateData, boolean includesPowerStateData) { + long[] deviceStats = new long[mCpuStatsArrayLayout.getDeviceStatsArrayLength()]; + long[] uidStats = new long[mCpuStatsArrayLayout.getUidStatsArrayLength()]; + + AggregatedPowerStats aps = new AggregatedPowerStats(mPowerStatsAggregator.getConfig()); + PowerComponentAggregatedPowerStats stats = aps.getPowerComponentStats( + BatteryConsumer.POWER_COMPONENT_CPU); + stats.setPowerStatsDescriptor(mPowerStatsDescriptor); + + mCpuStatsArrayLayout.setUidPowerEstimate(uidStats, 1); + stats.setUidStats(APP_UID1, new int[]{ + AggregatedPowerStatsConfig.POWER_STATE_BATTERY, + AggregatedPowerStatsConfig.SCREEN_STATE_ON, + BatteryConsumer.PROCESS_STATE_UNSPECIFIED}, uidStats); + + mCpuStatsArrayLayout.setUidPowerEstimate(uidStats, 20); + stats.setUidStats(APP_UID1, new int[]{ + AggregatedPowerStatsConfig.POWER_STATE_BATTERY, + AggregatedPowerStatsConfig.SCREEN_STATE_ON, + BatteryConsumer.PROCESS_STATE_FOREGROUND}, uidStats); + + mCpuStatsArrayLayout.setUidPowerEstimate(uidStats, 300); + stats.setUidStats(APP_UID1, new int[]{ + AggregatedPowerStatsConfig.POWER_STATE_BATTERY, + AggregatedPowerStatsConfig.SCREEN_STATE_ON, + BatteryConsumer.PROCESS_STATE_BACKGROUND}, uidStats); + + mCpuStatsArrayLayout.setUidPowerEstimate(uidStats, 4000); + stats.setUidStats(APP_UID1, new int[]{ + AggregatedPowerStatsConfig.POWER_STATE_BATTERY, + AggregatedPowerStatsConfig.SCREEN_STATE_OTHER, + BatteryConsumer.PROCESS_STATE_BACKGROUND}, uidStats); + + mCpuStatsArrayLayout.setUidPowerEstimate(uidStats, 50000); + stats.setUidStats(APP_UID1, new int[]{ + AggregatedPowerStatsConfig.POWER_STATE_OTHER, + AggregatedPowerStatsConfig.SCREEN_STATE_OTHER, + BatteryConsumer.PROCESS_STATE_FOREGROUND}, uidStats); + + mCpuStatsArrayLayout.setDevicePowerEstimate(deviceStats, 600000); + stats.setDeviceStats(new int[]{ + AggregatedPowerStatsConfig.POWER_STATE_BATTERY, + AggregatedPowerStatsConfig.SCREEN_STATE_ON}, deviceStats); + + mCpuStatsArrayLayout.setDevicePowerEstimate(deviceStats, 7000000); + stats.setDeviceStats(new int[]{ + AggregatedPowerStatsConfig.POWER_STATE_BATTERY, + AggregatedPowerStatsConfig.SCREEN_STATE_OTHER}, deviceStats); + + mCpuStatsArrayLayout.setDevicePowerEstimate(deviceStats, 80000000); + stats.setDeviceStats(new int[]{ + AggregatedPowerStatsConfig.POWER_STATE_OTHER, + AggregatedPowerStatsConfig.SCREEN_STATE_ON}, deviceStats); + + return exportToBatteryUsageStats(aps, includeProcessStateData, + includeScreenStateData, includesPowerStateData); + } + + private @NonNull BatteryUsageStats exportToBatteryUsageStats(AggregatedPowerStats aps, + boolean includeProcessStateData, boolean includeScreenStateData, + boolean includesPowerStateData) { + PowerStatsExporter exporter = new PowerStatsExporter(mPowerStatsStore, + mPowerStatsAggregator, /* batterySessionTimeSpanSlackMillis */ 0); + + BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(new String[0], false, + includeProcessStateData, includeScreenStateData, includesPowerStateData, 0); + exporter.populateBatteryUsageStatsBuilder(builder, aps); + return builder.build(); + } + + @Test public void breakdownByProcState_fullRange() throws Exception { breakdownByProcState_fullRange(false, false); } @@ -232,19 +445,28 @@ public class PowerStatsExporterTest { BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS, BatteryConsumer.POWER_COMPONENT_CPU, 7.51016); + assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_ANY, + BatteryConsumer.PROCESS_STATE_ANY, 4.33); assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU, BatteryConsumer.PROCESS_STATE_ANY, 3.97099); + assertUidPowerEstimate(message, actual, APP_UID1, + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, + BatteryConsumer.PROCESS_STATE_ANY, 0.360); + + assertUidPowerEstimate(message, actual, APP_UID2, BatteryConsumer.POWER_COMPONENT_ANY, + BatteryConsumer.PROCESS_STATE_ANY, 3.538999); assertUidPowerEstimate(message, actual, APP_UID2, BatteryConsumer.POWER_COMPONENT_CPU, BatteryConsumer.PROCESS_STATE_ANY, 3.538999); UidBatteryConsumer uidScope = actual.getUidBatteryConsumers().stream() .filter(us -> us.getUid() == APP_UID1).findFirst().orElse(null); // There shouldn't be any per-procstate data for (int procState = 0; procState < BatteryConsumer.PROCESS_STATE_COUNT; procState++) { - if (procState != BatteryConsumer.PROCESS_STATE_UNSPECIFIED) { - assertThat(uidScope.getConsumedPower(new BatteryConsumer.Dimensions( - BatteryConsumer.POWER_COMPONENT_CPU, - BatteryConsumer.PROCESS_STATE_FOREGROUND))).isEqualTo(0); + if (procState == BatteryConsumer.PROCESS_STATE_UNSPECIFIED) { + continue; } + double power = uidScope.getConsumedPower( + new BatteryConsumer.Dimensions(BatteryConsumer.POWER_COMPONENT_CPU, procState)); + assertWithMessage("procState=" + procState).that(power).isEqualTo(0); } actual.close(); } @@ -333,22 +555,34 @@ public class PowerStatsExporterTest { private void assertAggregatedPowerEstimate(String message, BatteryUsageStats bus, int scope, int componentId, double expected) { AggregateBatteryConsumer consumer = bus.getAggregateBatteryConsumer(scope); - double actual = componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID - ? consumer.getConsumedPower(componentId) - : consumer.getConsumedPowerForCustomComponent(componentId); + double actual = consumer.getConsumedPower(componentId); + assertWithMessage(message).that(actual).isWithin(TOLERANCE).of(expected); + } + + private void assertAggregatedPowerEstimate(String message, BatteryUsageStats bus, int scope, + int componentId, int screenState, int powerState, double expected) { + AggregateBatteryConsumer consumer = bus.getAggregateBatteryConsumer(scope); + double actual = consumer.getConsumedPower( + new BatteryConsumer.Dimensions(componentId, BatteryConsumer.PROCESS_STATE_ANY, + screenState, powerState)); assertWithMessage(message).that(actual).isWithin(TOLERANCE).of(expected); } private void assertUidPowerEstimate(String message, BatteryUsageStats bus, int uid, int componentId, int processState, double expected) { + assertUidPowerEstimate(message, bus, uid, componentId, processState, + BatteryConsumer.SCREEN_STATE_ANY, BatteryConsumer.POWER_STATE_ANY, + expected); + } + + private void assertUidPowerEstimate(String message, BatteryUsageStats bus, int uid, + int componentId, int processState, int screenState, int powerState, double expected) { List<UidBatteryConsumer> uidScopes = bus.getUidBatteryConsumers(); final UidBatteryConsumer uidScope = uidScopes.stream() .filter(us -> us.getUid() == uid).findFirst().orElse(null); assertWithMessage(message).that(uidScope).isNotNull(); - double actual = componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID - ? uidScope.getConsumedPower( - new BatteryConsumer.Dimensions(componentId, processState)) - : uidScope.getConsumedPowerForCustomComponent(componentId); + double actual = uidScope.getConsumedPower( + new BatteryConsumer.Dimensions(componentId, processState, screenState, powerState)); assertWithMessage(message).that(actual).isWithin(TOLERANCE).of(expected); } diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerStatsProcessorTest.java index 9fde61a51e75..c05a91062368 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerStatsProcessorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerStatsProcessorTest.java @@ -16,8 +16,6 @@ package com.android.server.power.stats; -import static android.os.BatteryConsumer.PROCESS_STATE_ANY; - import static com.android.server.power.stats.AggregatedPowerStatsConfig.POWER_STATE_BATTERY; import static com.android.server.power.stats.AggregatedPowerStatsConfig.POWER_STATE_OTHER; import static com.android.server.power.stats.AggregatedPowerStatsConfig.SCREEN_STATE_ON; @@ -280,7 +278,7 @@ public class ScreenPowerStatsProcessorTest { ScreenPowerStatsLayout layout = new ScreenPowerStatsLayout(descriptor); long[] stats = new long[descriptor.uidStatsArrayLength]; aggregatedStats.getUidStats(stats, uid, - new int[]{powerState, screenState, PROCESS_STATE_ANY}); + new int[]{powerState, screenState, BatteryConsumer.PROCESS_STATE_UNSPECIFIED}); assertThat(layout.getUidPowerEstimate(stats)).isWithin(PRECISION) .of(expectedScreenPowerEstimate); } diff --git a/tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java b/tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java index 4143f595f9a0..30cc002b4144 100644 --- a/tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java +++ b/tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java @@ -171,11 +171,11 @@ public class BatteryUsageStatsPerfTest { .setConsumedPower(123) .setConsumedPower( BatteryConsumer.POWER_COMPONENT_CPU, 10100) - .setConsumedPowerForCustomComponent( + .setConsumedPower( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10200) .setUsageDurationMillis( BatteryConsumer.POWER_COMPONENT_CPU, 10300) - .setUsageDurationForCustomComponentMillis( + .setUsageDurationMillis( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10400); for (int i = 0; i < 1000; i++) { @@ -191,10 +191,9 @@ public class BatteryUsageStatsPerfTest { consumerBuilder.setUsageDurationMillis(componentId, componentId * 1000); } - consumerBuilder.setConsumedPowerForCustomComponent( - BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 1234) - .setUsageDurationForCustomComponentMillis( - BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 4321); + consumerBuilder + .setConsumedPower(BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 1234) + .setUsageDurationMillis(BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 4321); } return builder.build(); } |