From 035fba8e31a25fc50f37b757942a9aaff29ba182 Mon Sep 17 00:00:00 2001 From: Dmitri Plotnikov Date: Tue, 25 Jan 2022 19:02:48 -0800 Subject: [PATCH] Allow requesting BatteryUsageStats for specific power components Bug: 216393849 Test: atest FrameworksCoreTests:BatteryUsageStatsProviderTest Change-Id: I8db1f41c42929ab2cfc5c64dc0c1fce74ca19896 --- .../android/os/BatteryUsageStatsQuery.java | 27 +++++- .../os/AmbientDisplayPowerCalculator.java | 5 ++ .../internal/os/AudioPowerCalculator.java | 5 ++ .../internal/os/BatteryChargeCalculator.java | 7 ++ .../os/BatteryUsageStatsProvider.java | 13 +++ .../internal/os/BluetoothPowerCalculator.java | 5 ++ .../internal/os/CameraPowerCalculator.java | 5 ++ .../internal/os/CpuPowerCalculator.java | 5 ++ .../os/CustomMeasuredPowerCalculator.java | 5 ++ .../os/FlashlightPowerCalculator.java | 5 ++ .../internal/os/GnssPowerCalculator.java | 5 ++ .../internal/os/IdlePowerCalculator.java | 5 ++ .../internal/os/MediaPowerCalculator.java | 7 ++ .../internal/os/MemoryPowerCalculator.java | 5 ++ .../os/MobileRadioPowerCalculator.java | 5 ++ .../internal/os/PhonePowerCalculator.java | 5 ++ .../android/internal/os/PowerCalculator.java | 8 ++ .../internal/os/ScreenPowerCalculator.java | 5 ++ .../internal/os/SensorPowerCalculator.java | 5 ++ .../os/SystemServicePowerCalculator.java | 5 ++ .../internal/os/UserPowerCalculator.java | 6 ++ .../internal/os/VideoPowerCalculator.java | 5 ++ .../internal/os/WakelockPowerCalculator.java | 5 ++ .../internal/os/WifiPowerCalculator.java | 5 ++ .../os/BatteryUsageStatsProviderTest.java | 82 +++++++++++++++---- .../internal/os/UserPowerCalculatorTest.java | 14 ++++ 26 files changed, 234 insertions(+), 20 deletions(-) diff --git a/core/java/android/os/BatteryUsageStatsQuery.java b/core/java/android/os/BatteryUsageStatsQuery.java index 81e49e958584a..37bd51bb66c5f 100644 --- a/core/java/android/os/BatteryUsageStatsQuery.java +++ b/core/java/android/os/BatteryUsageStatsQuery.java @@ -75,8 +75,9 @@ public final class BatteryUsageStatsQuery implements Parcelable { @NonNull private final int[] mUserIds; private final long mMaxStatsAgeMs; - private long mFromTimestamp; - private long mToTimestamp; + private final long mFromTimestamp; + private final long mToTimestamp; + private final @BatteryConsumer.PowerComponent int[] mPowerComponents; private BatteryUsageStatsQuery(@NonNull Builder builder) { mFlags = builder.mFlags; @@ -85,6 +86,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { mMaxStatsAgeMs = builder.mMaxStatsAgeMs; mFromTimestamp = builder.mFromTimestamp; mToTimestamp = builder.mToTimestamp; + mPowerComponents = builder.mPowerComponents; } @BatteryUsageStatsFlags @@ -115,6 +117,14 @@ public final class BatteryUsageStatsQuery implements Parcelable { return (mFlags & FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA) != 0; } + /** + * Returns the power components that should be estimated or null if all power components + * are being requested. + */ + public int[] getPowerComponents() { + return mPowerComponents; + } + /** * Returns the client's tolerance for stale battery stats. The data is allowed to be up to * this many milliseconds out-of-date. @@ -147,6 +157,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { mMaxStatsAgeMs = in.readLong(); mFromTimestamp = in.readLong(); mToTimestamp = in.readLong(); + mPowerComponents = in.createIntArray(); } @Override @@ -157,6 +168,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { dest.writeLong(mMaxStatsAgeMs); dest.writeLong(mFromTimestamp); dest.writeLong(mToTimestamp); + dest.writeIntArray(mPowerComponents); } @Override @@ -187,6 +199,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { private long mMaxStatsAgeMs = DEFAULT_MAX_STATS_AGE_MS; private long mFromTimestamp; private long mToTimestamp; + private @BatteryConsumer.PowerComponent int[] mPowerComponents; /** * Builds a read-only BatteryUsageStatsQuery object. @@ -247,6 +260,16 @@ public final class BatteryUsageStatsQuery implements Parcelable { return this; } + /** + * Requests to return only statistics for the specified power components. The default + * is all power components. + */ + public Builder includePowerComponents( + @BatteryConsumer.PowerComponent int[] powerComponents) { + mPowerComponents = powerComponents; + return this; + } + /** * Requests to aggregate stored snapshots between the two supplied timestamps * @param fromTimestamp Exclusive starting timestamp, as per System.currentTimeMillis() diff --git a/core/java/com/android/internal/os/AmbientDisplayPowerCalculator.java b/core/java/com/android/internal/os/AmbientDisplayPowerCalculator.java index 94430704468f2..d8e89b4c2637c 100644 --- a/core/java/com/android/internal/os/AmbientDisplayPowerCalculator.java +++ b/core/java/com/android/internal/os/AmbientDisplayPowerCalculator.java @@ -33,6 +33,11 @@ import java.util.List; public class AmbientDisplayPowerCalculator extends PowerCalculator { private final UsageBasedPowerEstimator[] mPowerEstimators; + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY; + } + public AmbientDisplayPowerCalculator(PowerProfile powerProfile) { final int numDisplays = powerProfile.getNumDisplays(); mPowerEstimators = new UsageBasedPowerEstimator[numDisplays]; diff --git a/core/java/com/android/internal/os/AudioPowerCalculator.java b/core/java/com/android/internal/os/AudioPowerCalculator.java index 2eab506bbb6c6..f9310b0c28d9c 100644 --- a/core/java/com/android/internal/os/AudioPowerCalculator.java +++ b/core/java/com/android/internal/os/AudioPowerCalculator.java @@ -43,6 +43,11 @@ public class AudioPowerCalculator extends PowerCalculator { powerProfile.getAveragePower(PowerProfile.POWER_AUDIO)); } + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_AUDIO; + } + @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/BatteryChargeCalculator.java b/core/java/com/android/internal/os/BatteryChargeCalculator.java index 81785298f8282..29b9e432b680e 100644 --- a/core/java/com/android/internal/os/BatteryChargeCalculator.java +++ b/core/java/com/android/internal/os/BatteryChargeCalculator.java @@ -16,6 +16,7 @@ package com.android.internal.os; +import android.os.BatteryConsumer; import android.os.BatteryStats; import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; @@ -29,6 +30,12 @@ import java.util.List; */ public class BatteryChargeCalculator extends PowerCalculator { + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + // Always apply this power calculator, no matter what power components were requested + return true; + } + @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java index 69b7b4e8df0ff..e4d5fb7a3edeb 100644 --- a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java +++ b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java @@ -181,9 +181,22 @@ public class BatteryUsageStatsProvider { getProcessForegroundTimeMs(uid, realtimeUs)); } + final int[] powerComponents = query.getPowerComponents(); final List powerCalculators = getPowerCalculators(); for (int i = 0, count = powerCalculators.size(); i < count; i++) { PowerCalculator powerCalculator = powerCalculators.get(i); + if (powerComponents != null) { + boolean include = false; + for (int j = 0; j < powerComponents.length; j++) { + if (powerCalculator.isPowerComponentSupported(powerComponents[j])) { + include = true; + break; + } + } + if (!include) { + continue; + } + } powerCalculator.calculate(batteryUsageStatsBuilder, mStats, realtimeUs, uptimeUs, query); } diff --git a/core/java/com/android/internal/os/BluetoothPowerCalculator.java b/core/java/com/android/internal/os/BluetoothPowerCalculator.java index 20535d29afcdd..066ee84c5ce8e 100644 --- a/core/java/com/android/internal/os/BluetoothPowerCalculator.java +++ b/core/java/com/android/internal/os/BluetoothPowerCalculator.java @@ -63,6 +63,11 @@ public class BluetoothPowerCalculator extends PowerCalculator { mHasBluetoothPowerController = mIdleMa != 0 && mRxMa != 0 && mTxMa != 0; } + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_BLUETOOTH; + } + @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/CameraPowerCalculator.java b/core/java/com/android/internal/os/CameraPowerCalculator.java index ddcabe869b326..7bccab5fc665e 100644 --- a/core/java/com/android/internal/os/CameraPowerCalculator.java +++ b/core/java/com/android/internal/os/CameraPowerCalculator.java @@ -36,6 +36,11 @@ public class CameraPowerCalculator extends PowerCalculator { profile.getAveragePower(PowerProfile.POWER_CAMERA)); } + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_CAMERA; + } + @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/CpuPowerCalculator.java b/core/java/com/android/internal/os/CpuPowerCalculator.java index ee614cdbdb951..6a96cfe85e999 100644 --- a/core/java/com/android/internal/os/CpuPowerCalculator.java +++ b/core/java/com/android/internal/os/CpuPowerCalculator.java @@ -92,6 +92,11 @@ public class CpuPowerCalculator extends PowerCalculator { } } + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_CPU; + } + @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java b/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java index bb307a0d29d8e..4cb7ef114094c 100644 --- a/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java +++ b/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java @@ -36,6 +36,11 @@ public class CustomMeasuredPowerCalculator extends PowerCalculator { public CustomMeasuredPowerCalculator(PowerProfile powerProfile) { } + @Override + public boolean isPowerComponentSupported(int powerComponent) { + return false; + } + @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/FlashlightPowerCalculator.java b/core/java/com/android/internal/os/FlashlightPowerCalculator.java index 32df17c51aace..7d3f9625aa4eb 100644 --- a/core/java/com/android/internal/os/FlashlightPowerCalculator.java +++ b/core/java/com/android/internal/os/FlashlightPowerCalculator.java @@ -34,6 +34,11 @@ public class FlashlightPowerCalculator extends PowerCalculator { profile.getAveragePower(PowerProfile.POWER_FLASHLIGHT)); } + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_FLASHLIGHT; + } + @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/GnssPowerCalculator.java b/core/java/com/android/internal/os/GnssPowerCalculator.java index a508e039fe714..a836ddb444f4a 100644 --- a/core/java/com/android/internal/os/GnssPowerCalculator.java +++ b/core/java/com/android/internal/os/GnssPowerCalculator.java @@ -43,6 +43,11 @@ public class GnssPowerCalculator extends PowerCalculator { } } + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_GNSS; + } + @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/IdlePowerCalculator.java b/core/java/com/android/internal/os/IdlePowerCalculator.java index d33a88deb9d7c..46808f9be0024 100644 --- a/core/java/com/android/internal/os/IdlePowerCalculator.java +++ b/core/java/com/android/internal/os/IdlePowerCalculator.java @@ -46,6 +46,11 @@ public class IdlePowerCalculator extends PowerCalculator { / (60 * 60 * 1_000_000.0); } + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_IDLE; + } + @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/MediaPowerCalculator.java b/core/java/com/android/internal/os/MediaPowerCalculator.java index e93d93ca7bc17..fff96dacf84b6 100644 --- a/core/java/com/android/internal/os/MediaPowerCalculator.java +++ b/core/java/com/android/internal/os/MediaPowerCalculator.java @@ -15,6 +15,7 @@ */ package com.android.internal.os; +import android.os.BatteryConsumer; import android.os.BatteryStats; /** @@ -32,6 +33,12 @@ public class MediaPowerCalculator extends PowerCalculator { mVideoAveragePowerMa = profile.getAveragePower(PowerProfile.POWER_VIDEO); } + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_VIDEO + || powerComponent == BatteryConsumer.POWER_COMPONENT_AUDIO; + } + @Override protected void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs, long rawUptimeUs, int statsType) { diff --git a/core/java/com/android/internal/os/MemoryPowerCalculator.java b/core/java/com/android/internal/os/MemoryPowerCalculator.java index 09fd85e42225b..0440a588a0931 100644 --- a/core/java/com/android/internal/os/MemoryPowerCalculator.java +++ b/core/java/com/android/internal/os/MemoryPowerCalculator.java @@ -23,6 +23,11 @@ public class MemoryPowerCalculator extends PowerCalculator { } } + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_MEMORY; + } + @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java index 28cc836396b4b..a1d5fc983dc44 100644 --- a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java +++ b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java @@ -85,6 +85,11 @@ public class MobileRadioPowerCalculator extends PowerCalculator { profile.getAveragePowerOrDefault(PowerProfile.POWER_RADIO_SCANNING, 0)); } + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO; + } + @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/PhonePowerCalculator.java b/core/java/com/android/internal/os/PhonePowerCalculator.java index 8dd463c0d5e1c..73103148a945d 100644 --- a/core/java/com/android/internal/os/PhonePowerCalculator.java +++ b/core/java/com/android/internal/os/PhonePowerCalculator.java @@ -36,6 +36,11 @@ public class PhonePowerCalculator extends PowerCalculator { powerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE)); } + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_PHONE; + } + @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/PowerCalculator.java b/core/java/com/android/internal/os/PowerCalculator.java index 93d562c571f87..d0a83e77dd4ea 100644 --- a/core/java/com/android/internal/os/PowerCalculator.java +++ b/core/java/com/android/internal/os/PowerCalculator.java @@ -35,6 +35,14 @@ public abstract class PowerCalculator { protected static final double MILLIAMPHOUR_PER_MICROCOULOMB = 1.0 / 1000.0 / 60.0 / 60.0; + /** + * Returns true if this power calculator computes power/duration for the specified + * power component. + */ + public abstract boolean isPowerComponentSupported( + @BatteryConsumer.PowerComponent int powerComponent); + + /** * Attributes the total amount of power used by this subsystem to various consumers such * as apps. diff --git a/core/java/com/android/internal/os/ScreenPowerCalculator.java b/core/java/com/android/internal/os/ScreenPowerCalculator.java index 2b634598bbbc4..d989e2aa687e9 100644 --- a/core/java/com/android/internal/os/ScreenPowerCalculator.java +++ b/core/java/com/android/internal/os/ScreenPowerCalculator.java @@ -65,6 +65,11 @@ public class ScreenPowerCalculator extends PowerCalculator { } } + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_SCREEN; + } + @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/SensorPowerCalculator.java b/core/java/com/android/internal/os/SensorPowerCalculator.java index 83e5b5702b6c6..495a6d9aae50c 100644 --- a/core/java/com/android/internal/os/SensorPowerCalculator.java +++ b/core/java/com/android/internal/os/SensorPowerCalculator.java @@ -38,6 +38,11 @@ public class SensorPowerCalculator extends PowerCalculator { } } + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_SENSORS; + } + @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/SystemServicePowerCalculator.java b/core/java/com/android/internal/os/SystemServicePowerCalculator.java index c527c06981ad2..d7872badd0a2a 100644 --- a/core/java/com/android/internal/os/SystemServicePowerCalculator.java +++ b/core/java/com/android/internal/os/SystemServicePowerCalculator.java @@ -61,6 +61,11 @@ public class SystemServicePowerCalculator extends PowerCalculator { } } + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_SYSTEM_SERVICES; + } + @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/UserPowerCalculator.java b/core/java/com/android/internal/os/UserPowerCalculator.java index 8e802869e2fc4..b590bf77283b7 100644 --- a/core/java/com/android/internal/os/UserPowerCalculator.java +++ b/core/java/com/android/internal/os/UserPowerCalculator.java @@ -16,6 +16,7 @@ package com.android.internal.os; +import android.os.BatteryConsumer; import android.os.BatteryStats; import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; @@ -33,6 +34,11 @@ import java.util.List; */ public class UserPowerCalculator extends PowerCalculator { + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + return true; + } + @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/VideoPowerCalculator.java b/core/java/com/android/internal/os/VideoPowerCalculator.java index 47916a6b09148..a222bcb4dfbfb 100644 --- a/core/java/com/android/internal/os/VideoPowerCalculator.java +++ b/core/java/com/android/internal/os/VideoPowerCalculator.java @@ -40,6 +40,11 @@ public class VideoPowerCalculator extends PowerCalculator { powerProfile.getAveragePower(PowerProfile.POWER_VIDEO)); } + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_VIDEO; + } + @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/WakelockPowerCalculator.java b/core/java/com/android/internal/os/WakelockPowerCalculator.java index e0ef1291800d7..aa6a4f87c7d07 100644 --- a/core/java/com/android/internal/os/WakelockPowerCalculator.java +++ b/core/java/com/android/internal/os/WakelockPowerCalculator.java @@ -43,6 +43,11 @@ public class WakelockPowerCalculator extends PowerCalculator { profile.getAveragePower(PowerProfile.POWER_CPU_IDLE)); } + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_WAKELOCK; + } + @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/WifiPowerCalculator.java b/core/java/com/android/internal/os/WifiPowerCalculator.java index 2a71ac6f441b6..77f15f15f8204 100644 --- a/core/java/com/android/internal/os/WifiPowerCalculator.java +++ b/core/java/com/android/internal/os/WifiPowerCalculator.java @@ -81,6 +81,11 @@ public class WifiPowerCalculator extends PowerCalculator { && mRxPowerEstimator.isSupported(); } + @Override + public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_WIFI; + } + @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java index 9b3876f6d4ca5..354b937099762 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java @@ -50,19 +50,75 @@ import java.util.List; @SmallTest @RunWith(AndroidJUnit4.class) +@SuppressWarnings("GuardedBy") public class BatteryUsageStatsProviderTest { private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42; private static final long MINUTE_IN_MS = 60 * 1000; + private static final double PRECISION = 0.00001; private final File mHistoryDir = TestIoUtils.createTemporaryDirectory(getClass().getSimpleName()); @Rule public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule(12345, mHistoryDir) - .setAveragePower(PowerProfile.POWER_FLASHLIGHT, 360.0); + .setAveragePower(PowerProfile.POWER_FLASHLIGHT, 360.0) + .setAveragePower(PowerProfile.POWER_AUDIO, 720.0); @Test public void test_getBatteryUsageStats() { + BatteryStatsImpl batteryStats = prepareBatteryStats(); + + Context context = InstrumentationRegistry.getContext(); + BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, batteryStats); + + final BatteryUsageStats batteryUsageStats = + provider.getBatteryUsageStats(BatteryUsageStatsQuery.DEFAULT); + + final List uidBatteryConsumers = + batteryUsageStats.getUidBatteryConsumers(); + final UidBatteryConsumer uidBatteryConsumer = uidBatteryConsumers.get(0); + assertThat(uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND)) + .isEqualTo(60 * MINUTE_IN_MS); + assertThat(uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND)) + .isEqualTo(10 * MINUTE_IN_MS); + assertThat(uidBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_AUDIO)) + .isWithin(PRECISION).of(2.0); + assertThat( + uidBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT)) + .isWithin(PRECISION).of(0.4); + + assertThat(batteryUsageStats.getStatsStartTimestamp()).isEqualTo(12345); + assertThat(batteryUsageStats.getStatsEndTimestamp()).isEqualTo(54321); + } + + @Test + public void test_selectPowerComponents() { + BatteryStatsImpl batteryStats = prepareBatteryStats(); + + Context context = InstrumentationRegistry.getContext(); + BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, batteryStats); + + final BatteryUsageStats batteryUsageStats = + provider.getBatteryUsageStats( + new BatteryUsageStatsQuery.Builder() + .includePowerComponents( + new int[]{BatteryConsumer.POWER_COMPONENT_AUDIO}) + .build() + ); + + final List uidBatteryConsumers = + batteryUsageStats.getUidBatteryConsumers(); + final UidBatteryConsumer uidBatteryConsumer = uidBatteryConsumers.get(0); + assertThat(uidBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_AUDIO)) + .isWithin(PRECISION).of(2.0); + + // FLASHLIGHT power estimation not requested, so the returned value is 0 + assertThat( + uidBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT)) + .isEqualTo(0); + } + + private BatteryStatsImpl prepareBatteryStats() { BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats(); batteryStats.noteActivityResumedLocked(APP_UID, @@ -82,24 +138,14 @@ public class BatteryUsageStatsProviderTest { batteryStats.noteUidProcessStateLocked(APP_UID, ActivityManager.PROCESS_STATE_CACHED_EMPTY, 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS); + batteryStats.noteFlashlightOnLocked(APP_UID, 1000, 1000); + batteryStats.noteFlashlightOffLocked(APP_UID, 5000, 5000); + + batteryStats.noteAudioOnLocked(APP_UID, 10000, 10000); + batteryStats.noteAudioOffLocked(APP_UID, 20000, 20000); + mStatsRule.setCurrentTime(54321); - - Context context = InstrumentationRegistry.getContext(); - BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, batteryStats); - - final BatteryUsageStats batteryUsageStats = - provider.getBatteryUsageStats(BatteryUsageStatsQuery.DEFAULT); - - final List uidBatteryConsumers = - batteryUsageStats.getUidBatteryConsumers(); - final UidBatteryConsumer uidBatteryConsumer = uidBatteryConsumers.get(0); - assertThat(uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND)) - .isEqualTo(60 * MINUTE_IN_MS); - assertThat(uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND)) - .isEqualTo(10 * MINUTE_IN_MS); - - assertThat(batteryUsageStats.getStatsStartTimestamp()).isEqualTo(12345); - assertThat(batteryUsageStats.getStatsEndTimestamp()).isEqualTo(54321); + return batteryStats; } @Test diff --git a/core/tests/coretests/src/com/android/internal/os/UserPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/UserPowerCalculatorTest.java index aae69d7b5bc90..aec4f524a26c9 100644 --- a/core/tests/coretests/src/com/android/internal/os/UserPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/UserPowerCalculatorTest.java @@ -126,6 +126,13 @@ public class UserPowerCalculatorTest { } private static class FakeAudioPowerCalculator extends PowerCalculator { + + @Override + public boolean isPowerComponentSupported( + @BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_AUDIO; + } + @Override protected void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { @@ -135,6 +142,13 @@ public class UserPowerCalculatorTest { } private static class FakeVideoPowerCalculator extends PowerCalculator { + + @Override + public boolean isPowerComponentSupported( + @BatteryConsumer.PowerComponent int powerComponent) { + return powerComponent == BatteryConsumer.POWER_COMPONENT_VIDEO; + } + @Override protected void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) {