diff options
| author | 2020-12-02 14:44:59 -0800 | |
|---|---|---|
| committer | 2020-12-09 18:17:18 -0800 | |
| commit | e786140e74d708e5ca013be2ce7bcf6f78c1a691 (patch) | |
| tree | 44ea1e35075ff006e20a51ff9f22a6f308e384a8 | |
| parent | 2cefd2df6d93cea24c91411422f7dfe61e9a33ce (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.java | 45 | ||||
| -rw-r--r-- | core/java/android/os/BatteryUsageStats.java | 19 | ||||
| -rw-r--r-- | core/java/android/os/PowerComponents.java | 98 | ||||
| -rw-r--r-- | core/java/android/os/UidBatteryConsumer.java | 49 | ||||
| -rw-r--r-- | core/java/com/android/internal/os/BatteryUsageStatsProvider.java | 82 | ||||
| -rw-r--r-- | core/java/com/android/internal/os/CpuPowerCalculator.java | 40 | ||||
| -rw-r--r-- | core/java/com/android/internal/os/PowerCalculator.java | 61 |
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. |