summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Dmitri Plotnikov <dplotnikov@google.com> 2024-07-30 17:33:25 -0700
committer Dmitri Plotnikov <dplotnikov@google.com> 2024-08-19 15:39:16 -0700
commita406aec7c5afbdcea043ba1f0b825c049159bb5d (patch)
tree2321ba86ce377e12a999e9226b5ef406bbfbe39c
parentf28c6040e47e7682141a260982f5bc2028be2072 (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
-rw-r--r--core/java/android/os/BatteryConsumer.java244
-rw-r--r--core/java/android/os/BatteryUsageStats.java166
-rw-r--r--core/java/android/os/BatteryUsageStatsQuery.java7
-rw-r--r--core/java/android/os/PowerComponents.java375
-rw-r--r--core/java/com/android/internal/os/PowerStats.java10
-rw-r--r--services/core/java/com/android/server/am/BatteryStatsService.java122
-rw-r--r--services/core/java/com/android/server/power/stats/CustomEnergyConsumerPowerCalculator.java6
-rw-r--r--services/core/java/com/android/server/power/stats/PowerComponentAggregatedPowerStats.java3
-rw-r--r--services/core/java/com/android/server/power/stats/PowerStatsAggregator.java4
-rw-r--r--services/core/java/com/android/server/power/stats/PowerStatsExporter.java172
-rw-r--r--services/core/java/com/android/server/power/stats/ScreenPowerStatsProcessor.java4
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsAtomTest.java68
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java8
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java75
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/CustomEnergyConsumerPowerCalculatorTest.java12
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsExporterTest.java256
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerStatsProcessorTest.java4
-rw-r--r--tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java11
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 &gt;= {@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();
}