Merge "Convert BatteryStats.dumpLocked from BatteryStatsHelper to BatteryUsageStats" into sc-dev

This commit is contained in:
Dmitri Plotnikov
2021-05-11 01:24:56 +00:00
committed by Android (Google) Code Review
10 changed files with 348 additions and 148 deletions

View File

@@ -18,6 +18,8 @@ package android.os;
import android.annotation.NonNull;
import java.io.PrintWriter;
/**
* Contains power consumption data across the entire device.
*
@@ -37,6 +39,11 @@ public final class AggregateBatteryConsumer extends BatteryConsumer implements P
mConsumedPowerMah = source.readDouble();
}
@Override
public void dump(PrintWriter pw, boolean skipEmptyComponents) {
mPowerComponents.dump(pw, skipEmptyComponents);
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
super.writeToParcel(dest, flags);

View File

@@ -19,6 +19,7 @@ package android.os;
import android.annotation.IntDef;
import android.annotation.NonNull;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -27,7 +28,7 @@ import java.lang.annotation.RetentionPolicy;
*
* @hide
*/
public class BatteryConsumer {
public abstract class BatteryConsumer {
/**
* Power usage component, describing the particular part of the system
@@ -85,12 +86,37 @@ public class BatteryConsumer {
public static final int FIRST_CUSTOM_POWER_COMPONENT_ID = 1000;
public static final int LAST_CUSTOM_POWER_COMPONENT_ID = 9999;
private static final String[] sPowerComponentNames = new String[POWER_COMPONENT_COUNT];
static {
// Assign individually to avoid future mismatch
sPowerComponentNames[POWER_COMPONENT_SCREEN] = "screen";
sPowerComponentNames[POWER_COMPONENT_CPU] = "cpu";
sPowerComponentNames[POWER_COMPONENT_BLUETOOTH] = "bluetooth";
sPowerComponentNames[POWER_COMPONENT_CAMERA] = "camera";
sPowerComponentNames[POWER_COMPONENT_AUDIO] = "audio";
sPowerComponentNames[POWER_COMPONENT_VIDEO] = "video";
sPowerComponentNames[POWER_COMPONENT_FLASHLIGHT] = "flashlight";
sPowerComponentNames[POWER_COMPONENT_SYSTEM_SERVICES] = "system_services";
sPowerComponentNames[POWER_COMPONENT_MOBILE_RADIO] = "mobile_radio";
sPowerComponentNames[POWER_COMPONENT_SENSORS] = "sensors";
sPowerComponentNames[POWER_COMPONENT_GNSS] = "gnss";
sPowerComponentNames[POWER_COMPONENT_WIFI] = "wifi";
sPowerComponentNames[POWER_COMPONENT_WAKELOCK] = "wakelock";
sPowerComponentNames[POWER_COMPONENT_MEMORY] = "memory";
sPowerComponentNames[POWER_COMPONENT_PHONE] = "phone";
sPowerComponentNames[POWER_COMPONENT_AMBIENT_DISPLAY] = "ambient_display";
sPowerComponentNames[POWER_COMPONENT_IDLE] = "idle";
sPowerComponentNames[POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS] = "reattributed";
}
/**
* Identifiers of models used for power estimation.
*
* @hide
*/
@IntDef(prefix = {"POWER_MODEL_"}, value = {
POWER_MODEL_UNDEFINED,
POWER_MODEL_POWER_PROFILE,
POWER_MODEL_MEASURED_ENERGY,
})
@@ -98,16 +124,21 @@ public class BatteryConsumer {
public @interface PowerModel {
}
/**
* Unspecified power model.
*/
public static final int POWER_MODEL_UNDEFINED = 0;
/**
* Power model that is based on average consumption rates that hardware components
* consume in various states.
*/
public static final int POWER_MODEL_POWER_PROFILE = 0;
public static final int POWER_MODEL_POWER_PROFILE = 1;
/**
* Power model that is based on energy consumption measured by on-device power monitors.
*/
public static final int POWER_MODEL_MEASURED_ENERGY = 1;
public static final int POWER_MODEL_MEASURED_ENERGY = 2;
protected final PowerComponents mPowerComponents;
@@ -197,6 +228,41 @@ public class BatteryConsumer {
mPowerComponents.writeToParcel(dest, flags);
}
/**
* Returns the name of the specified component. Intended for logging and debugging.
*/
public static String powerComponentIdToString(@BatteryConsumer.PowerComponent int componentId) {
return sPowerComponentNames[componentId];
}
/**
* Returns the name of the specified power model. Intended for logging and debugging.
*/
public static String powerModelToString(@BatteryConsumer.PowerModel int powerModel) {
switch (powerModel) {
case BatteryConsumer.POWER_MODEL_MEASURED_ENERGY:
return "measured energy";
case BatteryConsumer.POWER_MODEL_POWER_PROFILE:
return "power profile";
default:
return "";
}
}
/**
* Prints the stats in a human-readable format.
*/
public void dump(PrintWriter pw) {
dump(pw, true);
}
/**
* Prints the stats in a human-readable format.
*
* @param skipEmptyComponents if true, omit any power components with a zero amount.
*/
public abstract void dump(PrintWriter pw, boolean skipEmptyComponents);
protected abstract static class BaseBuilder<T extends BaseBuilder<?>> {
final PowerComponents.Builder mPowerComponentsBuilder;

View File

@@ -51,6 +51,7 @@ import android.view.Display;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper;
import com.android.internal.os.BatteryUsageStatsProvider;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -5299,154 +5300,19 @@ public abstract class BatteryStats implements Parcelable {
pw.println(getDischargeAmountScreenDozeSinceCharge());
pw.println();
final BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, this);
final BatteryUsageStats stats = provider.getBatteryUsageStats(
new BatteryUsageStatsQuery.Builder()
.setMaxStatsAgeMs(0)
.includePowerModels()
.build());
stats.dump(pw, prefix);
final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
helper.create(this);
helper.refreshStats(which, UserHandle.USER_ALL);
List<BatterySipper> sippers = helper.getUsageList();
if (sippers != null && sippers.size() > 0) {
pw.print(prefix); pw.println(" Estimated power use (mAh):");
pw.print(prefix); pw.print(" Capacity: ");
printmAh(pw, helper.getPowerProfile().getBatteryCapacity());
pw.print(", Computed drain: "); printmAh(pw, helper.getComputedPower());
pw.print(", actual drain: "); printmAh(pw, helper.getMinDrainedPower());
if (helper.getMinDrainedPower() != helper.getMaxDrainedPower()) {
pw.print("-"); printmAh(pw, helper.getMaxDrainedPower());
}
pw.println();
for (int i=0; i<sippers.size(); i++) {
final BatterySipper bs = sippers.get(i);
pw.print(prefix);
switch (bs.drainType) {
case AMBIENT_DISPLAY:
pw.print(" Ambient display: ");
break;
case IDLE:
pw.print(" Idle: ");
break;
case CELL:
pw.print(" Cell standby: ");
break;
case PHONE:
pw.print(" Phone calls: ");
break;
case WIFI:
pw.print(" Wifi: ");
break;
case BLUETOOTH:
pw.print(" Bluetooth: ");
break;
case SCREEN:
pw.print(" Screen: ");
break;
case FLASHLIGHT:
pw.print(" Flashlight: ");
break;
case APP:
pw.print(" Uid ");
UserHandle.formatUid(pw, bs.uidObj.getUid());
pw.print(": ");
break;
case USER:
pw.print(" User "); pw.print(bs.userId);
pw.print(": ");
break;
case UNACCOUNTED:
pw.print(" Unaccounted: ");
break;
case OVERCOUNTED:
pw.print(" Over-counted: ");
break;
case CAMERA:
pw.print(" Camera: ");
break;
default:
pw.print(" ???: ");
break;
}
printmAh(pw, bs.totalPowerMah);
if (bs.usagePowerMah != bs.totalPowerMah) {
// If the usage (generic power) isn't the whole amount, we list out
// what components are involved in the calculation.
pw.print(" (");
if (bs.usagePowerMah != 0) {
pw.print(" usage=");
printmAh(pw, bs.usagePowerMah);
}
if (bs.cpuPowerMah != 0) {
pw.print(" cpu=");
printmAh(pw, bs.cpuPowerMah);
}
if (bs.wakeLockPowerMah != 0) {
pw.print(" wake=");
printmAh(pw, bs.wakeLockPowerMah);
}
if (bs.mobileRadioPowerMah != 0) {
pw.print(" radio=");
printmAh(pw, bs.mobileRadioPowerMah);
}
if (bs.wifiPowerMah != 0) {
pw.print(" wifi=");
printmAh(pw, bs.wifiPowerMah);
}
if (bs.bluetoothPowerMah != 0) {
pw.print(" bt=");
printmAh(pw, bs.bluetoothPowerMah);
}
if (bs.gpsPowerMah != 0) {
pw.print(" gps=");
printmAh(pw, bs.gpsPowerMah);
}
if (bs.sensorPowerMah != 0) {
pw.print(" sensor=");
printmAh(pw, bs.sensorPowerMah);
}
if (bs.cameraPowerMah != 0) {
pw.print(" camera=");
printmAh(pw, bs.cameraPowerMah);
}
if (bs.flashlightPowerMah != 0) {
pw.print(" flash=");
printmAh(pw, bs.flashlightPowerMah);
}
if (bs.customMeasuredPowerMah != null) {
for (int idx = 0; idx < bs.customMeasuredPowerMah.length; idx++) {
final double customPowerMah = bs.customMeasuredPowerMah[idx];
if (customPowerMah != 0) {
pw.print(" custom[" + idx + "]=");
printmAh(pw, customPowerMah);
}
}
}
pw.print(" )");
}
// If there is additional smearing information, include it.
if (bs.totalSmearedPowerMah != bs.totalPowerMah) {
pw.print(" Including smearing: ");
printmAh(pw, bs.totalSmearedPowerMah);
pw.print(" (");
if (bs.screenPowerMah != 0) {
pw.print(" screen=");
printmAh(pw, bs.screenPowerMah);
}
if (bs.proportionalSmearMah != 0) {
pw.print(" proportional=");
printmAh(pw, bs.proportionalSmearMah);
}
pw.print(" )");
}
if (bs.shouldHide) {
pw.print(" Excluded from smearing");
}
pw.println();
}
pw.println();
}
sippers = helper.getMobilemsppList();
final List<BatterySipper> sippers = helper.getMobilemsppList();
if (sippers != null && sippers.size() > 0) {
pw.print(prefix); pw.println(" Per-app mobile ms per packet:");
long totalTime = 0;

View File

@@ -23,10 +23,13 @@ import android.util.SparseArray;
import com.android.internal.os.BatteryStatsHistory;
import com.android.internal.os.BatteryStatsHistoryIterator;
import com.android.internal.os.PowerCalculator;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
/**
@@ -73,6 +76,7 @@ public final class BatteryUsageStats implements Parcelable {
private final int mDischargePercentage;
private final long mStatsStartTimestampMs;
private final double mBatteryCapacityMah;
private final double mDischargedPowerLowerBound;
private final double mDischargedPowerUpperBound;
private final long mBatteryTimeRemainingMs;
@@ -86,6 +90,7 @@ public final class BatteryUsageStats implements Parcelable {
private BatteryUsageStats(@NonNull Builder builder) {
mStatsStartTimestampMs = builder.mStatsStartTimestampMs;
mBatteryCapacityMah = builder.mBatteryCapacityMah;
mDischargePercentage = builder.mDischargePercentage;
mDischargedPowerLowerBound = builder.mDischargedPowerLowerBoundMah;
mDischargedPowerUpperBound = builder.mDischargedPowerUpperBoundMah;
@@ -144,6 +149,13 @@ public final class BatteryUsageStats implements Parcelable {
.getConsumedPower();
}
/**
* Returns battery capacity in milli-amp-hours.
*/
public double getBatteryCapacity() {
return mBatteryCapacityMah;
}
/**
* Portion of battery charge drained since BatteryStats reset (e.g. due to being fully
* charged), as percentage of the full charge in the range [0:100]
@@ -217,6 +229,7 @@ public final class BatteryUsageStats implements Parcelable {
private BatteryUsageStats(@NonNull Parcel source) {
mStatsStartTimestampMs = source.readLong();
mBatteryCapacityMah = source.readDouble();
mDischargePercentage = source.readInt();
mDischargedPowerLowerBound = source.readDouble();
mDischargedPowerUpperBound = source.readDouble();
@@ -274,6 +287,7 @@ public final class BatteryUsageStats implements Parcelable {
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeLong(mStatsStartTimestampMs);
dest.writeDouble(mBatteryCapacityMah);
dest.writeInt(mDischargePercentage);
dest.writeDouble(mDischargedPowerLowerBound);
dest.writeDouble(mDischargedPowerUpperBound);
@@ -321,6 +335,104 @@ public final class BatteryUsageStats implements Parcelable {
}
};
/**
* Prints the stats in a human-readable format.
*/
public void dump(PrintWriter pw, String prefix) {
pw.print(prefix);
pw.println(" Estimated power use (mAh):");
pw.print(prefix);
pw.print(" Capacity: ");
PowerCalculator.printPowerMah(pw, getBatteryCapacity());
pw.print(", Computed drain: ");
PowerCalculator.printPowerMah(pw, getConsumedPower());
final Range<Double> dischargedPowerRange = getDischargedPowerRange();
pw.print(", actual drain: ");
PowerCalculator.printPowerMah(pw, dischargedPowerRange.getLower());
if (!dischargedPowerRange.getLower().equals(dischargedPowerRange.getUpper())) {
pw.print("-");
PowerCalculator.printPowerMah(pw, dischargedPowerRange.getUpper());
}
pw.println();
pw.println(" Global");
final BatteryConsumer deviceConsumer = getAggregateBatteryConsumer(
AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
final BatteryConsumer appsConsumer = getAggregateBatteryConsumer(
AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS);
for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT;
componentId++) {
final double devicePowerMah = deviceConsumer.getConsumedPower(componentId);
final double appsPowerMah = appsConsumer.getConsumedPower(componentId);
if (devicePowerMah == 0 && appsPowerMah == 0) {
continue;
}
final String componentName = BatteryConsumer.powerComponentIdToString(componentId);
printPowerComponent(pw, prefix, componentName, devicePowerMah, appsPowerMah,
deviceConsumer.getPowerModel(componentId),
deviceConsumer.getUsageDurationMillis(componentId));
}
for (int componentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID;
componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID
+ mCustomPowerComponentNames.length;
componentId++) {
final double devicePowerMah =
deviceConsumer.getConsumedPowerForCustomComponent(componentId);
final double appsPowerMah =
appsConsumer.getConsumedPowerForCustomComponent(componentId);
if (devicePowerMah == 0 && appsPowerMah == 0) {
continue;
}
printPowerComponent(pw, prefix, deviceConsumer.getCustomPowerComponentName(componentId),
devicePowerMah, appsPowerMah,
BatteryConsumer.POWER_MODEL_UNDEFINED,
deviceConsumer.getUsageDurationForCustomComponentMillis(componentId));
}
dumpSortedBatteryConsumers(pw, prefix, getUidBatteryConsumers());
dumpSortedBatteryConsumers(pw, prefix, getUserBatteryConsumers());
}
private void printPowerComponent(PrintWriter pw, String prefix, String componentName,
double devicePowerMah, double appsPowerMah, int powerModel, long durationMs) {
StringBuilder sb = new StringBuilder();
sb.append(prefix).append(" ").append(componentName).append(": ")
.append(PowerCalculator.formatCharge(devicePowerMah));
if (powerModel != BatteryConsumer.POWER_MODEL_UNDEFINED
&& powerModel != BatteryConsumer.POWER_MODEL_POWER_PROFILE) {
sb.append(" [");
sb.append(BatteryConsumer.powerModelToString(powerModel));
sb.append("]");
}
sb.append(" apps: ").append(PowerCalculator.formatCharge(appsPowerMah));
if (durationMs != 0) {
sb.append(" duration: ");
BatteryStats.formatTimeMs(sb, durationMs);
}
pw.println(sb.toString());
}
private void dumpSortedBatteryConsumers(PrintWriter pw, String prefix,
List<? extends BatteryConsumer> batteryConsumers) {
batteryConsumers.sort(
Comparator.<BatteryConsumer>comparingDouble(BatteryConsumer::getConsumedPower)
.reversed());
for (BatteryConsumer consumer : batteryConsumers) {
if (consumer.getConsumedPower() == 0) {
continue;
}
pw.print(prefix);
pw.print(" ");
consumer.dump(pw);
pw.println();
}
}
/**
* Builder for BatteryUsageStats.
*/
@@ -329,6 +441,7 @@ public final class BatteryUsageStats implements Parcelable {
private final String[] mCustomPowerComponentNames;
private final boolean mIncludePowerModels;
private long mStatsStartTimestampMs;
private double mBatteryCapacityMah;
private int mDischargePercentage;
private double mDischargedPowerLowerBoundMah;
private double mDischargedPowerUpperBoundMah;
@@ -364,6 +477,14 @@ public final class BatteryUsageStats implements Parcelable {
return new BatteryUsageStats(this);
}
/**
* Sets the battery capacity in milli-amp-hours.
*/
public Builder setBatteryCapacity(double batteryCapacityMah) {
mBatteryCapacityMah = batteryCapacityMah;
return this;
}
/**
* Sets the timestamp of the latest battery stats reset, in milliseconds.
*/

View File

@@ -17,6 +17,10 @@ package android.os;
import android.annotation.NonNull;
import com.android.internal.os.PowerCalculator;
import java.io.PrintWriter;
/**
* Contains details of battery attribution data broken down to individual power drain types
* such as CPU, RAM, GPU etc.
@@ -202,6 +206,37 @@ class PowerComponents {
return max;
}
public void dump(PrintWriter pw, boolean skipEmptyComponents) {
String separator = "";
for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT;
componentId++) {
final double componentPower = getConsumedPower(componentId);
if (skipEmptyComponents && componentPower == 0) {
continue;
}
pw.print(separator); separator = " ";
pw.print(BatteryConsumer.powerComponentIdToString(componentId));
pw.print("=");
PowerCalculator.printPowerMah(pw, componentPower);
}
final int customComponentCount = getCustomPowerComponentCount();
for (int customComponentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID;
customComponentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID
+ customComponentCount;
customComponentId++) {
final double customComponentPower =
getConsumedPowerForCustomComponent(customComponentId);
if (skipEmptyComponents && customComponentPower == 0) {
continue;
}
pw.print(separator); separator = " ";
pw.print(getCustomPowerComponentName(customComponentId));
pw.print("=");
PowerCalculator.printPowerMah(pw, customComponentPower);
}
}
/**
* Builder for PowerComponents.
*/

View File

@@ -20,6 +20,9 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import com.android.internal.os.PowerCalculator;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -112,6 +115,18 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
dest.writeLong(mTimeInBackgroundMs);
}
@Override
public void dump(PrintWriter pw, boolean skipEmptyComponents) {
final double consumedPower = getConsumedPower();
pw.print("UID ");
UserHandle.formatUid(pw, getUid());
pw.print(": ");
PowerCalculator.printPowerMah(pw, consumedPower);
pw.print(" ( ");
mPowerComponents.dump(pw, skipEmptyComponents /* skipTotalPowerComponent */);
pw.print(" ) ");
}
@NonNull
public static final Creator<UidBatteryConsumer> CREATOR = new Creator<UidBatteryConsumer>() {
public UidBatteryConsumer createFromParcel(@NonNull Parcel source) {

View File

@@ -18,6 +18,9 @@ package android.os;
import android.annotation.NonNull;
import com.android.internal.os.PowerCalculator;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -52,6 +55,18 @@ public class UserBatteryConsumer extends BatteryConsumer implements Parcelable {
dest.writeInt(mUserId);
}
@Override
public void dump(PrintWriter pw, boolean skipEmptyComponents) {
final double consumedPower = getConsumedPower();
pw.print("User ");
pw.print(mUserId);
pw.print(": ");
PowerCalculator.printPowerMah(pw, consumedPower);
pw.print(" ( ");
mPowerComponents.dump(pw, skipEmptyComponents /* skipTotalPowerComponent */);
pw.print(" ) ");
}
public static final Creator<UserBatteryConsumer> CREATOR =
new Creator<UserBatteryConsumer>() {
@Override

View File

@@ -42,6 +42,8 @@ public class BatteryChargeCalculator extends PowerCalculator {
batteryCapacityMah = batteryStats.getEstimatedBatteryCapacity();
}
}
builder.setBatteryCapacity(batteryCapacityMah);
final double dischargedPowerLowerBoundMah =
batteryStats.getLowDischargeAmountSinceCharge() * batteryCapacityMah / 100.0;
final double dischargedPowerUpperBoundMah =

View File

@@ -24,6 +24,7 @@ import android.os.UidBatteryConsumer;
import android.os.UserHandle;
import android.util.SparseArray;
import java.io.PrintWriter;
import java.util.List;
import java.util.Locale;
@@ -157,6 +158,12 @@ public abstract class PowerCalculator {
}
}
/**
* Prints formatted amount of power in milli-amp-hours.
*/
public static void printPowerMah(PrintWriter pw, double powerMah) {
pw.print(formatCharge(powerMah));
}
/**
* Converts charge in mAh to string.

View File

@@ -24,6 +24,7 @@ import android.os.BatteryConsumer;
import android.os.BatteryUsageStats;
import android.os.Parcel;
import android.os.UidBatteryConsumer;
import android.os.UserBatteryConsumer;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -31,7 +32,11 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -60,13 +65,42 @@ public class BatteryUsageStatsTest {
validateBatteryUsageStats(inBatteryUsageStats);
}
@Test
public void testDump() {
final BatteryUsageStats stats = buildBatteryUsageStats();
final StringWriter out = new StringWriter();
try (PrintWriter pw = new PrintWriter(out)) {
stats.dump(pw, " ");
}
final String dump = out.toString();
assertThat(dump).contains("Capacity: 4000");
assertThat(dump).contains("Computed drain: 30000");
assertThat(dump).contains("actual drain: 1000-2000");
assertThat(dump).contains("cpu: 20100 apps: 10100 duration: 20s 300ms");
assertThat(dump).contains("FOO: 20200 apps: 10200 duration: 20s 400ms");
assertThat(dump).contains("UID 2000: 1200 ( screen=300 cpu=400 FOO=500 )");
assertThat(dump).contains("User 42: 30.0 ( cpu=10.0 FOO=20.0 )");
}
@Test
public void testPowerComponentNames_existAndUnique() {
Set<String> allNames = new HashSet<>();
for (int i = 0; i < BatteryConsumer.POWER_COMPONENT_COUNT; i++) {
assertThat(BatteryConsumer.powerComponentIdToString(i)).isNotNull();
allNames.add(BatteryConsumer.powerComponentIdToString(i));
}
assertThat(allNames).hasSize(BatteryConsumer.POWER_COMPONENT_COUNT);
}
private BatteryUsageStats buildBatteryUsageStats() {
final MockClocks clocks = new MockClocks();
final MockBatteryStatsImpl batteryStats = new MockBatteryStatsImpl(clocks);
final BatteryStatsImpl.Uid batteryStatsUid = batteryStats.getUidStatsLocked(2000);
final BatteryUsageStats.Builder builder =
new BatteryUsageStats.Builder(new String[]{"FOO"})
new BatteryUsageStats.Builder(new String[]{"FOO"}, true)
.setBatteryCapacity(4000)
.setDischargePercentage(20)
.setDischargedPowerRange(1000, 2000)
.setStatsStartTimestamp(1000);
@@ -108,11 +142,22 @@ public class BatteryUsageStatsTest {
.setUsageDurationForCustomComponentMillis(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20400);
builder.getOrCreateUserBatteryConsumerBuilder(42)
.setConsumedPower(
BatteryConsumer.POWER_COMPONENT_CPU, 10)
.setConsumedPowerForCustomComponent(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20)
.setUsageDurationMillis(
BatteryConsumer.POWER_COMPONENT_CPU, 30)
.setUsageDurationForCustomComponentMillis(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 40);
return builder.build();
}
public void validateBatteryUsageStats(BatteryUsageStats batteryUsageStats) {
assertThat(batteryUsageStats.getConsumedPower()).isEqualTo(30000);
assertThat(batteryUsageStats.getBatteryCapacity()).isEqualTo(4000);
assertThat(batteryUsageStats.getDischargePercentage()).isEqualTo(20);
assertThat(batteryUsageStats.getDischargedPowerRange().getLower()).isEqualTo(1000);
assertThat(batteryUsageStats.getDischargedPowerRange().getUpper()).isEqualTo(2000);
@@ -173,5 +218,26 @@ public class BatteryUsageStatsTest {
assertThat(deviceBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1);
assertThat(deviceBatteryConsumer.getCustomPowerComponentName(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo("FOO");
final List<UserBatteryConsumer> userBatteryConsumers =
batteryUsageStats.getUserBatteryConsumers();
for (UserBatteryConsumer userBatteryConsumer : userBatteryConsumers) {
if (userBatteryConsumer.getUserId() == 42) {
assertThat(userBatteryConsumer.getConsumedPower(
BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(10);
assertThat(userBatteryConsumer.getConsumedPowerForCustomComponent(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(20);
assertThat(userBatteryConsumer.getUsageDurationMillis(
BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(30);
assertThat(userBatteryConsumer.getUsageDurationForCustomComponentMillis(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(40);
assertThat(userBatteryConsumer.getConsumedPower()).isEqualTo(30);
assertThat(userBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1);
assertThat(userBatteryConsumer.getCustomPowerComponentName(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo("FOO");
} else {
fail("Unexpected user ID " + userBatteryConsumer.getUserId());
}
}
}
}