Convert CpuPowerCalculator from using BatterySipper to UidBatteryConsumer

Bug: 158137862
Test: Start Settings app, navigate to Apps, pick an app, navigate to Battery

Change-Id: I1ce3d1a0ece5419384c366e908523312651877ee
This commit is contained in:
Dmitri Plotnikov
2020-12-02 14:44:59 -08:00
parent 2cefd2df6d
commit e786140e74
7 changed files with 357 additions and 37 deletions

View File

@@ -49,6 +49,28 @@ public abstract class BatteryConsumer {
public static final int FIRST_CUSTOM_POWER_COMPONENT_ID = 1000;
public static final int LAST_CUSTOM_POWER_COMPONENT_ID = 9999;
/**
* Time usage component, describing the particular part of the system
* that was used for the corresponding amount of time.
*
* @hide
*/
@IntDef(prefix = {"TIME_COMPONENT_"}, value = {
TIME_COMPONENT_CPU,
TIME_COMPONENT_CPU_FOREGROUND,
})
@Retention(RetentionPolicy.SOURCE)
public static @interface TimeComponent {
}
public static final int TIME_COMPONENT_CPU = 0;
public static final int TIME_COMPONENT_CPU_FOREGROUND = 1;
public static final int TIME_COMPONENT_COUNT = 2;
public static final int FIRST_CUSTOM_TIME_COMPONENT_ID = 1000;
public static final int LAST_CUSTOM_TIME_COMPONENT_ID = 9999;
private final PowerComponents mPowerComponents;
protected BatteryConsumer(@NonNull PowerComponents powerComponents) {
@@ -83,6 +105,29 @@ public abstract class BatteryConsumer {
return mPowerComponents.getConsumedPowerForCustomComponent(componentId);
}
/**
* Returns the amount of time since BatteryStats reset used by the specified component, e.g.
* CPU, WiFi etc.
*
* @param componentId The ID of the time component, e.g.
* {@link UidBatteryConsumer#TIME_COMPONENT_CPU}.
* @return Amount of time in milliseconds.
*/
public long getUsageDurationMillis(@TimeComponent int componentId) {
return mPowerComponents.getUsageDurationMillis(componentId);
}
/**
* Returns the amount of usage time attributed to the specified custom component
* since BatteryStats reset.
*
* @param componentId The ID of the custom power component.
* @return Amount of time in milliseconds.
*/
public long getUsageDurationForCustomComponentMillis(int componentId) {
return mPowerComponents.getUsageDurationForCustomComponentMillis(componentId);
}
protected void writeToParcel(Parcel dest, int flags) {
mPowerComponents.writeToParcel(dest, flags);
}

View File

@@ -35,7 +35,11 @@ public final class BatteryUsageStats implements Parcelable {
private BatteryUsageStats(@NonNull Builder builder) {
mConsumedPower = builder.mConsumedPower;
mDischargePercentage = builder.mDischargePercentage;
mUidBatteryConsumers = builder.mUidBatteryConsumers;
final int uidBatteryConsumerCount = builder.mUidBatteryConsumerBuilders.size();
mUidBatteryConsumers = new ArrayList<>(uidBatteryConsumerCount);
for (int i = 0; i < uidBatteryConsumerCount; i++) {
mUidBatteryConsumers.add(builder.mUidBatteryConsumerBuilders.get(i).build());
}
}
/**
@@ -95,7 +99,8 @@ public final class BatteryUsageStats implements Parcelable {
public static final class Builder {
private double mConsumedPower;
private int mDischargePercentage;
private final ArrayList<UidBatteryConsumer> mUidBatteryConsumers = new ArrayList<>();
private final ArrayList<UidBatteryConsumer.Builder> mUidBatteryConsumerBuilders =
new ArrayList<>();
/**
* Constructs a read-only object using the Builder values.
@@ -130,9 +135,15 @@ public final class BatteryUsageStats implements Parcelable {
* individual UID.
*/
@NonNull
public Builder addUidBatteryConsumer(@NonNull UidBatteryConsumer uidBatteryConsumer) {
mUidBatteryConsumers.add(uidBatteryConsumer);
public Builder addUidBatteryConsumerBuilder(
@NonNull UidBatteryConsumer.Builder uidBatteryConsumer) {
mUidBatteryConsumerBuilders.add(uidBatteryConsumer);
return this;
}
@NonNull
public List<UidBatteryConsumer.Builder> getUidBatteryConsumerBuilders() {
return mUidBatteryConsumerBuilders;
}
}
}

View File

@@ -29,21 +29,25 @@ class PowerComponents {
private final double mTotalPowerConsumed;
private final double[] mPowerComponents;
private final long[] mTimeComponents;
PowerComponents(@NonNull Builder builder) {
mTotalPowerConsumed = builder.mTotalPowerConsumed;
mPowerComponents = builder.mPowerComponents;
mTimeComponents = builder.mTimeComponents;
}
PowerComponents(@NonNull Parcel source) {
mTotalPowerConsumed = source.readDouble();
mPowerComponents = source.createDoubleArray();
mTimeComponents = source.createLongArray();
}
/** Writes contents to Parcel */
void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeDouble(mTotalPowerConsumed);
dest.writeDoubleArray(mPowerComponents);
dest.writeLongArray(mTimeComponents);
}
/**
@@ -93,16 +97,59 @@ class PowerComponents {
}
}
/**
* Returns the amount of time used by the specified component, e.g. CPU, WiFi etc.
*
* @param componentId The ID of the time component, e.g.
* {@link UidBatteryConsumer#TIME_COMPONENT_CPU}.
* @return Amount of time in milliseconds.
*/
public long getUsageDurationMillis(@UidBatteryConsumer.TimeComponent int componentId) {
if (componentId >= UidBatteryConsumer.TIME_COMPONENT_COUNT) {
throw new IllegalArgumentException(
"Unsupported time component ID: " + componentId);
}
try {
return mTimeComponents[componentId];
} catch (ArrayIndexOutOfBoundsException e) {
throw new IllegalArgumentException("Unsupported power component ID: " + componentId);
}
}
/**
* Returns the amount of usage time attributed to the specified custom component.
*
* @param componentId The ID of the custom power component.
* @return Amount of time in milliseconds.
*/
public long getUsageDurationForCustomComponentMillis(int componentId) {
if (componentId < UidBatteryConsumer.FIRST_CUSTOM_TIME_COMPONENT_ID) {
throw new IllegalArgumentException(
"Unsupported custom time component ID: " + componentId);
}
try {
return mTimeComponents[
UidBatteryConsumer.TIME_COMPONENT_COUNT + componentId
- UidBatteryConsumer.FIRST_CUSTOM_TIME_COMPONENT_ID];
} catch (ArrayIndexOutOfBoundsException e) {
throw new IllegalArgumentException(
"Unsupported custom time component ID: " + componentId);
}
}
/**
* Builder for PowerComponents.
*/
static final class Builder {
private double mTotalPowerConsumed;
private final double[] mPowerComponents;
private final long[] mTimeComponents;
Builder(int customPowerComponentCount) {
mPowerComponents = new double[BatteryConsumer.POWER_COMPONENT_COUNT
Builder(int customPowerComponentCount, int customTimeComponentCount) {
mPowerComponents = new double[UidBatteryConsumer.POWER_COMPONENT_COUNT
+ customPowerComponentCount];
mTimeComponents = new long[UidBatteryConsumer.TIME_COMPONENT_COUNT
+ customTimeComponentCount];
}
/**
@@ -159,6 +206,53 @@ class PowerComponents {
return this;
}
/**
* Sets the amount of time used by the specified component, e.g. CPU, WiFi etc.
*
* @param componentId The ID of the time component, e.g.
* {@link UidBatteryConsumer#TIME_COMPONENT_CPU}.
* @param componentUsageDurationMillis Amount of time in milliseconds.
*/
@NonNull
public Builder setUsageDurationMillis(@UidBatteryConsumer.TimeComponent int componentId,
long componentUsageDurationMillis) {
if (componentId >= UidBatteryConsumer.TIME_COMPONENT_COUNT) {
throw new IllegalArgumentException(
"Unsupported time component ID: " + componentId);
}
try {
mTimeComponents[componentId] = componentUsageDurationMillis;
} catch (ArrayIndexOutOfBoundsException e) {
throw new IllegalArgumentException(
"Unsupported time component ID: " + componentId);
}
return this;
}
/**
* Sets the amount of time used by the specified custom component.
*
* @param componentId The ID of the custom power component.
* @param componentUsageDurationMillis Amount of time in milliseconds.
*/
@NonNull
public Builder setUsageDurationForCustomComponentMillis(int componentId,
long componentUsageDurationMillis) {
if (componentId < UidBatteryConsumer.FIRST_CUSTOM_TIME_COMPONENT_ID) {
throw new IllegalArgumentException(
"Unsupported custom time component ID: " + componentId);
}
try {
mTimeComponents[UidBatteryConsumer.TIME_COMPONENT_COUNT + componentId
- UidBatteryConsumer.FIRST_CUSTOM_TIME_COMPONENT_ID] =
componentUsageDurationMillis;
} catch (ArrayIndexOutOfBoundsException e) {
throw new IllegalArgumentException(
"Unsupported custom time component ID: " + componentId);
}
return this;
}
/**
* Creates a read-only object out of the Builder values.
*/

View File

@@ -82,12 +82,24 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
*/
public static final class Builder {
private final PowerComponents.Builder mPowerComponentsBuilder;
private final BatteryStats.Uid mBatteryStatsUid;
private final int mUid;
private String mPackageWithHighestDrain;
public Builder(int customPowerComponentCount, int uid) {
mPowerComponentsBuilder = new PowerComponents.Builder(customPowerComponentCount);
mUid = uid;
public Builder(int customPowerComponentCount, int customTimeComponentCount,
BatteryStats.Uid batteryStatsUid) {
mPowerComponentsBuilder = new PowerComponents.Builder(customPowerComponentCount,
customTimeComponentCount);
mBatteryStatsUid = batteryStatsUid;
mUid = batteryStatsUid.getUid();
}
public BatteryStats.Uid getBatteryStatsUid() {
return mBatteryStatsUid;
}
public int getUid() {
return mUid;
}
/**
@@ -102,7 +114,7 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
* Sets the amount of drain attributed to the specified drain type, e.g. CPU, WiFi etc.
*
* @param componentId The ID of the power component, e.g.
* {@link BatteryConsumer#POWER_COMPONENT_CPU}.
* {@link BatteryConsumer#POWER_COMPONENT_CPU}.
* @param componentPower Amount of consumed power in mAh.
*/
@NonNull
@@ -132,6 +144,35 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
return this;
}
/**
* Sets the amount of time used by the specified component, e.g. CPU, WiFi etc.
*
* @param componentId The ID of the time component, e.g.
* {@link UidBatteryConsumer#TIME_COMPONENT_CPU}.
* @param componentUsageDurationMillis Amount of time in milliseconds.
*/
@NonNull
public Builder setUsageDurationMillis(@UidBatteryConsumer.TimeComponent int componentId,
long componentUsageDurationMillis) {
mPowerComponentsBuilder.setUsageDurationMillis(componentId,
componentUsageDurationMillis);
return this;
}
/**
* Sets the amount of time used by the specified custom component.
*
* @param componentId The ID of the custom power component.
* @param componentUsageDurationMillis Amount of time in milliseconds.
*/
@NonNull
public Builder setUsageDurationForCustomComponentMillis(int componentId,
long componentUsageDurationMillis) {
mPowerComponentsBuilder.setUsageDurationForCustomComponentMillis(componentId,
componentUsageDurationMillis);
return this;
}
/**
* Sets the name of the package owned by this UID that consumed the highest amount
* of power since BatteryStats reset.

View File

@@ -17,13 +17,18 @@
package com.android.internal.os;
import android.content.Context;
import android.os.BatteryConsumer;
import android.hardware.SensorManager;
import android.net.ConnectivityManager;
import android.os.BatteryStats;
import android.os.BatteryUsageStats;
import android.os.Bundle;
import android.os.SystemClock;
import android.os.UidBatteryConsumer;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.SparseArray;
import java.util.ArrayList;
import java.util.List;
/**
@@ -33,10 +38,53 @@ import java.util.List;
public class BatteryUsageStatsProvider {
private final Context mContext;
private final BatteryStatsImpl mStats;
private final PowerProfile mPowerProfile;
private final Object mLock = new Object();
private List<PowerCalculator> mPowerCalculators;
public BatteryUsageStatsProvider(Context context, BatteryStatsImpl stats) {
mContext = context;
mStats = stats;
mPowerProfile = new PowerProfile(mContext);
}
private List<PowerCalculator> getPowerCalculators() {
synchronized (mLock) {
if (mPowerCalculators == null) {
mPowerCalculators = new ArrayList<>();
// Power calculators are applied in the order of registration
mPowerCalculators.add(new CpuPowerCalculator(mPowerProfile));
mPowerCalculators.add(new MemoryPowerCalculator(mPowerProfile));
mPowerCalculators.add(new WakelockPowerCalculator(mPowerProfile));
if (!isWifiOnlyDevice(mContext)) {
mPowerCalculators.add(new MobileRadioPowerCalculator(mPowerProfile));
}
mPowerCalculators.add(new WifiPowerCalculator(mPowerProfile));
mPowerCalculators.add(new BluetoothPowerCalculator(mPowerProfile));
mPowerCalculators.add(new SensorPowerCalculator(mPowerProfile,
mContext.getSystemService(SensorManager.class)));
mPowerCalculators.add(new CameraPowerCalculator(mPowerProfile));
mPowerCalculators.add(new FlashlightPowerCalculator(mPowerProfile));
mPowerCalculators.add(new MediaPowerCalculator(mPowerProfile));
mPowerCalculators.add(new PhonePowerCalculator(mPowerProfile));
mPowerCalculators.add(new ScreenPowerCalculator(mPowerProfile));
mPowerCalculators.add(new AmbientDisplayPowerCalculator(mPowerProfile));
mPowerCalculators.add(new SystemServicePowerCalculator(mPowerProfile));
mPowerCalculators.add(new IdlePowerCalculator(mPowerProfile));
mPowerCalculators.add(new UserPowerCalculator());
}
}
return mPowerCalculators;
}
private static boolean isWifiOnlyDevice(Context context) {
ConnectivityManager cm = context.getSystemService(ConnectivityManager.class);
if (cm == null) {
return false;
}
return !cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
}
/**
@@ -49,11 +97,19 @@ public class BatteryUsageStatsProvider {
false /* collectBatteryBroadcast */);
batteryStatsHelper.create((Bundle) null);
final UserManager userManager = mContext.getSystemService(UserManager.class);
batteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED,
userManager.getUserProfiles());
final List<UserHandle> asUsers = userManager.getUserProfiles();
final int n = asUsers.size();
SparseArray<UserHandle> users = new SparseArray<>(n);
for (int i = 0; i < n; ++i) {
UserHandle userHandle = asUsers.get(i);
users.put(userHandle.getIdentifier(), userHandle);
}
batteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, users);
// TODO(b/174186358): read extra power component number from configuration
final int customPowerComponentCount = 0;
final int customTimeComponentCount = 0;
final BatteryUsageStats.Builder batteryUsageStatsBuilder = new BatteryUsageStats.Builder()
.setDischargePercentage(batteryStatsHelper.getStats().getDischargeAmount(0))
.setConsumedPower(batteryStatsHelper.getTotalPower());
@@ -62,15 +118,23 @@ public class BatteryUsageStatsProvider {
for (int i = 0; i < usageList.size(); i++) {
final BatterySipper sipper = usageList.get(i);
if (sipper.drainType == BatterySipper.DrainType.APP) {
batteryUsageStatsBuilder.addUidBatteryConsumer(
new UidBatteryConsumer.Builder(customPowerComponentCount, sipper.getUid())
batteryUsageStatsBuilder.addUidBatteryConsumerBuilder(
new UidBatteryConsumer.Builder(customPowerComponentCount,
customTimeComponentCount, sipper.uidObj)
.setPackageWithHighestDrain(sipper.packageWithHighestDrain)
.setConsumedPower(sipper.sumPower())
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU,
sipper.cpuPowerMah)
.build());
.setConsumedPower(sipper.sumPower()));
}
}
final long realtimeUs = SystemClock.elapsedRealtime() * 1000;
final long uptimeUs = SystemClock.uptimeMillis() * 1000;
final List<PowerCalculator> powerCalculators = getPowerCalculators();
for (PowerCalculator powerCalculator : powerCalculators) {
powerCalculator.calculate(batteryUsageStatsBuilder, mStats, realtimeUs, uptimeUs,
BatteryStats.STATS_SINCE_CHARGED, users);
}
return batteryUsageStatsBuilder.build();
}
}

View File

@@ -16,6 +16,7 @@
package com.android.internal.os;
import android.os.BatteryStats;
import android.os.UidBatteryConsumer;
import android.util.ArrayMap;
import android.util.Log;
@@ -30,9 +31,9 @@ public class CpuPowerCalculator extends PowerCalculator {
}
@Override
protected void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
long rawUptimeUs, int statsType) {
app.cpuTimeMs = (u.getUserCpuTimeUs(statsType) + u.getSystemCpuTimeUs(statsType)) / 1000;
protected void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u,
long rawRealtimeUs, long rawUptimeUs, int statsType) {
long cpuTimeMs = (u.getUserCpuTimeUs(statsType) + u.getSystemCpuTimeUs(statsType)) / 1000;
final int numClusters = mProfile.getNumCpuClusters();
double cpuPowerMaUs = 0;
@@ -70,47 +71,52 @@ public class CpuPowerCalculator extends PowerCalculator {
+ numClusters + " actual # " + cpuClusterTimes.length);
}
}
app.cpuPowerMah = cpuPowerMaUs / MICROSEC_IN_HR;
final double cpuPowerMah = cpuPowerMaUs / MICROSEC_IN_HR;
if (DEBUG && (app.cpuTimeMs != 0 || app.cpuPowerMah != 0)) {
Log.d(TAG, "UID " + u.getUid() + ": CPU time=" + app.cpuTimeMs + " ms power="
+ formatCharge(app.cpuPowerMah));
if (DEBUG && (cpuTimeMs != 0 || cpuPowerMah != 0)) {
Log.d(TAG, "UID " + u.getUid() + ": CPU time=" + cpuTimeMs + " ms power="
+ formatCharge(cpuPowerMah));
}
// Keep track of the package with highest drain.
double highestDrain = 0;
app.cpuFgTimeMs = 0;
String packageWithHighestDrain = null;
long cpuFgTimeMs = 0;
final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
final int processStatsCount = processStats.size();
for (int i = 0; i < processStatsCount; i++) {
final BatteryStats.Uid.Proc ps = processStats.valueAt(i);
final String processName = processStats.keyAt(i);
app.cpuFgTimeMs += ps.getForegroundTime(statsType);
cpuFgTimeMs += ps.getForegroundTime(statsType);
final long costValue = ps.getUserTime(statsType) + ps.getSystemTime(statsType)
+ ps.getForegroundTime(statsType);
// Each App can have multiple packages and with multiple running processes.
// Keep track of the package who's process has the highest drain.
if (app.packageWithHighestDrain == null ||
app.packageWithHighestDrain.startsWith("*")) {
if (packageWithHighestDrain == null || packageWithHighestDrain.startsWith("*")) {
highestDrain = costValue;
app.packageWithHighestDrain = processName;
packageWithHighestDrain = processName;
} else if (highestDrain < costValue && !processName.startsWith("*")) {
highestDrain = costValue;
app.packageWithHighestDrain = processName;
packageWithHighestDrain = processName;
}
}
// Ensure that the CPU times make sense.
if (app.cpuFgTimeMs > app.cpuTimeMs) {
if (DEBUG && app.cpuFgTimeMs > app.cpuTimeMs + 10000) {
if (cpuFgTimeMs > cpuTimeMs) {
if (DEBUG && cpuFgTimeMs > cpuTimeMs + 10000) {
Log.d(TAG, "WARNING! Cputime is more than 10 seconds behind Foreground time");
}
// Statistics may not have been gathered yet.
app.cpuTimeMs = app.cpuFgTimeMs;
cpuTimeMs = cpuFgTimeMs;
}
app.setConsumedPower(UidBatteryConsumer.POWER_COMPONENT_CPU, cpuPowerMah);
app.setUsageDurationMillis(UidBatteryConsumer.TIME_COMPONENT_CPU, cpuTimeMs);
app.setUsageDurationMillis(UidBatteryConsumer.TIME_COMPONENT_CPU_FOREGROUND, cpuFgTimeMs);
app.setPackageWithHighestDrain(packageWithHighestDrain);
}
}

View File

@@ -16,6 +16,8 @@
package com.android.internal.os;
import android.os.BatteryStats;
import android.os.BatteryUsageStats;
import android.os.UidBatteryConsumer;
import android.os.UserHandle;
import android.util.SparseArray;
@@ -54,6 +56,34 @@ public abstract class PowerCalculator {
}
}
/**
* Attributes the total amount of power used by this subsystem to various consumers such
* as apps.
*
* @param builder {@link BatteryUsageStats.Builder that contains a list of
* per-UID battery consumer builders for attribution data.
* The calculator may modify the builder and its constituent parts.
* @param batteryStats The recorded battery stats.
* @param rawRealtimeUs The raw system realtime in microseconds.
* @param rawUptimeUs The raw system uptime in microseconds.
* @param statsType The type of stats. As of {@link android.os.Build.VERSION_CODES#Q}, this
* can only be {@link BatteryStats#STATS_SINCE_CHARGED}, since
* {@link BatteryStats#STATS_CURRENT} and
* {@link BatteryStats#STATS_SINCE_UNPLUGGED} are deprecated.
* @param asUsers An array of users for which the attribution is requested. It may
* contain {@link UserHandle#USER_ALL} to indicate that the attribution
* should be performed for all users.
*/
public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats,
long rawRealtimeUs, long rawUptimeUs, int statsType, SparseArray<UserHandle> asUsers) {
final List<UidBatteryConsumer.Builder> uidBatteryConsumerBuilders =
builder.getUidBatteryConsumerBuilders();
for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) {
final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.get(i);
calculateApp(app, app.getBatteryStatsUid(), rawRealtimeUs, rawUptimeUs, statsType);
}
}
/**
* Calculate the amount of power an app used for this subsystem.
* @param app The BatterySipper that represents the power use of an app.
@@ -66,7 +96,36 @@ public abstract class PowerCalculator {
* {@link BatteryStats#STATS_SINCE_UNPLUGGED} are deprecated.
*/
protected void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
long rawUptimeUs, int statsType) {}
long rawUptimeUs, int statsType) {
// TODO(b/175156498): Temporary code during the transition from BatterySippers to
// BatteryConsumers.
UidBatteryConsumer.Builder builder = new UidBatteryConsumer.Builder(0, 0, u);
calculateApp(builder, u, rawRealtimeUs, rawUptimeUs, statsType);
final UidBatteryConsumer uidBatteryConsumer = builder.build();
app.cpuPowerMah = uidBatteryConsumer.getConsumedPower(
UidBatteryConsumer.POWER_COMPONENT_CPU);
app.cpuTimeMs = uidBatteryConsumer.getUsageDurationMillis(
UidBatteryConsumer.TIME_COMPONENT_CPU);
app.cpuFgTimeMs = uidBatteryConsumer.getUsageDurationMillis(
UidBatteryConsumer.TIME_COMPONENT_CPU_FOREGROUND);
app.packageWithHighestDrain = uidBatteryConsumer.getPackageWithHighestDrain();
}
/**
* Calculate the amount of power an app used for this subsystem.
* @param app The UidBatteryConsumer.Builder that represents the power use of an app.
* @param u The recorded stats for the app.
* @param rawRealtimeUs The raw system realtime in microseconds.
* @param rawUptimeUs The raw system uptime in microseconds.
* @param statsType The type of stats. As of {@link android.os.Build.VERSION_CODES#Q}, this can
* only be {@link BatteryStats#STATS_SINCE_CHARGED}, since
* {@link BatteryStats#STATS_CURRENT} and
* {@link BatteryStats#STATS_SINCE_UNPLUGGED} are deprecated.
*/
protected void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u,
long rawRealtimeUs, long rawUptimeUs, int statsType) {
}
/**
* Reset any state maintained in this calculator.