Merge "Add BatteryConsumer.getCustomPowerComponentName() and getCustomPowerComponentCount()" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
07bc3d6d95
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -96,7 +96,7 @@ public class CpuPowerCalculatorTest {
|
||||
.setKernelCpuUidUserSysTimeReader(mMockKernelCpuUidUserSysTimeReader)
|
||||
.setKernelCpuUidActiveTimeReader(mMockKerneCpuUidActiveTimeReader)
|
||||
.setSystemServerCpuThreadReader(mMockSystemServerCpuThreadReader)
|
||||
.initMeasuredEnergyStatsLocked(supportedPowerBuckets, 0);
|
||||
.initMeasuredEnergyStatsLocked(supportedPowerBuckets, new String[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user