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:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user