Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fa2a4f44 authored by Michael Wachenschwanz's avatar Michael Wachenschwanz
Browse files

Wipe BatteryStats on Custom Power Bucket change

If the supported OTHER EnergyConsumers change after a reboot, the
MeasuredEnergyStats from the reboot can no longer be considered valid.

Bug: 178504428
Test: atest FrameworksCoreTests:com.android.internal.power.MeasuredEnergyStatsTest
Change-Id: I2561c459c0b2a881661bd2913f9413a2cbd96abb
parent 720add59
Loading
Loading
Loading
Loading
+17 −7
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import com.android.internal.annotations.VisibleForTesting;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;

/**
 * Tracks the measured charge consumption of various subsystems according to their
@@ -96,8 +97,10 @@ public class MeasuredEnergyStats {
     * supportedStandardBuckets must be of size {@link #NUMBER_STANDARD_POWER_BUCKETS}.
     * numCustomBuckets >= 0 is the number of (non-standard) custom power buckets on the device.
     */
    public MeasuredEnergyStats(boolean[] supportedStandardBuckets, String[] customBucketNames) {
        final int numTotalBuckets = NUMBER_STANDARD_POWER_BUCKETS + customBucketNames.length;
    public MeasuredEnergyStats(@NonNull boolean[] supportedStandardBuckets,
            @Nullable String[] customBucketNames) {
        mCustomBucketNames = customBucketNames == null ? new String[0] : customBucketNames;
        final int numTotalBuckets = NUMBER_STANDARD_POWER_BUCKETS + mCustomBucketNames.length;
        mAccumulatedChargeMicroCoulomb = new long[numTotalBuckets];
        // Initialize to all zeros where supported, otherwise POWER_DATA_UNAVAILABLE.
        // All custom buckets are, by definition, supported, so their values stay at 0.
@@ -106,7 +109,6 @@ public class MeasuredEnergyStats {
                mAccumulatedChargeMicroCoulomb[stdBucket] = POWER_DATA_UNAVAILABLE;
            }
        }
        mCustomBucketNames = customBucketNames;
    }

    /**
@@ -431,14 +433,22 @@ public class MeasuredEnergyStats {

    /** Check if the supported power buckets are precisely those given. */
    public boolean isSupportEqualTo(
            @NonNull boolean[] queriedStandardBuckets, String[] customBucketNames) {
            @NonNull boolean[] queriedStandardBuckets, @Nullable String[] customBucketNames) {
        if (customBucketNames == null) {
            //In practice customBucketNames should never be null, but sanitize it just to be sure.
            customBucketNames = new String[0];
        }

        final int numBuckets = getNumberOfIndices();
        // TODO(b/178504428): Detect whether custom buckets have changed qualitatively, not just
        //                    quantitatively, and treat as mismatch if so.
        if (numBuckets != NUMBER_STANDARD_POWER_BUCKETS + customBucketNames.length) {
        final int numCustomBuckets = customBucketNames == null ? 0 : customBucketNames.length;
        if (numBuckets != NUMBER_STANDARD_POWER_BUCKETS + numCustomBuckets) {
            return false;
        }

        if (!Arrays.equals(mCustomBucketNames, customBucketNames)) {
            return false;
        }

        for (int stdBucket = 0; stdBucket < NUMBER_STANDARD_POWER_BUCKETS; stdBucket++) {
            if (isStandardBucketSupported(stdBucket) != queriedStandardBuckets[stdBucket]) {
                return false;
+80 −0
Original line number Diff line number Diff line
@@ -499,4 +499,84 @@ public class MeasuredEnergyStatsTest {
        assertEquals(exp, MeasuredEnergyStats.getDisplayPowerBucket(Display.STATE_DOZE));
        assertEquals(exp, MeasuredEnergyStats.getDisplayPowerBucket(Display.STATE_DOZE_SUSPEND));
    }

    /** Test MeasuredEnergyStats#isSupportEqualTo */
    @Test
    public void testIsSupportEqualTo() {
        final boolean[] supportedStandardBuckets = new boolean[NUMBER_STANDARD_POWER_BUCKETS];
        Arrays.fill(supportedStandardBuckets, true);
        final String[] customBucketNames = {"A", "B"};

        final MeasuredEnergyStats stats =
                new MeasuredEnergyStats(supportedStandardBuckets.clone(),
                        customBucketNames.clone());

        assertTrue(
                "All standard and custom bucket supports match",
                stats.isSupportEqualTo(supportedStandardBuckets, customBucketNames));

        boolean[] differentSupportedStandardBuckets = supportedStandardBuckets.clone();
        differentSupportedStandardBuckets[0] = !differentSupportedStandardBuckets[0];
        assertFalse(
                "Standard bucket support mismatch",
                stats.isSupportEqualTo(differentSupportedStandardBuckets, customBucketNames));

        assertFalse(
                "Custom bucket support mismatch",
                stats.isSupportEqualTo(supportedStandardBuckets, new String[]{"C", "B"}));

        assertFalse(
                "Fewer custom buckets supported",
                stats.isSupportEqualTo(supportedStandardBuckets, new String[]{"A"}));

        assertFalse(
                "More custom bucket supported",
                stats.isSupportEqualTo(supportedStandardBuckets, new String[]{"A", "B", "C"}));

        assertFalse(
                "Custom bucket support order changed",
                stats.isSupportEqualTo(supportedStandardBuckets, new String[]{"B", "A"}));
    }

    /** Test MeasuredEnergyStats#isSupportEqualTo when holding a null array of custom buckets */
    @Test
    public void testIsSupportEqualTo_nullCustomBuckets() {
        final boolean[] supportedStandardBuckets = new boolean[NUMBER_STANDARD_POWER_BUCKETS];

        final MeasuredEnergyStats stats =
                new MeasuredEnergyStats(supportedStandardBuckets.clone(), null);

        assertTrue(
                "Null custom bucket name lists should match",
                stats.isSupportEqualTo(supportedStandardBuckets, null));

        assertTrue(
                "Null and empty custom buckets should match",
                stats.isSupportEqualTo(supportedStandardBuckets, new String[0]));

        assertFalse(
                "Null custom buckets should not match populated list",
                stats.isSupportEqualTo(supportedStandardBuckets, new String[]{"A", "B"}));
    }

    /** Test MeasuredEnergyStats#isSupportEqualTo when holding an empty array of custom buckets */
    @Test
    public void testIsSupportEqualTo_emptyCustomBuckets() {
        final boolean[] supportedStandardBuckets = new boolean[NUMBER_STANDARD_POWER_BUCKETS];

        final MeasuredEnergyStats stats =
                new MeasuredEnergyStats(supportedStandardBuckets.clone(), new String[0]);

        assertTrue(
                "Empty custom buckets should match",
                stats.isSupportEqualTo(supportedStandardBuckets, new String[0]));

        assertTrue(
                "Empty and null custom buckets should match",
                stats.isSupportEqualTo(supportedStandardBuckets, null));

        assertFalse(
                "Empty custom buckets should not match populated list",
                stats.isSupportEqualTo(supportedStandardBuckets, new String[]{"A", "B"}));
    }
}