diff options
5 files changed, 123 insertions, 39 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index cc86a604c194..6f89254d9388 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -994,6 +994,19 @@ public abstract class BatteryStats implements Parcelable { */ public abstract long getScreenOnEnergy(); + /** + * Returns the energies used by this uid for each + * {@link android.hardware.power.stats.EnergyConsumer.ordinal} of (custom) energy consumer + * type {@link android.hardware.power.stats.EnergyConsumerType#OTHER}). + * + * @return energies (in microjoules) used since boot for each (custom) energy consumer of + * type OTHER, indexed by their ordinal. Returns null if no energy reporting is + * supported. + * + * {@hide} + */ + public abstract @Nullable long[] getCustomMeasuredEnergiesMicroJoules(); + public static abstract class Sensor { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) @@ -2511,6 +2524,19 @@ public abstract class BatteryStats implements Parcelable { */ public abstract long getScreenDozeEnergy(); + /** + * Returns the energies used for each + * {@link android.hardware.power.stats.EnergyConsumer.ordinal} of (custom) energy consumer + * type {@link android.hardware.power.stats.EnergyConsumerType#OTHER}). + * + * @return energies (in microjoules) used since boot for each (custom) energy consumer of + * type OTHER, indexed by their ordinal. Returns null if no energy reporting is + * supported. + * + * {@hide} + */ + public abstract @Nullable long[] getCustomMeasuredEnergiesMicroJoules(); + public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS = new BitDescription[] { new BitDescription(HistoryItem.STATE_CPU_RUNNING_FLAG, "running", "r"), new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock", "w"), diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 0da2998ee9c3..96a71b994375 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -7157,34 +7157,34 @@ public class BatteryStatsImpl extends BatteryStats { @Override public long getScreenOnEnergy() { - if (mGlobalMeasuredEnergyStats == null) { - return ENERGY_DATA_UNAVAILABLE; - } - return mGlobalMeasuredEnergyStats - .getAccumulatedStandardBucketEnergy(MeasuredEnergyStats.ENERGY_BUCKET_SCREEN_ON); + return getMeasuredEnergyMicroJoules(MeasuredEnergyStats.ENERGY_BUCKET_SCREEN_ON); } @Override public long getScreenDozeEnergy() { - if (mGlobalMeasuredEnergyStats == null) { - return ENERGY_DATA_UNAVAILABLE; - } - return mGlobalMeasuredEnergyStats - .getAccumulatedStandardBucketEnergy(MeasuredEnergyStats.ENERGY_BUCKET_SCREEN_DOZE); + return getMeasuredEnergyMicroJoules(MeasuredEnergyStats.ENERGY_BUCKET_SCREEN_DOZE); } /** - * Returns the energy in microjoules that the given custom energy bucket consumed. + * Returns the energy in microjoules that the given standard energy bucket consumed. * Will return {@link #ENERGY_DATA_UNAVAILABLE} if data is unavailable * - * @param customEnergyBucket custom energy bucket of interest - * @return energy (in microjoules) used by this uid for this energy bucket + * @param bucket standard energy bucket of interest + * @return energy (in microjoules) used for this energy bucket */ - public long getCustomMeasuredEnergyMicroJoules(int customEnergyBucket) { + private long getMeasuredEnergyMicroJoules(@StandardEnergyBucket int bucket) { if (mGlobalMeasuredEnergyStats == null) { return ENERGY_DATA_UNAVAILABLE; } - return mGlobalMeasuredEnergyStats.getAccumulatedCustomBucketEnergy(customEnergyBucket); + return mGlobalMeasuredEnergyStats.getAccumulatedStandardBucketEnergy(bucket); + } + + @Override + public @Nullable long[] getCustomMeasuredEnergiesMicroJoules() { + if (mGlobalMeasuredEnergyStats == null) { + return null; + } + return mGlobalMeasuredEnergyStats.getAccumulatedCustomBucketEnergies(); } @Override public long getStartClockTime() { @@ -7978,20 +7978,16 @@ public class BatteryStatsImpl extends BatteryStats { return mUidMeasuredEnergyStats.getAccumulatedStandardBucketEnergy(bucket); } - /** - * Returns the energy used by this uid for a custom energy bucket of interest. - * @param customEnergyBucket custom energy bucket of interest - * @return energy (in microjoules) used by this uid for this energy bucket - */ - public long getCustomMeasuredEnergyMicroJoules(int customEnergyBucket) { - if (mBsi.mGlobalMeasuredEnergyStats == null - || !mBsi.mGlobalMeasuredEnergyStats.isValidCustomBucket(customEnergyBucket)) { - return ENERGY_DATA_UNAVAILABLE; + @Override + public long[] getCustomMeasuredEnergiesMicroJoules() { + if (mBsi.mGlobalMeasuredEnergyStats == null) { + return null; } if (mUidMeasuredEnergyStats == null) { - return 0L; // It is supported, but was never filled, so it must be 0 + // Custom buckets may exist. But all values for this uid are 0 so we report all 0s. + return new long[mBsi.mGlobalMeasuredEnergyStats.getNumberCustomEnergyBuckets()]; } - return mUidMeasuredEnergyStats.getAccumulatedCustomBucketEnergy(customEnergyBucket); + return mUidMeasuredEnergyStats.getAccumulatedCustomBucketEnergies(); } /** @@ -14527,7 +14523,12 @@ public class BatteryStatsImpl extends BatteryStats { */ @GuardedBy("this") public void dumpMeasuredEnergyStatsLocked(PrintWriter pw) { - if (mGlobalMeasuredEnergyStats == null) return; + pw.printf("On battery measured energy stats (microjoules) \n"); + if (mGlobalMeasuredEnergyStats == null) { + pw.printf(" Not supported on this device.\n"); + return; + } + dumpMeasuredEnergyStatsLocked(pw, "non-uid usage", mGlobalMeasuredEnergyStats); int size = mUidStats.size(); @@ -14545,7 +14546,8 @@ public class BatteryStatsImpl extends BatteryStats { MeasuredEnergyStats stats) { if (stats == null) return; final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); - iPw.printf("On battery measured energy stats for %s:\n", name); + iPw.increaseIndent(); + iPw.printf("%s:\n", name); iPw.increaseIndent(); stats.dump(iPw); iPw.decreaseIndent(); diff --git a/core/java/com/android/internal/power/MeasuredEnergyStats.java b/core/java/com/android/internal/power/MeasuredEnergyStats.java index 38ef55c065a0..d7b4d78c56cf 100644 --- a/core/java/com/android/internal/power/MeasuredEnergyStats.java +++ b/core/java/com/android/internal/power/MeasuredEnergyStats.java @@ -238,6 +238,7 @@ public class MeasuredEnergyStats { * Return accumulated energy (in microjoules) for the a custom energy bucket since last reset. * Returns {@link android.os.BatteryStats#ENERGY_DATA_UNAVAILABLE} if this data is unavailable. */ + @VisibleForTesting public long getAccumulatedCustomBucketEnergy(int customBucket) { if (!isValidCustomBucket(customBucket)) { return ENERGY_DATA_UNAVAILABLE; @@ -246,6 +247,17 @@ public class MeasuredEnergyStats { } /** + * Return accumulated energies (in microjoules) for all custom energy buckets since last reset. + */ + public @NonNull long[] getAccumulatedCustomBucketEnergies() { + final long[] energies = new long[getNumberCustomEnergyBuckets()]; + for (int bucket = 0; bucket < energies.length; bucket++) { + energies[bucket] = mAccumulatedEnergiesMicroJoules[customBucketToIndex(bucket)]; + } + return energies; + } + + /** * Map {@link android.view.Display} STATE_ to corresponding {@link StandardEnergyBucket}. */ public static @StandardEnergyBucket int getDisplayEnergyBucket(int screenState) { @@ -404,7 +416,6 @@ public class MeasuredEnergyStats { /** Dump debug data. */ public void dump(PrintWriter pw) { - pw.println("Accumulated energy since last reset (microjoules):"); pw.print(" "); for (int index = 0; index < mAccumulatedEnergiesMicroJoules.length; index++) { pw.print(getBucketName(index)); @@ -431,6 +442,11 @@ public class MeasuredEnergyStats { return "CUSTOM_" + indexToCustomBucket(index); } + /** Get the number of custom energy buckets on this device. */ + public int getNumberCustomEnergyBuckets() { + return mAccumulatedEnergiesMicroJoules.length - NUMBER_STANDARD_ENERGY_BUCKETS; + } + private static int customBucketToIndex(int customBucket) { return customBucket + NUMBER_STANDARD_ENERGY_BUCKETS; } @@ -450,6 +466,7 @@ public class MeasuredEnergyStats { } /** Returns whether the given custom bucket is valid (exists) on this device. */ + @VisibleForTesting public boolean isValidCustomBucket(int customBucket) { return customBucket >= 0 && customBucketToIndex(customBucket) < mAccumulatedEnergiesMicroJoules.length; diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java index 4c52848cc079..6652c64c4344 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java @@ -707,22 +707,26 @@ public class BatteryStatsNoteTest extends TestCase { int uid2, long blame2A, long blame2B, MockBatteryStatsImpl bi) { + final long[] actualTotal = bi.getCustomMeasuredEnergiesMicroJoules(); + final long[] actualUid1 = bi.getUidStatsLocked(uid1).getCustomMeasuredEnergiesMicroJoules(); + final long[] actualUid2 = bi.getUidStatsLocked(uid2).getCustomMeasuredEnergiesMicroJoules(); + + assertNotNull(actualTotal); + assertNotNull(actualUid1); + assertNotNull(actualUid2); + assertEquals("Wrong total blame in bucket 0 for Case " + caseName, totalBlameA, - bi.getCustomMeasuredEnergyMicroJoules(0)); + actualTotal[0]); assertEquals("Wrong total blame in bucket 1 for Case " + caseName, totalBlameB, - bi.getCustomMeasuredEnergyMicroJoules(1)); + actualTotal[1]); - assertEquals("Wrong uid1 blame in bucket 0 for Case " + caseName, blame1A, - bi.getUidStatsLocked(uid1).getCustomMeasuredEnergyMicroJoules(0)); + assertEquals("Wrong uid1 blame in bucket 0 for Case " + caseName, blame1A, actualUid1[0]); - assertEquals("Wrong uid1 blame in bucket 1 for Case " + caseName, blame1B, - bi.getUidStatsLocked(uid1).getCustomMeasuredEnergyMicroJoules(1)); + assertEquals("Wrong uid1 blame in bucket 1 for Case " + caseName, blame1B, actualUid1[1]); - assertEquals("Wrong uid2 blame in bucket 0 for Case " + caseName, blame2A, - bi.getUidStatsLocked(uid2).getCustomMeasuredEnergyMicroJoules(0)); + assertEquals("Wrong uid2 blame in bucket 0 for Case " + caseName, blame2A, actualUid2[0]); - assertEquals("Wrong uid2 blame in bucket 1 for Case " + caseName, blame2B, - bi.getUidStatsLocked(uid2).getCustomMeasuredEnergyMicroJoules(1)); + assertEquals("Wrong uid2 blame in bucket 1 for Case " + caseName, blame2B, actualUid2[1]); } } diff --git a/core/tests/coretests/src/com/android/internal/power/MeasuredEnergyStatsTest.java b/core/tests/coretests/src/com/android/internal/power/MeasuredEnergyStatsTest.java index 1679774adb35..5fd5a7838c3a 100644 --- a/core/tests/coretests/src/com/android/internal/power/MeasuredEnergyStatsTest.java +++ b/core/tests/coretests/src/com/android/internal/power/MeasuredEnergyStatsTest.java @@ -405,6 +405,41 @@ public class MeasuredEnergyStatsTest { } @Test + public void testGetAccumulatedCustomBucketEnergies() { + final MeasuredEnergyStats stats + = new MeasuredEnergyStats(new boolean[NUMBER_STANDARD_ENERGY_BUCKETS], 3); + + stats.updateCustomBucket(0, 50, true); + stats.updateCustomBucket(1, 60, true); + stats.updateCustomBucket(2, 13, true); + stats.updateCustomBucket(1, 70, true); + + final long[] output = stats.getAccumulatedCustomBucketEnergies(); + assertEquals(3, output.length); + + assertEquals(50, output[0]); + assertEquals(60 + 70, output[1]); + assertEquals(13, output[2]); + } + + @Test + public void testGetAccumulatedCustomBucketEnergies_empty() { + final MeasuredEnergyStats stats + = new MeasuredEnergyStats(new boolean[NUMBER_STANDARD_ENERGY_BUCKETS], 0); + + final long[] output = stats.getAccumulatedCustomBucketEnergies(); + assertEquals(0, output.length); + } + + @Test + public void testGetNumberCustomEnergyBuckets() { + assertEquals(0, new MeasuredEnergyStats(new boolean[NUMBER_STANDARD_ENERGY_BUCKETS], 0) + .getNumberCustomEnergyBuckets()); + assertEquals(3, new MeasuredEnergyStats(new boolean[NUMBER_STANDARD_ENERGY_BUCKETS], 3) + .getNumberCustomEnergyBuckets()); + } + + @Test public void testReset() { final boolean[] supportedStandardBuckets = new boolean[NUMBER_STANDARD_ENERGY_BUCKETS]; final int numCustomBuckets = 2; |