Merge "Add BatteryConsumer.getCustomPowerComponentName() and getCustomPowerComponentCount()" into sc-dev

This commit is contained in:
Dmitri Plotnikov
2021-04-13 23:44:29 +00:00
committed by Android (Google) Code Review
21 changed files with 263 additions and 133 deletions

View File

@@ -149,6 +149,7 @@ public abstract class BatteryConsumer {
public static final int POWER_MODEL_MEASURED_ENERGY = 1;
private final PowerComponents mPowerComponents;
private String[] mCustomPowerComponentNames;
protected BatteryConsumer(@NonNull PowerComponents powerComponents) {
mPowerComponents = powerComponents;
@@ -192,6 +193,23 @@ public abstract class BatteryConsumer {
return mPowerComponents.getConsumedPowerForCustomComponent(componentId);
}
public int getCustomPowerComponentCount() {
return mPowerComponents.getCustomPowerComponentCount();
}
void setCustomPowerComponentNames(String[] customPowerComponentNames) {
mPowerComponents.setCustomPowerComponentNames(customPowerComponentNames);
}
/**
* Returns the name of the specified power component.
*
* @param componentId The ID of the custom power component.
*/
public String getCustomPowerComponentName(int componentId) {
return mPowerComponents.getCustomPowerComponentName(componentId);
}
/**
* Returns the amount of time since BatteryStats reset used by the specified component, e.g.
* CPU, WiFi etc.
@@ -222,9 +240,9 @@ public abstract class BatteryConsumer {
protected abstract static class BaseBuilder<T extends BaseBuilder<?>> {
final PowerComponents.Builder mPowerComponentsBuilder;
public BaseBuilder(int customPowerComponentCount, int customTimeComponentCount,
boolean includePowerModels) {
mPowerComponentsBuilder = new PowerComponents.Builder(customPowerComponentCount,
public BaseBuilder(@NonNull String[] customPowerComponentNames,
int customTimeComponentCount, boolean includePowerModels) {
mPowerComponentsBuilder = new PowerComponents.Builder(customPowerComponentNames,
customTimeComponentCount, includePowerModels);
}

View File

@@ -24,6 +24,7 @@ import com.android.internal.os.BatteryStatsHistory;
import com.android.internal.os.BatteryStatsHistoryIterator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
@@ -39,9 +40,10 @@ public final class BatteryUsageStats implements Parcelable {
private final double mDischargedPowerUpperBound;
private final long mBatteryTimeRemainingMs;
private final long mChargeTimeRemainingMs;
private final ArrayList<UidBatteryConsumer> mUidBatteryConsumers;
private final ArrayList<SystemBatteryConsumer> mSystemBatteryConsumers;
private final ArrayList<UserBatteryConsumer> mUserBatteryConsumers;
private final String[] mCustomPowerComponentNames;
private final List<UidBatteryConsumer> mUidBatteryConsumers;
private final List<SystemBatteryConsumer> mSystemBatteryConsumers;
private final List<UserBatteryConsumer> mUserBatteryConsumers;
private final Parcel mHistoryBuffer;
private final List<BatteryStats.HistoryTag> mHistoryTagPool;
@@ -54,6 +56,7 @@ public final class BatteryUsageStats implements Parcelable {
mHistoryTagPool = builder.mHistoryTagPool;
mBatteryTimeRemainingMs = builder.mBatteryTimeRemainingMs;
mChargeTimeRemainingMs = builder.mChargeTimeRemainingMs;
mCustomPowerComponentNames = builder.mCustomPowerComponentNames;
double totalPower = 0;
@@ -182,12 +185,31 @@ public final class BatteryUsageStats implements Parcelable {
mDischargedPowerUpperBound = source.readDouble();
mBatteryTimeRemainingMs = source.readLong();
mChargeTimeRemainingMs = source.readLong();
mUidBatteryConsumers = new ArrayList<>();
source.readParcelableList(mUidBatteryConsumers, getClass().getClassLoader());
mSystemBatteryConsumers = new ArrayList<>();
source.readParcelableList(mSystemBatteryConsumers, getClass().getClassLoader());
mUserBatteryConsumers = new ArrayList<>();
source.readParcelableList(mUserBatteryConsumers, getClass().getClassLoader());
mCustomPowerComponentNames = source.readStringArray();
int uidCount = source.readInt();
mUidBatteryConsumers = new ArrayList<>(uidCount);
for (int i = 0; i < uidCount; i++) {
final UidBatteryConsumer consumer =
UidBatteryConsumer.CREATOR.createFromParcel(source);
consumer.setCustomPowerComponentNames(mCustomPowerComponentNames);
mUidBatteryConsumers.add(consumer);
}
int sysCount = source.readInt();
mSystemBatteryConsumers = new ArrayList<>(sysCount);
for (int i = 0; i < sysCount; i++) {
final SystemBatteryConsumer consumer =
SystemBatteryConsumer.CREATOR.createFromParcel(source);
consumer.setCustomPowerComponentNames(mCustomPowerComponentNames);
mSystemBatteryConsumers.add(consumer);
}
int userCount = source.readInt();
mUserBatteryConsumers = new ArrayList<>(userCount);
for (int i = 0; i < userCount; i++) {
final UserBatteryConsumer consumer =
UserBatteryConsumer.CREATOR.createFromParcel(source);
consumer.setCustomPowerComponentNames(mCustomPowerComponentNames);
mUserBatteryConsumers.add(consumer);
}
if (source.readBoolean()) {
mHistoryBuffer = Parcel.obtain();
mHistoryBuffer.setDataSize(0);
@@ -211,6 +233,8 @@ public final class BatteryUsageStats implements Parcelable {
mHistoryBuffer = null;
mHistoryTagPool = null;
}
System.out.println("From Parcel = " + Arrays.toString(
mCustomPowerComponentNames));
}
@Override
@@ -222,9 +246,19 @@ public final class BatteryUsageStats implements Parcelable {
dest.writeDouble(mDischargedPowerUpperBound);
dest.writeLong(mBatteryTimeRemainingMs);
dest.writeLong(mChargeTimeRemainingMs);
dest.writeParcelableList(mUidBatteryConsumers, flags);
dest.writeParcelableList(mSystemBatteryConsumers, flags);
dest.writeParcelableList(mUserBatteryConsumers, flags);
dest.writeStringArray(mCustomPowerComponentNames);
dest.writeInt(mUidBatteryConsumers.size());
for (int i = mUidBatteryConsumers.size() - 1; i >= 0; i--) {
mUidBatteryConsumers.get(i).writeToParcel(dest, flags);
}
dest.writeInt(mSystemBatteryConsumers.size());
for (int i = mSystemBatteryConsumers.size() - 1; i >= 0; i--) {
mSystemBatteryConsumers.get(i).writeToParcel(dest, flags);
}
dest.writeInt(mUserBatteryConsumers.size());
for (int i = mUserBatteryConsumers.size() - 1; i >= 0; i--) {
mUserBatteryConsumers.get(i).writeToParcel(dest, flags);
}
if (mHistoryBuffer != null) {
dest.writeBoolean(true);
@@ -259,7 +293,7 @@ public final class BatteryUsageStats implements Parcelable {
* Builder for BatteryUsageStats.
*/
public static final class Builder {
private final int mCustomPowerComponentCount;
private final String[] mCustomPowerComponentNames;
private final int mCustomTimeComponentCount;
private final boolean mIncludePowerModels;
private long mStatsStartTimestampMs;
@@ -277,13 +311,13 @@ public final class BatteryUsageStats implements Parcelable {
private Parcel mHistoryBuffer;
private List<BatteryStats.HistoryTag> mHistoryTagPool;
public Builder(int customPowerComponentCount, int customTimeComponentCount) {
this(customPowerComponentCount, customTimeComponentCount, false);
public Builder(String[] customPowerComponentNames, int customTimeComponentCount) {
this(customPowerComponentNames, customTimeComponentCount, false);
}
public Builder(int customPowerComponentCount, int customTimeComponentCount,
public Builder(String[] customPowerComponentNames, int customTimeComponentCount,
boolean includePowerModels) {
mCustomPowerComponentCount = customPowerComponentCount;
mCustomPowerComponentNames = customPowerComponentNames;
mCustomTimeComponentCount = customTimeComponentCount;
mIncludePowerModels = includePowerModels;
}
@@ -366,7 +400,7 @@ public final class BatteryUsageStats implements Parcelable {
int uid = batteryStatsUid.getUid();
UidBatteryConsumer.Builder builder = mUidBatteryConsumerBuilders.get(uid);
if (builder == null) {
builder = new UidBatteryConsumer.Builder(mCustomPowerComponentCount,
builder = new UidBatteryConsumer.Builder(mCustomPowerComponentNames,
mCustomTimeComponentCount, mIncludePowerModels, batteryStatsUid);
mUidBatteryConsumerBuilders.put(uid, builder);
}
@@ -382,7 +416,7 @@ public final class BatteryUsageStats implements Parcelable {
@SystemBatteryConsumer.DrainType int drainType) {
SystemBatteryConsumer.Builder builder = mSystemBatteryConsumerBuilders.get(drainType);
if (builder == null) {
builder = new SystemBatteryConsumer.Builder(mCustomPowerComponentCount,
builder = new SystemBatteryConsumer.Builder(mCustomPowerComponentNames,
mCustomTimeComponentCount, mIncludePowerModels, drainType);
mSystemBatteryConsumerBuilders.put(drainType, builder);
}
@@ -397,7 +431,7 @@ public final class BatteryUsageStats implements Parcelable {
public UserBatteryConsumer.Builder getOrCreateUserBatteryConsumerBuilder(int userId) {
UserBatteryConsumer.Builder builder = mUserBatteryConsumerBuilders.get(userId);
if (builder == null) {
builder = new UserBatteryConsumer.Builder(mCustomPowerComponentCount,
builder = new UserBatteryConsumer.Builder(mCustomPowerComponentNames,
mCustomTimeComponentCount, mIncludePowerModels, userId);
mUserBatteryConsumerBuilders.put(userId, builder);
}

View File

@@ -26,7 +26,7 @@ import android.annotation.NonNull;
class PowerComponents {
private static final int CUSTOM_POWER_COMPONENT_OFFSET = BatteryConsumer.POWER_COMPONENT_COUNT
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID;
public static final int CUSTOM_TIME_COMPONENT_OFFSET = BatteryConsumer.TIME_COMPONENT_COUNT
private static final int CUSTOM_TIME_COMPONENT_OFFSET = BatteryConsumer.TIME_COMPONENT_COUNT
- BatteryConsumer.FIRST_CUSTOM_TIME_COMPONENT_ID;
private final double mTotalConsumedPowerMah;
@@ -34,9 +34,12 @@ class PowerComponents {
private final long[] mTimeComponentsMs;
private final int mCustomPowerComponentCount;
private final byte[] mPowerModels;
// Not written to Parcel and must be explicitly restored during the parent object's unparceling
private String[] mCustomPowerComponentNames;
PowerComponents(@NonNull Builder builder) {
mCustomPowerComponentCount = builder.mCustomPowerComponentCount;
mCustomPowerComponentNames = builder.mCustomPowerComponentNames;
mCustomPowerComponentCount = mCustomPowerComponentNames.length;
mPowerComponentsMah = builder.mPowerComponentsMah;
mTimeComponentsMs = builder.mTimeComponentsMs;
mTotalConsumedPowerMah = builder.getTotalPower();
@@ -117,6 +120,26 @@ class PowerComponents {
}
}
void setCustomPowerComponentNames(String[] customPowerComponentNames) {
mCustomPowerComponentNames = customPowerComponentNames;
}
public String getCustomPowerComponentName(int componentId) {
if (componentId >= BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID
&& componentId < BatteryConsumer.LAST_CUSTOM_POWER_COMPONENT_ID) {
try {
return mCustomPowerComponentNames[componentId
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID];
} catch (ArrayIndexOutOfBoundsException e) {
throw new IllegalArgumentException(
"Unsupported custom power component ID: " + componentId);
}
} else {
throw new IllegalArgumentException(
"Unsupported custom power component ID: " + componentId);
}
}
@BatteryConsumer.PowerModel
int getPowerModel(@BatteryConsumer.PowerComponent int component) {
if (mPowerModels == null) {
@@ -164,20 +187,24 @@ class PowerComponents {
}
}
public int getCustomPowerComponentCount() {
return mCustomPowerComponentCount;
}
/**
* Builder for PowerComponents.
*/
static final class Builder {
private final double[] mPowerComponentsMah;
private final int mCustomPowerComponentCount;
private final String[] mCustomPowerComponentNames;
private final long[] mTimeComponentsMs;
private final byte[] mPowerModels;
Builder(int customPowerComponentCount, int customTimeComponentCount,
Builder(@NonNull String[] customPowerComponentNames, int customTimeComponentCount,
boolean includePowerModels) {
mCustomPowerComponentCount = customPowerComponentCount;
mCustomPowerComponentNames = customPowerComponentNames;
int powerComponentCount =
BatteryConsumer.POWER_COMPONENT_COUNT + customPowerComponentCount;
BatteryConsumer.POWER_COMPONENT_COUNT + mCustomPowerComponentNames.length;
mPowerComponentsMah = new double[powerComponentCount];
mTimeComponentsMs =
new long[BatteryConsumer.TIME_COMPONENT_COUNT + customTimeComponentCount];

View File

@@ -140,9 +140,9 @@ public class SystemBatteryConsumer extends BatteryConsumer implements Parcelable
private double mPowerConsumedByAppsMah;
private List<UidBatteryConsumer.Builder> mUidBatteryConsumers;
Builder(int customPowerComponentCount, int customTimeComponentCount,
Builder(@NonNull String[] customPowerComponentNames, int customTimeComponentCount,
boolean includePowerModels, @DrainType int drainType) {
super(customPowerComponentCount, customTimeComponentCount, includePowerModels);
super(customPowerComponentNames, customTimeComponentCount, includePowerModels);
mDrainType = drainType;
}

View File

@@ -139,9 +139,9 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
public long mTimeInBackgroundMs;
private boolean mExcludeFromBatteryUsageStats;
public Builder(int customPowerComponentCount, int customTimeComponentCount,
public Builder(@NonNull String[] customPowerComponentNames, int customTimeComponentCount,
boolean includePowerModels, @NonNull BatteryStats.Uid batteryStatsUid) {
super(customPowerComponentCount, customTimeComponentCount, includePowerModels);
super(customPowerComponentNames, customTimeComponentCount, includePowerModels);
mBatteryStatsUid = batteryStatsUid;
mUid = batteryStatsUid.getUid();
}

View File

@@ -77,9 +77,9 @@ public class UserBatteryConsumer extends BatteryConsumer implements Parcelable {
private final int mUserId;
private List<UidBatteryConsumer.Builder> mUidBatteryConsumers;
Builder(int customPowerComponentCount, int customTimeComponentCount,
Builder(@NonNull String[] customPowerComponentNames, int customTimeComponentCount,
boolean includePowerModels, int userId) {
super(customPowerComponentCount, customTimeComponentCount, includePowerModels);
super(customPowerComponentNames, customTimeComponentCount, includePowerModels);
mUserId = userId;
}

View File

@@ -40,6 +40,7 @@ import android.net.INetworkStatsService;
import android.net.NetworkStats;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.BatteryConsumer;
import android.os.BatteryManager;
import android.os.BatteryStats;
import android.os.Binder;
@@ -160,7 +161,7 @@ public class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
static final int VERSION = 196;
static final int VERSION = 197;
// The maximum number of names wakelocks we will keep track of
// per uid; once the limit is reached, we batch the remaining wakelocks
@@ -6947,6 +6948,22 @@ public class BatteryStatsImpl extends BatteryStats {
return mGlobalMeasuredEnergyStats.getAccumulatedCustomBucketCharges();
}
/**
* Returns the names of custom power components.
*/
public @Nullable String[] getCustomPowerComponentNames() {
if (mGlobalMeasuredEnergyStats == null) {
return null;
}
final String[] names = mGlobalMeasuredEnergyStats.getCustomBucketNames();
for (int i = 0; i < names.length; i++) {
if (TextUtils.isEmpty(names[i])) {
names[i] = "CUSTOM_" + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i;
}
}
return names;
}
@Override public long getStartClockTime() {
final long currentTimeMs = System.currentTimeMillis();
if ((currentTimeMs > MILLISECONDS_IN_YEAR
@@ -14379,17 +14396,18 @@ public class BatteryStatsImpl extends BatteryStats {
mConstants.startObserving(context.getContentResolver());
registerUsbStateReceiver(context);
}
/**
* Initialize the measured charge stats data structures.
*
* @param supportedStandardBuckets boolean array indicating which {@link StandardPowerBucket}s
* are currently supported.
* If null, none are supported (regardless of numCustomBuckets).
* @param numCustomBuckets number of custom (OTHER) EnergyConsumers on this device
* are currently supported. If null, none are supported
* (regardless of customBucketNames).
* @param customBucketNames names of custom (OTHER) EnergyConsumers on this device
*/
@GuardedBy("this")
public void initMeasuredEnergyStatsLocked(@Nullable boolean[] supportedStandardBuckets,
int numCustomBuckets) {
String[] customBucketNames) {
boolean supportedBucketMismatch = false;
mScreenStateAtLastEnergyMeasurement = mScreenState;
@@ -14401,10 +14419,10 @@ public class BatteryStatsImpl extends BatteryStats {
} else {
if (mGlobalMeasuredEnergyStats == null) {
mGlobalMeasuredEnergyStats =
new MeasuredEnergyStats(supportedStandardBuckets, numCustomBuckets);
new MeasuredEnergyStats(supportedStandardBuckets, customBucketNames);
} else {
supportedBucketMismatch = !mGlobalMeasuredEnergyStats.isSupportEqualTo(
supportedStandardBuckets, numCustomBuckets);
supportedStandardBuckets, customBucketNames);
}
if (supportedStandardBuckets[MeasuredEnergyStats.POWER_BUCKET_BLUETOOTH]) {
@@ -14423,7 +14441,7 @@ public class BatteryStatsImpl extends BatteryStats {
if (supportedBucketMismatch) {
mGlobalMeasuredEnergyStats = supportedStandardBuckets == null
? null : new MeasuredEnergyStats(supportedStandardBuckets, numCustomBuckets);
? null : new MeasuredEnergyStats(supportedStandardBuckets, customBucketNames);
// Supported power buckets changed since last boot.
// Existing data is no longer reliable.
resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime());

View File

@@ -123,11 +123,7 @@ public class BatteryUsageStatsProvider {
final long realtimeUs = mStats.mClocks.elapsedRealtime() * 1000;
final long uptimeUs = mStats.mClocks.uptimeMillis() * 1000;
final long[] customMeasuredChargesUC =
mStats.getCustomConsumerMeasuredBatteryConsumptionUC();
final int customPowerComponentCount = customMeasuredChargesUC != null
? customMeasuredChargesUC.length
: 0;
final String[] customPowerComponentNames = mStats.getCustomPowerComponentNames();
// TODO(b/174186358): read extra time component number from configuration
final int customTimeComponentCount = 0;
@@ -136,7 +132,7 @@ public class BatteryUsageStatsProvider {
& BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_POWER_MODELS) != 0;
final BatteryUsageStats.Builder batteryUsageStatsBuilder = new BatteryUsageStats.Builder(
customPowerComponentCount, customTimeComponentCount, includePowerModels);
customPowerComponentNames, customTimeComponentCount, includePowerModels);
batteryUsageStatsBuilder.setStatsStartTimestamp(mStats.getStartClockTime());
SparseArray<? extends BatteryStats.Uid> uidStats = mStats.getUidStats();

View File

@@ -23,6 +23,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.text.TextUtils;
import android.util.DebugUtils;
import android.util.Slog;
import android.view.Display;
@@ -88,13 +89,15 @@ public class MeasuredEnergyStats {
*/
private final long[] mAccumulatedChargeMicroCoulomb;
private final String[] mCustomBucketNames;
/**
* Creates a MeasuredEnergyStats set to support the provided power buckets.
* supportedStandardBuckets must be of size {@link #NUMBER_STANDARD_POWER_BUCKETS}.
* numCustomBuckets >= 0 is the number of (non-standard) custom power buckets on the device.
*/
public MeasuredEnergyStats(boolean[] supportedStandardBuckets, int numCustomBuckets) {
final int numTotalBuckets = NUMBER_STANDARD_POWER_BUCKETS + numCustomBuckets;
public MeasuredEnergyStats(boolean[] supportedStandardBuckets, String[] customBucketNames) {
final int numTotalBuckets = NUMBER_STANDARD_POWER_BUCKETS + customBucketNames.length;
mAccumulatedChargeMicroCoulomb = new long[numTotalBuckets];
// Initialize to all zeros where supported, otherwise POWER_DATA_UNAVAILABLE.
// All custom buckets are, by definition, supported, so their values stay at 0.
@@ -103,6 +106,7 @@ public class MeasuredEnergyStats {
mAccumulatedChargeMicroCoulomb[stdBucket] = POWER_DATA_UNAVAILABLE;
}
}
mCustomBucketNames = customBucketNames;
}
/**
@@ -119,6 +123,7 @@ public class MeasuredEnergyStats {
mAccumulatedChargeMicroCoulomb[stdBucket] = POWER_DATA_UNAVAILABLE;
}
}
mCustomBucketNames = template.getCustomBucketNames();
}
/**
@@ -135,6 +140,7 @@ public class MeasuredEnergyStats {
*/
private MeasuredEnergyStats(int numIndices) {
mAccumulatedChargeMicroCoulomb = new long[numIndices];
mCustomBucketNames = new String[0];
}
/** Construct from parcel. */
@@ -142,12 +148,14 @@ public class MeasuredEnergyStats {
final int size = in.readInt();
mAccumulatedChargeMicroCoulomb = new long[size];
in.readLongArray(mAccumulatedChargeMicroCoulomb);
mCustomBucketNames = in.readStringArray();
}
/** Write to parcel */
public void writeToParcel(Parcel out) {
out.writeInt(mAccumulatedChargeMicroCoulomb.length);
out.writeLongArray(mAccumulatedChargeMicroCoulomb);
out.writeStringArray(mCustomBucketNames);
}
/**
@@ -294,7 +302,7 @@ public class MeasuredEnergyStats {
final int numCustomBuckets = arraySize - NUMBER_STANDARD_POWER_BUCKETS;
final MeasuredEnergyStats stats = new MeasuredEnergyStats(
new boolean[NUMBER_STANDARD_POWER_BUCKETS], numCustomBuckets);
new boolean[NUMBER_STANDARD_POWER_BUCKETS], new String[numCustomBuckets]);
stats.readSummaryFromParcel(in, true);
return stats;
}
@@ -406,12 +414,12 @@ public class MeasuredEnergyStats {
/** Check if the supported power buckets are precisely those given. */
public boolean isSupportEqualTo(
@NonNull boolean[] queriedStandardBuckets, int numCustomBuckets) {
@NonNull boolean[] queriedStandardBuckets, String[] customBucketNames) {
final int numBuckets = getNumberOfIndices();
// TODO(b/178504428): Detect whether custom buckets have changed qualitatively, not just
// quantitatively, and treat as mismatch if so.
if (numBuckets != NUMBER_STANDARD_POWER_BUCKETS + numCustomBuckets) {
if (numBuckets != NUMBER_STANDARD_POWER_BUCKETS + customBucketNames.length) {
return false;
}
for (int stdBucket = 0; stdBucket < NUMBER_STANDARD_POWER_BUCKETS; stdBucket++) {
@@ -422,6 +430,10 @@ public class MeasuredEnergyStats {
return true;
}
public String[] getCustomBucketNames() {
return mCustomBucketNames;
}
/** Dump debug data. */
public void dump(PrintWriter pw) {
pw.print(" ");
@@ -443,11 +455,16 @@ public class MeasuredEnergyStats {
* If the index is a standard bucket, returns its name; otherwise returns its prefixed custom
* bucket number.
*/
private static String getBucketName(int index) {
private String getBucketName(int index) {
if (isValidStandardBucket(index)) {
return DebugUtils.valueToString(MeasuredEnergyStats.class, "POWER_BUCKET_", index);
}
return "CUSTOM_" + indexToCustomBucket(index);
final int customBucket = indexToCustomBucket(index);
StringBuilder name = new StringBuilder().append("CUSTOM_").append(customBucket);
if (mCustomBucketNames != null && !TextUtils.isEmpty(mCustomBucketNames[customBucket])) {
name.append('(').append(mCustomBucketNames[customBucket]).append(')');
}
return name.toString();
}
/** Get the number of custom power buckets on this device. */

View File

@@ -109,11 +109,11 @@ public class BatteryUsageStatsRule implements TestRule {
}
/** Call only after setting the power profile information. */
public BatteryUsageStatsRule initMeasuredEnergyStatsLocked(int numCustom) {
public BatteryUsageStatsRule initMeasuredEnergyStatsLocked() {
final boolean[] supportedStandardBuckets =
new boolean[MeasuredEnergyStats.NUMBER_STANDARD_POWER_BUCKETS];
Arrays.fill(supportedStandardBuckets, true);
mBatteryStats.initMeasuredEnergyStatsLocked(supportedStandardBuckets, numCustom);
mBatteryStats.initMeasuredEnergyStatsLocked(supportedStandardBuckets, new String[0]);
mBatteryStats.informThatAllExternalStatsAreFlushed();
return this;
}
@@ -167,15 +167,11 @@ public class BatteryUsageStatsRule implements TestRule {
}
BatteryUsageStats apply(BatteryUsageStatsQuery query, PowerCalculator... calculators) {
final long[] customMeasuredEnergiesMicroJoules =
mBatteryStats.getCustomConsumerMeasuredBatteryConsumptionUC();
final int customMeasuredEnergiesCount = customMeasuredEnergiesMicroJoules != null
? customMeasuredEnergiesMicroJoules.length
: 0;
final String[] customPowerComponentNames = mBatteryStats.getCustomPowerComponentNames();
final boolean includePowerModels = (query.getFlags()
& BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_POWER_MODELS) != 0;
BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(
customMeasuredEnergiesCount, 0, includePowerModels);
customPowerComponentNames, 0, includePowerModels);
SparseArray<? extends BatteryStats.Uid> uidStats = mBatteryStats.getUidStats();
for (int i = 0; i < uidStats.size(); i++) {
builder.getOrCreateUidBatteryConsumerBuilder(uidStats.valueAt(i));

View File

@@ -66,10 +66,11 @@ public class BatteryUsageStatsTest {
final MockBatteryStatsImpl batteryStats = new MockBatteryStatsImpl(clocks);
final BatteryStatsImpl.Uid batteryStatsUid = batteryStats.getUidStatsLocked(2000);
final BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(1, 1)
.setDischargePercentage(20)
.setDischargedPowerRange(1000, 2000)
.setStatsStartTimestamp(1000);
final BatteryUsageStats.Builder builder =
new BatteryUsageStats.Builder(new String[]{"FOO"}, 1)
.setDischargePercentage(20)
.setDischargedPowerRange(1000, 2000)
.setStatsStartTimestamp(1000);
builder.getOrCreateUidBatteryConsumerBuilder(batteryStatsUid)
.setPackageWithHighestDrain("foo")
@@ -134,6 +135,9 @@ public class BatteryUsageStatsTest {
assertThat(uidBatteryConsumer.getUsageDurationForCustomComponentMillis(
BatteryConsumer.FIRST_CUSTOM_TIME_COMPONENT_ID)).isEqualTo(800);
assertThat(uidBatteryConsumer.getConsumedPower()).isEqualTo(1200);
assertThat(uidBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1);
assertThat(uidBatteryConsumer.getCustomPowerComponentName(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo("FOO");
} else {
fail("Unexpected UID " + uidBatteryConsumer.getUid());
}
@@ -153,6 +157,9 @@ public class BatteryUsageStatsTest {
BatteryConsumer.FIRST_CUSTOM_TIME_COMPONENT_ID)).isEqualTo(10400);
assertThat(systemBatteryConsumer.getConsumedPower()).isEqualTo(20300);
assertThat(systemBatteryConsumer.getPowerConsumedByApps()).isEqualTo(20000);
assertThat(systemBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1);
assertThat(systemBatteryConsumer.getCustomPowerComponentName(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo("FOO");
} else {
fail("Unexpected drain type " + systemBatteryConsumer.getDrainType());
}

View File

@@ -44,7 +44,7 @@ public class BluetoothPowerCalculatorTest {
.setAveragePower(PowerProfile.POWER_BLUETOOTH_CONTROLLER_IDLE, 10.0)
.setAveragePower(PowerProfile.POWER_BLUETOOTH_CONTROLLER_RX, 50.0)
.setAveragePower(PowerProfile.POWER_BLUETOOTH_CONTROLLER_TX, 100.0)
.initMeasuredEnergyStatsLocked(0);
.initMeasuredEnergyStatsLocked();
@Test
public void testTimerBasedModel() {

View File

@@ -96,7 +96,7 @@ public class CpuPowerCalculatorTest {
.setKernelCpuUidUserSysTimeReader(mMockKernelCpuUidUserSysTimeReader)
.setKernelCpuUidActiveTimeReader(mMockKerneCpuUidActiveTimeReader)
.setSystemServerCpuThreadReader(mMockSystemServerCpuThreadReader)
.initMeasuredEnergyStatsLocked(supportedPowerBuckets, 0);
.initMeasuredEnergyStatsLocked(supportedPowerBuckets, new String[0]);
}
@Test

View File

@@ -42,7 +42,7 @@ public class GnssPowerCalculatorTest {
.setAveragePower(PowerProfile.POWER_GPS_ON, 360.0)
.setAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED,
new double[] {720.0, 1440.0, 1800.0})
.initMeasuredEnergyStatsLocked(0);
.initMeasuredEnergyStatsLocked();
@Test
public void testTimerBasedModel() {

View File

@@ -57,7 +57,7 @@ public class MobileRadioPowerCalculatorTest {
.setAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_RX, 1440.0)
.setAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_TX,
new double[] {720.0, 1080.0, 1440.0, 1800.0, 2160.0})
.initMeasuredEnergyStatsLocked(0);
.initMeasuredEnergyStatsLocked();
@Test
public void testCounterBasedModel() {

View File

@@ -51,7 +51,9 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl {
final boolean[] supportedStandardBuckets =
new boolean[MeasuredEnergyStats.NUMBER_STANDARD_POWER_BUCKETS];
Arrays.fill(supportedStandardBuckets, true);
mGlobalMeasuredEnergyStats = new MeasuredEnergyStats(supportedStandardBuckets, 2);
final String[] customBucketNames = {"FOO", "BAR"};
mGlobalMeasuredEnergyStats =
new MeasuredEnergyStats(supportedStandardBuckets, customBucketNames);
// A no-op handler.
mHandler = new Handler(Looper.getMainLooper()) {

View File

@@ -53,7 +53,7 @@ public class WifiPowerCalculatorTest {
.setAveragePower(PowerProfile.POWER_WIFI_SCAN, 480.0)
.setAveragePower(PowerProfile.POWER_WIFI_BATCHED_SCAN, 720.0)
.setAveragePower(PowerProfile.POWER_WIFI_ACTIVE, 1080.0)
.initMeasuredEnergyStatsLocked(0);
.initMeasuredEnergyStatsLocked();
/** Sets up a batterystats object with pre-populated network values. */
private BatteryStatsImpl setupTestNetworkNumbers() {

View File

@@ -23,6 +23,8 @@ import static com.android.internal.power.MeasuredEnergyStats.POWER_BUCKET_SCREEN
import static com.android.internal.power.MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON;
import static com.android.internal.power.MeasuredEnergyStats.POWER_BUCKET_SCREEN_OTHER;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
@@ -49,13 +51,13 @@ public class MeasuredEnergyStatsTest {
@Test
public void testConstruction() {
final boolean[] supportedStandardBuckets = new boolean[NUMBER_STANDARD_POWER_BUCKETS];
final int numCustomBuckets = 2;
final String[] customBucketNames = {"A", "B"};
supportedStandardBuckets[POWER_BUCKET_SCREEN_ON] = true;
supportedStandardBuckets[POWER_BUCKET_SCREEN_DOZE] = false;
supportedStandardBuckets[POWER_BUCKET_SCREEN_OTHER] = true;
final MeasuredEnergyStats stats =
new MeasuredEnergyStats(supportedStandardBuckets, numCustomBuckets);
new MeasuredEnergyStats(supportedStandardBuckets, customBucketNames);
for (int i = 0; i < NUMBER_STANDARD_POWER_BUCKETS; i++) {
if (supportedStandardBuckets[i]) {
@@ -66,21 +68,22 @@ public class MeasuredEnergyStatsTest {
assertEquals(POWER_DATA_UNAVAILABLE, stats.getAccumulatedStandardBucketCharge(i));
}
}
for (int i = 0; i < numCustomBuckets; i++) {
for (int i = 0; i < customBucketNames.length; i++) {
assertEquals(0L, stats.getAccumulatedCustomBucketCharge(i));
}
assertThat(stats.getCustomBucketNames()).asList().containsExactly("A", "B");
}
@Test
public void testCreateFromTemplate() {
final boolean[] supportedStandardBuckets = new boolean[NUMBER_STANDARD_POWER_BUCKETS];
final int numCustomBuckets = 2;
final String[] customBucketNames = {"A", "B"};
supportedStandardBuckets[POWER_BUCKET_SCREEN_ON] = true;
supportedStandardBuckets[POWER_BUCKET_SCREEN_DOZE] = false;
supportedStandardBuckets[POWER_BUCKET_SCREEN_OTHER] = true;
final MeasuredEnergyStats stats =
new MeasuredEnergyStats(supportedStandardBuckets, numCustomBuckets);
new MeasuredEnergyStats(supportedStandardBuckets, customBucketNames);
stats.updateStandardBucket(POWER_BUCKET_SCREEN_ON, 10);
stats.updateStandardBucket(POWER_BUCKET_SCREEN_ON, 5);
stats.updateStandardBucket(POWER_BUCKET_SCREEN_OTHER, 40);
@@ -99,7 +102,7 @@ public class MeasuredEnergyStatsTest {
newStats.getAccumulatedStandardBucketCharge(i));
}
}
for (int i = 0; i < numCustomBuckets; i++) {
for (int i = 0; i < customBucketNames.length; i++) {
assertEquals(0L, newStats.getAccumulatedCustomBucketCharge(i));
}
}
@@ -107,13 +110,13 @@ public class MeasuredEnergyStatsTest {
@Test
public void testReadWriteParcel() {
final boolean[] supportedStandardBuckets = new boolean[NUMBER_STANDARD_POWER_BUCKETS];
final int numCustomBuckets = 2;
final String[] customBucketNames = {"A", "B"};
supportedStandardBuckets[POWER_BUCKET_SCREEN_ON] = true;
supportedStandardBuckets[POWER_BUCKET_SCREEN_DOZE] = false;
supportedStandardBuckets[POWER_BUCKET_SCREEN_OTHER] = true;
final MeasuredEnergyStats stats =
new MeasuredEnergyStats(supportedStandardBuckets, numCustomBuckets);
new MeasuredEnergyStats(supportedStandardBuckets, customBucketNames);
stats.updateStandardBucket(POWER_BUCKET_SCREEN_ON, 10);
stats.updateStandardBucket(POWER_BUCKET_SCREEN_ON, 5);
stats.updateStandardBucket(POWER_BUCKET_SCREEN_OTHER, 40);
@@ -130,25 +133,25 @@ public class MeasuredEnergyStatsTest {
assertEquals(stats.getAccumulatedStandardBucketCharge(i),
newStats.getAccumulatedStandardBucketCharge(i));
}
for (int i = 0; i < numCustomBuckets; i++) {
for (int i = 0; i < customBucketNames.length; i++) {
assertEquals(stats.getAccumulatedCustomBucketCharge(i),
newStats.getAccumulatedCustomBucketCharge(i));
}
assertEquals(POWER_DATA_UNAVAILABLE,
newStats.getAccumulatedCustomBucketCharge(numCustomBuckets + 1));
newStats.getAccumulatedCustomBucketCharge(customBucketNames.length + 1));
parcel.recycle();
}
@Test
public void testCreateAndReadSummaryFromParcel() {
final boolean[] supportedStandardBuckets = new boolean[NUMBER_STANDARD_POWER_BUCKETS];
final int numCustomBuckets = 2;
final String[] customBucketNames = {"A", "B"};
supportedStandardBuckets[POWER_BUCKET_SCREEN_ON] = true;
supportedStandardBuckets[POWER_BUCKET_SCREEN_DOZE] = false;
supportedStandardBuckets[POWER_BUCKET_SCREEN_OTHER] = true;
final MeasuredEnergyStats stats =
new MeasuredEnergyStats(supportedStandardBuckets, numCustomBuckets);
new MeasuredEnergyStats(supportedStandardBuckets, customBucketNames);
stats.updateStandardBucket(POWER_BUCKET_SCREEN_ON, 10);
stats.updateStandardBucket(POWER_BUCKET_SCREEN_ON, 5);
stats.updateStandardBucket(POWER_BUCKET_SCREEN_OTHER, 40);
@@ -166,25 +169,25 @@ public class MeasuredEnergyStatsTest {
assertEquals(stats.getAccumulatedStandardBucketCharge(i),
newStats.getAccumulatedStandardBucketCharge(i));
}
for (int i = 0; i < numCustomBuckets; i++) {
for (int i = 0; i < customBucketNames.length; i++) {
assertEquals(stats.getAccumulatedCustomBucketCharge(i),
newStats.getAccumulatedCustomBucketCharge(i));
}
assertEquals(POWER_DATA_UNAVAILABLE,
newStats.getAccumulatedCustomBucketCharge(numCustomBuckets + 1));
newStats.getAccumulatedCustomBucketCharge(customBucketNames.length + 1));
parcel.recycle();
}
@Test
public void testCreateAndReadSummaryFromParcel_existingTemplate() {
final boolean[] supportedStandardBuckets = new boolean[NUMBER_STANDARD_POWER_BUCKETS];
final int numCustomBuckets = 2;
final String[] customBucketNames = {"A", "B"};
supportedStandardBuckets[POWER_BUCKET_SCREEN_ON] = true;
supportedStandardBuckets[POWER_BUCKET_SCREEN_DOZE] = false;
supportedStandardBuckets[POWER_BUCKET_SCREEN_OTHER] = true;
final MeasuredEnergyStats template =
new MeasuredEnergyStats(supportedStandardBuckets, numCustomBuckets);
new MeasuredEnergyStats(supportedStandardBuckets, customBucketNames);
template.updateStandardBucket(POWER_BUCKET_SCREEN_ON, 10);
template.updateStandardBucket(POWER_BUCKET_SCREEN_ON, 5);
template.updateStandardBucket(POWER_BUCKET_SCREEN_OTHER, 40);
@@ -205,7 +208,7 @@ public class MeasuredEnergyStatsTest {
newsupportedStandardBuckets[POWER_BUCKET_SCREEN_DOZE] = true; // switched false > true
newsupportedStandardBuckets[POWER_BUCKET_SCREEN_OTHER] = false; // switched true > false
final MeasuredEnergyStats newTemplate =
new MeasuredEnergyStats(newsupportedStandardBuckets, numCustomBuckets);
new MeasuredEnergyStats(newsupportedStandardBuckets, customBucketNames);
parcel.setDataPosition(0);
final MeasuredEnergyStats newStats =
@@ -225,23 +228,23 @@ public class MeasuredEnergyStatsTest {
newStats.getAccumulatedStandardBucketCharge(i));
}
}
for (int i = 0; i < numCustomBuckets; i++) {
for (int i = 0; i < customBucketNames.length; i++) {
assertEquals(stats.getAccumulatedCustomBucketCharge(i),
newStats.getAccumulatedCustomBucketCharge(i));
}
assertEquals(POWER_DATA_UNAVAILABLE,
newStats.getAccumulatedCustomBucketCharge(numCustomBuckets + 1));
newStats.getAccumulatedCustomBucketCharge(customBucketNames.length + 1));
parcel.recycle();
}
@Test
public void testCreateAndReadSummaryFromParcel_skipZero() {
final boolean[] supportedStandardBuckets = new boolean[NUMBER_STANDARD_POWER_BUCKETS];
final int numCustomBuckets = 2;
final String[] customBucketNames = {"A", "B"};
Arrays.fill(supportedStandardBuckets, true);
final MeasuredEnergyStats stats =
new MeasuredEnergyStats(supportedStandardBuckets, numCustomBuckets);
new MeasuredEnergyStats(supportedStandardBuckets, customBucketNames);
// Accumulate charge in one bucket and one custom bucket, the rest should be zero
stats.updateStandardBucket(POWER_BUCKET_SCREEN_ON, 200);
stats.updateCustomBucket(1, 60);
@@ -298,13 +301,13 @@ public class MeasuredEnergyStatsTest {
@Test
public void testCreateAndReadSummaryFromParcel_nullTemplate() {
final boolean[] supportedStandardBuckets = new boolean[NUMBER_STANDARD_POWER_BUCKETS];
final int numCustomBuckets = 2;
final String[] customBucketNames = {"A", "B"};
supportedStandardBuckets[POWER_BUCKET_SCREEN_ON] = true;
supportedStandardBuckets[POWER_BUCKET_SCREEN_DOZE] = false;
supportedStandardBuckets[POWER_BUCKET_SCREEN_OTHER] = true;
final MeasuredEnergyStats stats =
new MeasuredEnergyStats(supportedStandardBuckets, numCustomBuckets);
new MeasuredEnergyStats(supportedStandardBuckets, customBucketNames);
stats.updateStandardBucket(POWER_BUCKET_SCREEN_ON, 10);
stats.updateStandardBucket(POWER_BUCKET_SCREEN_ON, 5);
stats.updateStandardBucket(POWER_BUCKET_SCREEN_OTHER, 40);
@@ -324,13 +327,13 @@ public class MeasuredEnergyStatsTest {
@Test
public void testCreateAndReadSummaryFromParcel_boring() {
final boolean[] supportedStandardBuckets = new boolean[NUMBER_STANDARD_POWER_BUCKETS];
final int numCustomBuckets = 2;
final String[] customBucketNames = {"A", "B"};
supportedStandardBuckets[POWER_BUCKET_SCREEN_ON] = true;
supportedStandardBuckets[POWER_BUCKET_SCREEN_DOZE] = false;
supportedStandardBuckets[POWER_BUCKET_SCREEN_OTHER] = true;
final MeasuredEnergyStats template =
new MeasuredEnergyStats(supportedStandardBuckets, numCustomBuckets);
new MeasuredEnergyStats(supportedStandardBuckets, customBucketNames);
template.updateStandardBucket(POWER_BUCKET_SCREEN_ON, 10);
template.updateStandardBucket(POWER_BUCKET_SCREEN_ON, 5);
template.updateStandardBucket(POWER_BUCKET_SCREEN_OTHER, 40);
@@ -348,7 +351,7 @@ public class MeasuredEnergyStatsTest {
newSupportedStandardBuckets[POWER_BUCKET_SCREEN_DOZE] = true; // switched false > true
newSupportedStandardBuckets[POWER_BUCKET_SCREEN_OTHER] = false; // switched true > false
final MeasuredEnergyStats newTemplate =
new MeasuredEnergyStats(newSupportedStandardBuckets, numCustomBuckets);
new MeasuredEnergyStats(newSupportedStandardBuckets, customBucketNames);
parcel.setDataPosition(0);
final MeasuredEnergyStats newStats =
@@ -362,13 +365,13 @@ public class MeasuredEnergyStatsTest {
@Test
public void testUpdateBucket() {
final boolean[] supportedStandardBuckets = new boolean[NUMBER_STANDARD_POWER_BUCKETS];
final int numCustomBuckets = 2;
final String[] customBucketNames = {"A", "B"};
supportedStandardBuckets[POWER_BUCKET_SCREEN_ON] = true;
supportedStandardBuckets[POWER_BUCKET_SCREEN_DOZE] = false;
supportedStandardBuckets[POWER_BUCKET_SCREEN_OTHER] = true;
final MeasuredEnergyStats stats =
new MeasuredEnergyStats(supportedStandardBuckets, numCustomBuckets);
new MeasuredEnergyStats(supportedStandardBuckets, customBucketNames);
stats.updateStandardBucket(POWER_BUCKET_SCREEN_ON, 10);
stats.updateStandardBucket(POWER_BUCKET_SCREEN_DOZE, 30);
stats.updateStandardBucket(POWER_BUCKET_SCREEN_OTHER, 40);
@@ -389,7 +392,8 @@ public class MeasuredEnergyStatsTest {
@Test
public void testIsValidCustomBucket() {
final MeasuredEnergyStats stats =
new MeasuredEnergyStats(new boolean[NUMBER_STANDARD_POWER_BUCKETS], 3);
new MeasuredEnergyStats(new boolean[NUMBER_STANDARD_POWER_BUCKETS],
new String[]{"A", "B", "C"});
assertFalse(stats.isValidCustomBucket(-1));
assertTrue(stats.isValidCustomBucket(0));
assertTrue(stats.isValidCustomBucket(1));
@@ -398,7 +402,7 @@ public class MeasuredEnergyStatsTest {
assertFalse(stats.isValidCustomBucket(4));
final MeasuredEnergyStats boringStats =
new MeasuredEnergyStats(new boolean[NUMBER_STANDARD_POWER_BUCKETS], 0);
new MeasuredEnergyStats(new boolean[NUMBER_STANDARD_POWER_BUCKETS], new String[0]);
assertFalse(boringStats.isValidCustomBucket(-1));
assertFalse(boringStats.isValidCustomBucket(0));
assertFalse(boringStats.isValidCustomBucket(1));
@@ -407,8 +411,8 @@ public class MeasuredEnergyStatsTest {
@Test
public void testGetAccumulatedCustomBucketCharges() {
final MeasuredEnergyStats stats =
new MeasuredEnergyStats(new boolean[NUMBER_STANDARD_POWER_BUCKETS], 3);
new MeasuredEnergyStats(new boolean[NUMBER_STANDARD_POWER_BUCKETS],
new String[]{"A", "B", "C"});
stats.updateCustomBucket(0, 50);
stats.updateCustomBucket(1, 60);
stats.updateCustomBucket(2, 13);
@@ -425,7 +429,7 @@ public class MeasuredEnergyStatsTest {
@Test
public void testGetAccumulatedCustomBucketCharges_empty() {
final MeasuredEnergyStats stats =
new MeasuredEnergyStats(new boolean[NUMBER_STANDARD_POWER_BUCKETS], 0);
new MeasuredEnergyStats(new boolean[NUMBER_STANDARD_POWER_BUCKETS], new String[0]);
final long[] output = stats.getAccumulatedCustomBucketCharges();
assertEquals(0, output.length);
@@ -433,22 +437,23 @@ public class MeasuredEnergyStatsTest {
@Test
public void testGetNumberCustomChargeBuckets() {
assertEquals(0, new MeasuredEnergyStats(new boolean[NUMBER_STANDARD_POWER_BUCKETS], 0)
.getNumberCustomPowerBuckets());
assertEquals(3, new MeasuredEnergyStats(new boolean[NUMBER_STANDARD_POWER_BUCKETS], 3)
.getNumberCustomPowerBuckets());
assertEquals(0,
new MeasuredEnergyStats(new boolean[NUMBER_STANDARD_POWER_BUCKETS], new String[0])
.getNumberCustomPowerBuckets());
assertEquals(3, new MeasuredEnergyStats(new boolean[NUMBER_STANDARD_POWER_BUCKETS],
new String[]{"A", "B", "C"}).getNumberCustomPowerBuckets());
}
@Test
public void testReset() {
final boolean[] supportedStandardBuckets = new boolean[NUMBER_STANDARD_POWER_BUCKETS];
final int numCustomBuckets = 2;
final String[] customBucketNames = {"A", "B"};
supportedStandardBuckets[POWER_BUCKET_SCREEN_ON] = true;
supportedStandardBuckets[POWER_BUCKET_SCREEN_DOZE] = false;
supportedStandardBuckets[POWER_BUCKET_SCREEN_OTHER] = true;
final MeasuredEnergyStats stats =
new MeasuredEnergyStats(supportedStandardBuckets, numCustomBuckets);
new MeasuredEnergyStats(supportedStandardBuckets, customBucketNames);
stats.updateStandardBucket(POWER_BUCKET_SCREEN_ON, 10);
stats.updateStandardBucket(POWER_BUCKET_SCREEN_ON, 5);
stats.updateStandardBucket(POWER_BUCKET_SCREEN_OTHER, 40);
@@ -466,7 +471,7 @@ public class MeasuredEnergyStatsTest {
assertEquals(POWER_DATA_UNAVAILABLE, stats.getAccumulatedStandardBucketCharge(i));
}
}
for (int i = 0; i < numCustomBuckets; i++) {
for (int i = 0; i < customBucketNames.length; i++) {
assertEquals(0, stats.getAccumulatedCustomBucketCharge(i));
}

View File

@@ -205,7 +205,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
mPowerStatsInternal = psi;
boolean[] supportedStdBuckets = null;
int numCustomBuckets = 0;
String[] customBucketNames = null;
if (mPowerStatsInternal != null) {
final SparseArray<EnergyConsumer> idToConsumer
= populateEnergyConsumerSubsystemMapsLocked();
@@ -227,12 +227,12 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
+ e.getCause());
// Continue running, later attempts to query may be successful.
}
numCustomBuckets = mMeasuredEnergySnapshot.getNumOtherOrdinals();
customBucketNames = mMeasuredEnergySnapshot.getOtherOrdinalNames();
supportedStdBuckets = getSupportedEnergyBuckets(idToConsumer);
}
}
synchronized (mStats) {
mStats.initMeasuredEnergyStatsLocked(supportedStdBuckets, numCustomBuckets);
mStats.initMeasuredEnergyStatsLocked(supportedStdBuckets, customBucketNames);
}
}
}

View File

@@ -99,14 +99,6 @@ public class MeasuredEnergySnapshot {
mAttributionSnapshots = new SparseArray<>(mNumOtherOrdinals);
}
/**
* Returns the number of ordinals for {@link EnergyConsumerType#OTHER}, i.e. the number of
* custom energy buckets supported by the device.
*/
public int getNumOtherOrdinals() {
return mNumOtherOrdinals;
}
/** Class for returning the relevant data calculated from the measured energy delta */
static class MeasuredEnergyDeltaData {
/** The chargeUC for {@link EnergyConsumerType#BLUETOOTH}. */
@@ -147,7 +139,7 @@ public class MeasuredEnergySnapshot {
* Fields with no interesting data (consumers not present in ecrs or with no energy
* difference) will generally be left as their default values.
* otherTotalChargeUC and otherUidChargesUC are always either both null or both of
* length {@link #getNumOtherOrdinals()}.
* length {@link #getOtherOrdinalNames().length}.
* Returns null, if ecrs is null or empty.
*/
public @Nullable MeasuredEnergyDeltaData updateAndGetDelta(EnergyConsumerResult[] ecrs,
@@ -237,8 +229,8 @@ public class MeasuredEnergySnapshot {
case EnergyConsumerType.OTHER:
if (output.otherTotalChargeUC == null) {
output.otherTotalChargeUC = new long[getNumOtherOrdinals()];
output.otherUidChargesUC = new SparseLongArray[getNumOtherOrdinals()];
output.otherTotalChargeUC = new long[mNumOtherOrdinals];
output.otherUidChargesUC = new SparseLongArray[mNumOtherOrdinals];
}
output.otherTotalChargeUC[ordinal] = deltaChargeUC;
output.otherUidChargesUC[ordinal] = otherUidCharges;
@@ -342,6 +334,23 @@ public class MeasuredEnergySnapshot {
pw.println();
}
/**
* Returns the names of ordinals for {@link EnergyConsumerType#OTHER}, i.e. the names of
* custom energy buckets supported by the device.
*/
public String[] getOtherOrdinalNames() {
final String[] names = new String[mNumOtherOrdinals];
int consumerIndex = 0;
final int size = mEnergyConsumers.size();
for (int idx = 0; idx < size; idx++) {
final EnergyConsumer consumer = mEnergyConsumers.valueAt(idx);
if (consumer.type == (int) EnergyConsumerType.OTHER) {
names[consumerIndex++] = consumer.name;
}
}
return names;
}
/** Determines the number of ordinals for a given {@link EnergyConsumerType}. */
private static int calculateNumOrdinals(@EnergyConsumerType int type,
SparseArray<EnergyConsumer> idToConsumer) {
@@ -361,5 +370,4 @@ public class MeasuredEnergySnapshot {
// since the last snapshot. Round off to the nearest whole long.
return (deltaEnergyUJ * MILLIVOLTS_PER_VOLT + (avgVoltageMV / 2)) / avgVoltageMV;
}
}

View File

@@ -18,6 +18,8 @@ package com.android.server.am;
import static com.android.server.am.MeasuredEnergySnapshot.UNAVAILABLE;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -224,15 +226,15 @@ public final class MeasuredEnergySnapshotTest {
}
@Test
public void testGetNumOtherOrdinals() {
public void testGetOtherOrdinalNames() {
final MeasuredEnergySnapshot snapshot = new MeasuredEnergySnapshot(ALL_ID_CONSUMER_MAP);
assertEquals(3, snapshot.getNumOtherOrdinals());
assertThat(snapshot.getOtherOrdinalNames()).asList().containsExactly("GPU", "HPU", "IPU");
}
@Test
public void testGetNumOtherOrdinals_none() {
public void testGetOtherOrdinalNames_none() {
final MeasuredEnergySnapshot snapshot = new MeasuredEnergySnapshot(SOME_ID_CONSUMER_MAP);
assertEquals(0, snapshot.getNumOtherOrdinals());
assertEquals(0, snapshot.getOtherOrdinalNames().length);
}
private static EnergyConsumer createEnergyConsumer(int id, int ord, byte type, String name) {