summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Dmitri Plotnikov <dplotnikov@google.com> 2020-12-02 14:44:59 -0800
committer Dmitri Plotnikov <dplotnikov@google.com> 2020-12-09 18:17:18 -0800
commite786140e74d708e5ca013be2ce7bcf6f78c1a691 (patch)
tree44ea1e35075ff006e20a51ff9f22a6f308e384a8
parent2cefd2df6d93cea24c91411422f7dfe61e9a33ce (diff)
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
-rw-r--r--core/java/android/os/BatteryConsumer.java45
-rw-r--r--core/java/android/os/BatteryUsageStats.java19
-rw-r--r--core/java/android/os/PowerComponents.java98
-rw-r--r--core/java/android/os/UidBatteryConsumer.java49
-rw-r--r--core/java/com/android/internal/os/BatteryUsageStatsProvider.java82
-rw-r--r--core/java/com/android/internal/os/CpuPowerCalculator.java40
-rw-r--r--core/java/com/android/internal/os/PowerCalculator.java61
7 files changed, 357 insertions, 37 deletions
diff --git a/core/java/android/os/BatteryConsumer.java b/core/java/android/os/BatteryConsumer.java
index d00c3c361722..74880b2d61d3 100644
--- a/core/java/android/os/BatteryConsumer.java
+++ b/core/java/android/os/BatteryConsumer.java
@@ -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);
}
diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java
index 3f036cdcfa72..79f58f68b637 100644
--- a/core/java/android/os/BatteryUsageStats.java
+++ b/core/java/android/os/BatteryUsageStats.java
@@ -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;
+ }
}
}
diff --git a/core/java/android/os/PowerComponents.java b/core/java/android/os/PowerComponents.java
index 42ba1ff60e5a..c18fff64ba62 100644
--- a/core/java/android/os/PowerComponents.java
+++ b/core/java/android/os/PowerComponents.java
@@ -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);
}
/**
@@ -94,15 +98,58 @@ 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];
}
/**
@@ -160,6 +207,53 @@ class PowerComponents {
}
/**
+ * 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.
*/
@NonNull
diff --git a/core/java/android/os/UidBatteryConsumer.java b/core/java/android/os/UidBatteryConsumer.java
index 7dcbf7d4cef3..d12ccb57794b 100644
--- a/core/java/android/os/UidBatteryConsumer.java
+++ b/core/java/android/os/UidBatteryConsumer.java
@@ -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
@@ -133,6 +145,35 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
}
/**
+ * 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.
*/
diff --git a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
index 62e9f98181ab..e1d0a151c723 100644
--- a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
+++ b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
@@ -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();
}
}
diff --git a/core/java/com/android/internal/os/CpuPowerCalculator.java b/core/java/com/android/internal/os/CpuPowerCalculator.java
index dac62a678665..732d2916a092 100644
--- a/core/java/com/android/internal/os/CpuPowerCalculator.java
+++ b/core/java/com/android/internal/os/CpuPowerCalculator.java
@@ -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);
}
}
diff --git a/core/java/com/android/internal/os/PowerCalculator.java b/core/java/com/android/internal/os/PowerCalculator.java
index f171b0d99acc..a57339b84b50 100644
--- a/core/java/com/android/internal/os/PowerCalculator.java
+++ b/core/java/com/android/internal/os/PowerCalculator.java
@@ -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;
@@ -55,6 +57,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.
* @param u The recorded stats for the 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.