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

Commit efd1e1ca authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Merge cherrypicks of ['googleplex-android-review.googlesource.com/30763903'] into 25Q1-release.

Change-Id: I6a6ffe0d51f51985d12c788af828951ee4a47171
parents 7b0fe34b 566a767f
Loading
Loading
Loading
Loading
+1 −5
Original line number Original line Diff line number Diff line
@@ -1101,9 +1101,6 @@ public final class BatteryStatsService extends IBatteryStats.Stub


    /** StatsPullAtomCallback for pulling BatteryUsageStats data. */
    /** StatsPullAtomCallback for pulling BatteryUsageStats data. */
    private class StatsPullAtomCallbackImpl implements StatsManager.StatsPullAtomCallback {
    private class StatsPullAtomCallbackImpl implements StatsManager.StatsPullAtomCallback {
        private static final long BATTERY_USAGE_STATS_PER_UID_MAX_STATS_AGE =
                TimeUnit.HOURS.toMillis(2);

        @Override
        @Override
        public int onPullAtom(int atomTag, List<StatsEvent> data) {
        public int onPullAtom(int atomTag, List<StatsEvent> data) {
            final BatteryUsageStats bus;
            final BatteryUsageStats bus;
@@ -1171,8 +1168,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
                            .setMinConsumedPowerThreshold(minConsumedPowerThreshold);
                            .setMinConsumedPowerThreshold(minConsumedPowerThreshold);


                    if (isBatteryUsageStatsAccumulationSupported()) {
                    if (isBatteryUsageStatsAccumulationSupported()) {
                        query.accumulated()
                        query.accumulated();
                                .setMaxStatsAgeMs(BATTERY_USAGE_STATS_PER_UID_MAX_STATS_AGE);
                    }
                    }


                    bus = getBatteryUsageStats(List.of(query.build())).get(0);
                    bus = getBatteryUsageStats(List.of(query.build())).get(0);
+17 −26
Original line number Original line Diff line number Diff line
@@ -195,22 +195,23 @@ public class BatteryUsageStatsProvider {
            mLastAccumulationMonotonicHistorySize = historySize;
            mLastAccumulationMonotonicHistorySize = historySize;
        }
        }


        // No need to store the accumulated stats asynchronously, as the entire accumulation
        handler.post(() -> accumulateBatteryUsageStats(stats));
        // operation is async
        handler.post(() -> accumulateBatteryUsageStats(stats, false));
    }
    }


    /**
    /**
     * Computes BatteryUsageStats for the period since the last accumulated stats were stored,
     * Computes BatteryUsageStats for the period since the last accumulated stats were stored,
     * adds them to the accumulated stats and asynchronously saves the result.
     * adds them to the accumulated stats and saves the result.
     */
     */
    public void accumulateBatteryUsageStats(BatteryStatsImpl stats) {
    public void accumulateBatteryUsageStats(BatteryStatsImpl stats) {
        accumulateBatteryUsageStats(stats, true);
    }

    private void accumulateBatteryUsageStats(BatteryStatsImpl stats, boolean storeAsync) {
        AccumulatedBatteryUsageStats accumulatedStats = loadAccumulatedBatteryUsageStats();
        AccumulatedBatteryUsageStats accumulatedStats = loadAccumulatedBatteryUsageStats();
        updateAccumulatedBatteryUsageStats(accumulatedStats, stats);

        final BatteryUsageStatsQuery query = new BatteryUsageStatsQuery.Builder()
                .setMaxStatsAgeMs(0)
                .includeProcessStateData()
                .includePowerStateData()
                .includeScreenStateData()
                .build();
        updateAccumulatedBatteryUsageStats(accumulatedStats, stats, query);


        PowerStatsSpan powerStatsSpan = new PowerStatsSpan(AccumulatedBatteryUsageStatsSection.ID);
        PowerStatsSpan powerStatsSpan = new PowerStatsSpan(AccumulatedBatteryUsageStatsSection.ID);
        powerStatsSpan.addSection(
        powerStatsSpan.addSection(
@@ -219,13 +220,8 @@ public class BatteryUsageStatsProvider {
                accumulatedStats.startWallClockTime,
                accumulatedStats.startWallClockTime,
                accumulatedStats.endMonotonicTime - accumulatedStats.startMonotonicTime);
                accumulatedStats.endMonotonicTime - accumulatedStats.startMonotonicTime);
        mMonotonicClock.write();
        mMonotonicClock.write();
        if (storeAsync) {
        mPowerStatsStore.storePowerStatsSpanAsync(powerStatsSpan,
        mPowerStatsStore.storePowerStatsSpanAsync(powerStatsSpan,
                accumulatedStats.builder::discard);
                accumulatedStats.builder::discard);
        } else {
            mPowerStatsStore.storePowerStatsSpan(powerStatsSpan);
            accumulatedStats.builder.discard();
        }
    }
    }


    /**
    /**
@@ -273,7 +269,7 @@ public class BatteryUsageStatsProvider {
        BatteryUsageStats batteryUsageStats;
        BatteryUsageStats batteryUsageStats;
        if ((query.getFlags()
        if ((query.getFlags()
                & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_ACCUMULATED) != 0) {
                & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_ACCUMULATED) != 0) {
            batteryUsageStats = getAccumulatedBatteryUsageStats(stats, query);
            batteryUsageStats = getAccumulatedBatteryUsageStats(stats, query, currentTimeMs);
        } else if (query.getAggregatedToTimestamp() == 0) {
        } else if (query.getAggregatedToTimestamp() == 0) {
            BatteryUsageStats.Builder builder = computeBatteryUsageStats(stats, query,
            BatteryUsageStats.Builder builder = computeBatteryUsageStats(stats, query,
                    query.getMonotonicStartTime(),
                    query.getMonotonicStartTime(),
@@ -292,13 +288,9 @@ public class BatteryUsageStatsProvider {
    }
    }


    private BatteryUsageStats getAccumulatedBatteryUsageStats(BatteryStatsImpl stats,
    private BatteryUsageStats getAccumulatedBatteryUsageStats(BatteryStatsImpl stats,
            BatteryUsageStatsQuery query) {
            BatteryUsageStatsQuery query, long currentTimeMs) {
        AccumulatedBatteryUsageStats accumulatedStats = loadAccumulatedBatteryUsageStats();
        AccumulatedBatteryUsageStats accumulatedStats = loadAccumulatedBatteryUsageStats();
        if (accumulatedStats.endMonotonicTime == MonotonicClock.UNDEFINED
        updateAccumulatedBatteryUsageStats(accumulatedStats, stats, query);
                || mMonotonicClock.monotonicTime() - accumulatedStats.endMonotonicTime
                > query.getMaxStatsAge()) {
            updateAccumulatedBatteryUsageStats(accumulatedStats, stats);
        }
        return accumulatedStats.builder.build();
        return accumulatedStats.builder.build();
    }
    }


@@ -329,7 +321,7 @@ public class BatteryUsageStatsProvider {
    }
    }


    private void updateAccumulatedBatteryUsageStats(AccumulatedBatteryUsageStats accumulatedStats,
    private void updateAccumulatedBatteryUsageStats(AccumulatedBatteryUsageStats accumulatedStats,
            BatteryStatsImpl stats) {
            BatteryStatsImpl stats, BatteryUsageStatsQuery query) {
        long startMonotonicTime = accumulatedStats.endMonotonicTime;
        long startMonotonicTime = accumulatedStats.endMonotonicTime;
        if (startMonotonicTime == MonotonicClock.UNDEFINED) {
        if (startMonotonicTime == MonotonicClock.UNDEFINED) {
            startMonotonicTime = stats.getMonotonicStartTime();
            startMonotonicTime = stats.getMonotonicStartTime();
@@ -341,7 +333,6 @@ public class BatteryUsageStatsProvider {
            accumulatedStats.builder = new BatteryUsageStats.Builder(
            accumulatedStats.builder = new BatteryUsageStats.Builder(
                    stats.getCustomEnergyConsumerNames(), true, true, true, 0);
                    stats.getCustomEnergyConsumerNames(), true, true, true, 0);
            accumulatedStats.startWallClockTime = stats.getStartClockTime();
            accumulatedStats.startWallClockTime = stats.getStartClockTime();
            accumulatedStats.startMonotonicTime = stats.getMonotonicStartTime();
            accumulatedStats.builder.setStatsStartTimestamp(accumulatedStats.startWallClockTime);
            accumulatedStats.builder.setStatsStartTimestamp(accumulatedStats.startWallClockTime);
        }
        }


@@ -351,7 +342,7 @@ public class BatteryUsageStatsProvider {
        accumulatedStats.builder.setStatsDuration(endWallClockTime - startMonotonicTime);
        accumulatedStats.builder.setStatsDuration(endWallClockTime - startMonotonicTime);


        mPowerAttributor.estimatePowerConsumption(accumulatedStats.builder, stats.getHistory(),
        mPowerAttributor.estimatePowerConsumption(accumulatedStats.builder, stats.getHistory(),
                startMonotonicTime, endMonotonicTime);
                startMonotonicTime, MonotonicClock.UNDEFINED);


        populateGeneralInfo(accumulatedStats.builder, stats);
        populateGeneralInfo(accumulatedStats.builder, stats);
    }
    }
+0 −4
Original line number Original line Diff line number Diff line
@@ -23,7 +23,6 @@ import android.util.SparseBooleanArray;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BatteryStatsHistory;
import com.android.internal.os.BatteryStatsHistory;
import com.android.internal.os.BatteryStatsHistoryIterator;
import com.android.internal.os.BatteryStatsHistoryIterator;
import com.android.internal.os.MonotonicClock;


import java.util.function.Consumer;
import java.util.function.Consumer;


@@ -170,9 +169,6 @@ public class PowerStatsAggregator {
                    }
                    }
                }
                }
            }
            }
            if (endTimeMs != MonotonicClock.UNDEFINED) {
                lastTime = endTimeMs;
            }
            if (lastTime > baseTime) {
            if (lastTime > baseTime) {
                mStats.setDuration(lastTime - baseTime);
                mStats.setDuration(lastTime - baseTime);
                mStats.finish(lastTime);
                mStats.finish(lastTime);
+77 −128
Original line number Original line Diff line number Diff line
@@ -36,7 +36,6 @@ import android.os.BatteryStats;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
import android.os.BatteryUsageStatsQuery;
import android.os.ConditionVariable;
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.Parcel;
import android.os.Parcel;
import android.os.Process;
import android.os.Process;
import android.os.UidBatteryConsumer;
import android.os.UidBatteryConsumer;
@@ -82,9 +81,8 @@ public class BatteryUsageStatsProviderTest {
                    .setAveragePower(PowerProfile.POWER_BATTERY_CAPACITY, 4000.0);
                    .setAveragePower(PowerProfile.POWER_BATTERY_CAPACITY, 4000.0);


    private MockClock mMockClock = mStatsRule.getMockClock();
    private MockClock mMockClock = mStatsRule.getMockClock();
    private MonotonicClock mMonotonicClock = mStatsRule.getMonotonicClock();
    private MonotonicClock mMonotonicClock = new MonotonicClock(666777, mMockClock);
    private Context mContext;
    private Context mContext;
    private PowerStatsStore mPowerStatsStore;


    @Before
    @Before
    public void setup() throws IOException {
    public void setup() throws IOException {
@@ -95,9 +93,6 @@ public class BatteryUsageStatsProviderTest {
        } else {
        } else {
            mContext = InstrumentationRegistry.getContext();
            mContext = InstrumentationRegistry.getContext();
        }
        }
        mPowerStatsStore = spy(new PowerStatsStore(
                new File(mStatsRule.getHistoryDir(), getClass().getSimpleName()),
                mStatsRule.getHandler()));
    }
    }


    @Test
    @Test
@@ -279,7 +274,10 @@ public class BatteryUsageStatsProviderTest {
        powerAttributor.setPowerComponentSupported(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT,
        powerAttributor.setPowerComponentSupported(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT,
                true);
                true);


        BatteryUsageStatsProvider provider = createBatteryUsageStatsProvider(0);
        BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(mContext,
                powerAttributor, mStatsRule.getPowerProfile(),
                mStatsRule.getCpuScalingPolicies(), mock(PowerStatsStore.class), 0, mMockClock,
                mMonotonicClock);


        return provider.getBatteryUsageStats(batteryStats, BatteryUsageStatsQuery.DEFAULT);
        return provider.getBatteryUsageStats(batteryStats, BatteryUsageStatsQuery.DEFAULT);
    }
    }
@@ -333,30 +331,30 @@ public class BatteryUsageStatsProviderTest {
        BatteryStats.HistoryItem item;
        BatteryStats.HistoryItem item;


        assertThat(item = iterator.next()).isNotNull();
        assertThat(item = iterator.next()).isNotNull();
        assertHistoryItem(batteryStats, item,
        assertHistoryItem(item,
                BatteryStats.HistoryItem.CMD_RESET, BatteryStats.HistoryItem.EVENT_NONE,
                BatteryStats.HistoryItem.CMD_RESET, BatteryStats.HistoryItem.EVENT_NONE,
                null, 0, 3_600_000, 90, 1_000_000);
                null, 0, 3_600_000, 90, 1_000_000);


        assertThat(item = iterator.next()).isNotNull();
        assertThat(item = iterator.next()).isNotNull();
        assertHistoryItem(batteryStats, item,
        assertHistoryItem(item,
                BatteryStats.HistoryItem.CMD_UPDATE, BatteryStats.HistoryItem.EVENT_NONE,
                BatteryStats.HistoryItem.CMD_UPDATE, BatteryStats.HistoryItem.EVENT_NONE,
                null, 0, 3_600_000, 90, 1_000_000);
                null, 0, 3_600_000, 90, 1_000_000);
        assertThat(item.states & BatteryStats.HistoryItem.STATE_CPU_RUNNING_FLAG).isNotEqualTo(0);
        assertThat(item.states & BatteryStats.HistoryItem.STATE_CPU_RUNNING_FLAG).isNotEqualTo(0);


        assertThat(item = iterator.next()).isNotNull();
        assertThat(item = iterator.next()).isNotNull();
        assertHistoryItem(batteryStats, item,
        assertHistoryItem(item,
                BatteryStats.HistoryItem.CMD_UPDATE, BatteryStats.HistoryItem.EVENT_NONE,
                BatteryStats.HistoryItem.CMD_UPDATE, BatteryStats.HistoryItem.EVENT_NONE,
                null, 0, 3_600_000, 90, 2_000_000);
                null, 0, 3_600_000, 90, 2_000_000);
        assertThat(item.states & BatteryStats.HistoryItem.STATE_CPU_RUNNING_FLAG).isEqualTo(0);
        assertThat(item.states & BatteryStats.HistoryItem.STATE_CPU_RUNNING_FLAG).isEqualTo(0);


        assertThat(item = iterator.next()).isNotNull();
        assertThat(item = iterator.next()).isNotNull();
        assertHistoryItem(batteryStats, item,
        assertHistoryItem(item,
                BatteryStats.HistoryItem.CMD_UPDATE,
                BatteryStats.HistoryItem.CMD_UPDATE,
                BatteryStats.HistoryItem.EVENT_ALARM | BatteryStats.HistoryItem.EVENT_FLAG_START,
                BatteryStats.HistoryItem.EVENT_ALARM | BatteryStats.HistoryItem.EVENT_FLAG_START,
                "foo", APP_UID, 3_600_000, 90, 3_000_000);
                "foo", APP_UID, 3_600_000, 90, 3_000_000);


        assertThat(item = iterator.next()).isNotNull();
        assertThat(item = iterator.next()).isNotNull();
        assertHistoryItem(batteryStats, item,
        assertHistoryItem(item,
                BatteryStats.HistoryItem.CMD_UPDATE,
                BatteryStats.HistoryItem.CMD_UPDATE,
                BatteryStats.HistoryItem.EVENT_ALARM | BatteryStats.HistoryItem.EVENT_FLAG_FINISH,
                BatteryStats.HistoryItem.EVENT_ALARM | BatteryStats.HistoryItem.EVENT_FLAG_FINISH,
                "foo", APP_UID, 3_600_000, 90, 3_001_000);
                "foo", APP_UID, 3_600_000, 90, 3_001_000);
@@ -443,15 +441,14 @@ public class BatteryUsageStatsProviderTest {
            assertThat(item.eventTag.string).startsWith(uid + " ");
            assertThat(item.eventTag.string).startsWith(uid + " ");
            assertThat(item.batteryChargeUah).isEqualTo(3_600_000);
            assertThat(item.batteryChargeUah).isEqualTo(3_600_000);
            assertThat(item.batteryLevel).isEqualTo(90);
            assertThat(item.batteryLevel).isEqualTo(90);
            assertThat(item.time).isEqualTo(batteryStats.getMonotonicStartTime() + 1_000_000);
            assertThat(item.time).isEqualTo((long) 1_000_000);
        }
        }


        assertThat(expectedUid).isEqualTo(200);
        assertThat(expectedUid).isEqualTo(200);
    }
    }


    private void assertHistoryItem(MockBatteryStatsImpl batteryStats, BatteryStats.HistoryItem item,
    private void assertHistoryItem(BatteryStats.HistoryItem item, int command, int eventCode,
            int command, int eventCode, String tag, int uid, int batteryChargeUah, int batteryLevel,
            String tag, int uid, int batteryChargeUah, int batteryLevel, long elapsedTimeMs) {
            long elapsedTimeMs) {
        assertThat(item.cmd).isEqualTo(command);
        assertThat(item.cmd).isEqualTo(command);
        assertThat(item.eventCode).isEqualTo(eventCode);
        assertThat(item.eventCode).isEqualTo(eventCode);
        if (tag == null) {
        if (tag == null) {
@@ -463,7 +460,7 @@ public class BatteryUsageStatsProviderTest {
        assertThat(item.batteryChargeUah).isEqualTo(batteryChargeUah);
        assertThat(item.batteryChargeUah).isEqualTo(batteryChargeUah);
        assertThat(item.batteryLevel).isEqualTo(batteryLevel);
        assertThat(item.batteryLevel).isEqualTo(batteryLevel);


        assertThat(item.time).isEqualTo(batteryStats.getMonotonicStartTime() + elapsedTimeMs);
        assertThat(item.time).isEqualTo(elapsedTimeMs);
    }
    }


    @Test
    @Test
@@ -569,66 +566,38 @@ public class BatteryUsageStatsProviderTest {


        assertThat(stats.getStatsStartTimestamp()).isEqualTo(5 * MINUTE_IN_MS);
        assertThat(stats.getStatsStartTimestamp()).isEqualTo(5 * MINUTE_IN_MS);
        assertThat(stats.getStatsEndTimestamp()).isEqualTo(55 * MINUTE_IN_MS);
        assertThat(stats.getStatsEndTimestamp()).isEqualTo(55 * MINUTE_IN_MS);
        assertBatteryConsumer(stats, 180.0, (10 + 20) * MINUTE_IN_MS);
        assertThat(stats.getAggregateBatteryConsumer(
        assertBatteryConsumer(stats, APP_UID, 180.0, (10 + 20) * MINUTE_IN_MS);
                        BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
                .getConsumedPower(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
                .isWithin(0.0001)
                .of(180.0);  // 360 mA * 0.5 hours
        assertThat(stats.getAggregateBatteryConsumer(
                        BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
                .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
                .isEqualTo((10 + 20) * MINUTE_IN_MS);
        final UidBatteryConsumer uidBatteryConsumer = stats.getUidBatteryConsumers().stream()
                .filter(uid -> uid.getUid() == APP_UID).findFirst().get();
        assertThat(uidBatteryConsumer
                .getConsumedPower(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
                .isWithin(0.1)
                .of(180.0);


        stats.close();
        stats.close();
    }
    }


    @Test
    @Test
    public void accumulateBatteryUsageStats() throws Throwable {
    public void accumulateBatteryUsageStats() throws Throwable {
        MockBatteryStatsImpl batteryStats = mStatsRule.getBatteryStats();
        accumulateBatteryUsageStats(10000000, 1);
        accumulateBatteryUsageStats(batteryStats, 10000000, 0);
        // Accumulate every 200 bytes of battery history
        // Accumulate every 200 bytes of battery history
        accumulateBatteryUsageStats(batteryStats, 200, 2);
        accumulateBatteryUsageStats(200, 2);
        accumulateBatteryUsageStats(batteryStats, 50, 4);
        accumulateBatteryUsageStats(50, 5);
        // Accumulate on every invocation of accumulateBatteryUsageStats
        // Accumulate on every invocation of accumulateBatteryUsageStats
        accumulateBatteryUsageStats(batteryStats, 0, 7);
        accumulateBatteryUsageStats(0, 7);
    }

    @Test
    public void getAccumulatedBatteryUsageStats() throws Throwable {
        MockBatteryStatsImpl batteryStats = mStatsRule.getBatteryStats();

        // Only accumulate the first 25 minutes
        accumulateBatteryUsageStats(batteryStats, 200, 1);

        BatteryUsageStatsProvider batteryUsageStatsProvider = createBatteryUsageStatsProvider(200);

        // At this point the last stored accumulated stats are `115 - 30 = 85` minutes old
        BatteryUsageStats stats = batteryUsageStatsProvider.getBatteryUsageStats(batteryStats,
                new BatteryUsageStatsQuery.Builder()
                        .accumulated()
                        .setMaxStatsAgeMs(90 * MINUTE_IN_MS)
                        .build());

        assertThat(stats.getStatsStartTimestamp()).isEqualTo(5 * MINUTE_IN_MS);
        assertThat(stats.getStatsEndTimestamp()).isEqualTo(30 * MINUTE_IN_MS);
        assertBatteryConsumer(stats, 60.0, 10 * MINUTE_IN_MS);
        assertBatteryConsumer(stats, APP_UID, 60.0, 10 * MINUTE_IN_MS);

        stats.close();

        // Now force the usage stats to catch up to the current time
        stats = batteryUsageStatsProvider.getBatteryUsageStats(batteryStats,
                new BatteryUsageStatsQuery.Builder()
                        .accumulated()
                        .setMaxStatsAgeMs(5 * MINUTE_IN_MS)
                        .build());

        assertThat(stats.getStatsStartTimestamp()).isEqualTo(5 * MINUTE_IN_MS);
        assertThat(stats.getStatsEndTimestamp()).isEqualTo(115 * MINUTE_IN_MS);
        assertBatteryConsumer(stats, 360.0, 60 * MINUTE_IN_MS);
        assertBatteryConsumer(stats, APP_UID, 360.0, 60 * MINUTE_IN_MS);

        stats.close();
    }
    }


    private void accumulateBatteryUsageStats(MockBatteryStatsImpl batteryStatsImpl,
    private void accumulateBatteryUsageStats(int accumulatedBatteryUsageStatsSpanSize,
            int accumulatedBatteryUsageStatsSpanSize, int expectedNumberOfUpdates)
            int expectedNumberOfUpdates) throws Throwable {
            throws Throwable {
        BatteryStatsImpl batteryStats = spy(mStatsRule.getBatteryStats());
        Handler handler = mStatsRule.getHandler();
        MockBatteryStatsImpl batteryStats = spy(batteryStatsImpl);
        // Note - these two are in microseconds
        // Note - these two are in microseconds
        when(batteryStats.computeBatteryTimeRemaining(anyLong())).thenReturn(111_000L);
        when(batteryStats.computeBatteryTimeRemaining(anyLong())).thenReturn(111_000L);
        when(batteryStats.computeChargeTimeRemaining(anyLong())).thenReturn(777_000L);
        when(batteryStats.computeChargeTimeRemaining(anyLong())).thenReturn(777_000L);
@@ -641,76 +610,82 @@ public class BatteryUsageStatsProviderTest {
            batteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
            batteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
        }
        }


        mPowerStatsStore.reset();
        PowerStatsStore powerStatsStore = spy(new PowerStatsStore(
                new File(mStatsRule.getHistoryDir(), getClass().getSimpleName()),
                mStatsRule.getHandler()));
        powerStatsStore.reset();


        int[] count = new int[1];
        int[] count = new int[1];
        doAnswer(inv -> {
        doAnswer(inv -> {
            count[0]++;
            count[0]++;
            return inv.callRealMethod();
            return null;
        }).when(mPowerStatsStore).storePowerStatsSpan(any(PowerStatsSpan.class));
        }).when(powerStatsStore).storePowerStatsSpan(any(PowerStatsSpan.class));


        BatteryUsageStatsProvider batteryUsageStatsProvider = createBatteryUsageStatsProvider(
        MultiStatePowerAttributor powerAttributor = new MultiStatePowerAttributor(mContext,
                accumulatedBatteryUsageStatsSpanSize);
                powerStatsStore, mStatsRule.getPowerProfile(), mStatsRule.getCpuScalingPolicies(),
                () -> 3500);
        for (int powerComponentId = 0; powerComponentId < BatteryConsumer.POWER_COMPONENT_COUNT;
                powerComponentId++) {
            powerAttributor.setPowerComponentSupported(powerComponentId, true);
        }
        powerAttributor.setPowerComponentSupported(BatteryConsumer.POWER_COMPONENT_ANY, true);

        BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(mContext,
                powerAttributor, mStatsRule.getPowerProfile(),
                mStatsRule.getCpuScalingPolicies(), powerStatsStore,
                accumulatedBatteryUsageStatsSpanSize, mMockClock, mMonotonicClock);


        batteryUsageStatsProvider.accumulateBatteryUsageStatsAsync(batteryStats, handler);
        provider.accumulateBatteryUsageStatsAsync(batteryStats, mStatsRule.getHandler());


        setTime(10 * MINUTE_IN_MS);
        synchronized (batteryStats) {
        synchronized (batteryStats) {
            batteryStats.noteFlashlightOnLocked(APP_UID,
            batteryStats.noteFlashlightOnLocked(APP_UID,
                    10 * MINUTE_IN_MS, 10 * MINUTE_IN_MS);
                    10 * MINUTE_IN_MS, 10 * MINUTE_IN_MS);
        }
        }


        batteryUsageStatsProvider.accumulateBatteryUsageStatsAsync(batteryStats, handler);
        provider.accumulateBatteryUsageStatsAsync(batteryStats, mStatsRule.getHandler());


        setTime(20 * MINUTE_IN_MS);
        synchronized (batteryStats) {
        synchronized (batteryStats) {
            batteryStats.noteFlashlightOffLocked(APP_UID,
            batteryStats.noteFlashlightOffLocked(APP_UID,
                    20 * MINUTE_IN_MS, 20 * MINUTE_IN_MS);
                    20 * MINUTE_IN_MS, 20 * MINUTE_IN_MS);
        }
        }


        batteryUsageStatsProvider.accumulateBatteryUsageStatsAsync(batteryStats, handler);
        provider.accumulateBatteryUsageStatsAsync(batteryStats, mStatsRule.getHandler());


        setTime(30 * MINUTE_IN_MS);
        synchronized (batteryStats) {
        synchronized (batteryStats) {
            batteryStats.noteFlashlightOnLocked(APP_UID,
            batteryStats.noteFlashlightOnLocked(APP_UID,
                    30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS);
                    30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS);
        }
        }


        batteryUsageStatsProvider.accumulateBatteryUsageStatsAsync(batteryStats, handler);
        provider.accumulateBatteryUsageStatsAsync(batteryStats, mStatsRule.getHandler());

        // Make sure the accumulated stats are computed and saved before generating more history
        mStatsRule.waitForBackgroundThread();


        setTime(50 * MINUTE_IN_MS);
        synchronized (batteryStats) {
        synchronized (batteryStats) {
            batteryStats.noteFlashlightOffLocked(APP_UID,
            batteryStats.noteFlashlightOffLocked(APP_UID,
                    50 * MINUTE_IN_MS, 50 * MINUTE_IN_MS);
                    50 * MINUTE_IN_MS, 50 * MINUTE_IN_MS);
        }
        }
        setTime(55 * MINUTE_IN_MS);
        setTime(55 * MINUTE_IN_MS);


        batteryUsageStatsProvider.accumulateBatteryUsageStatsAsync(batteryStats, handler);
        provider.accumulateBatteryUsageStatsAsync(batteryStats, mStatsRule.getHandler());


        // This section has not been saved yet, but should be added to the accumulated totals
        // This section has not been saved yet, but should be added to the accumulated totals
        setTime(80 * MINUTE_IN_MS);
        synchronized (batteryStats) {
        synchronized (batteryStats) {
            batteryStats.noteFlashlightOnLocked(APP_UID,
            batteryStats.noteFlashlightOnLocked(APP_UID,
                    80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS);
                    80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS);
        }
        }


        batteryUsageStatsProvider.accumulateBatteryUsageStatsAsync(batteryStats, handler);
        provider.accumulateBatteryUsageStatsAsync(batteryStats, mStatsRule.getHandler());


        setTime(110 * MINUTE_IN_MS);
        synchronized (batteryStats) {
        synchronized (batteryStats) {
            batteryStats.noteFlashlightOffLocked(APP_UID,
            batteryStats.noteFlashlightOffLocked(APP_UID,
                    110 * MINUTE_IN_MS, 110 * MINUTE_IN_MS);
                    110 * MINUTE_IN_MS, 110 * MINUTE_IN_MS);
        }
        }
        setTime(115 * MINUTE_IN_MS);
        setTime(115 * MINUTE_IN_MS);


        batteryUsageStatsProvider.accumulateBatteryUsageStatsAsync(batteryStats, handler);
        // Pick up the remainder of battery history that has not yet been accumulated
        provider.accumulateBatteryUsageStats(batteryStats);


        mStatsRule.waitForBackgroundThread();
        mStatsRule.waitForBackgroundThread();


        BatteryUsageStats stats = batteryUsageStatsProvider.getBatteryUsageStats(batteryStats,
        BatteryUsageStats stats = provider.getBatteryUsageStats(batteryStats,
                new BatteryUsageStatsQuery.Builder().accumulated().build());
                new BatteryUsageStatsQuery.Builder().accumulated().build());


        assertThat(stats.getStatsStartTimestamp()).isEqualTo(5 * MINUTE_IN_MS);
        assertThat(stats.getStatsStartTimestamp()).isEqualTo(5 * MINUTE_IN_MS);
@@ -721,55 +696,29 @@ public class BatteryUsageStatsProviderTest {
        assertThat(stats.getBatteryCapacity()).isEqualTo(4000);  // from PowerProfile
        assertThat(stats.getBatteryCapacity()).isEqualTo(4000);  // from PowerProfile


        // Total: 10 + 20 + 30 = 60
        // Total: 10 + 20 + 30 = 60
        assertBatteryConsumer(stats, 360.0, 60 * MINUTE_IN_MS);
        assertThat(stats.getAggregateBatteryConsumer(
        assertBatteryConsumer(stats, APP_UID, 360.0, 60 * MINUTE_IN_MS);
                        BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
        stats.close();

        mStatsRule.waitForBackgroundThread();

        assertThat(count[0]).isEqualTo(expectedNumberOfUpdates);
    }

    private BatteryUsageStatsProvider createBatteryUsageStatsProvider(
            int accumulatedBatteryUsageStatsSpanSize) {
        MultiStatePowerAttributor powerAttributor = new MultiStatePowerAttributor(mContext,
                mPowerStatsStore, mStatsRule.getPowerProfile(), mStatsRule.getCpuScalingPolicies(),
                () -> 3500);
        for (int powerComponentId = 0; powerComponentId < BatteryConsumer.POWER_COMPONENT_COUNT;
                powerComponentId++) {
            powerAttributor.setPowerComponentSupported(powerComponentId, true);
        }
        powerAttributor.setPowerComponentSupported(BatteryConsumer.POWER_COMPONENT_ANY, true);

        return new BatteryUsageStatsProvider(mContext, powerAttributor,
                mStatsRule.getPowerProfile(), mStatsRule.getCpuScalingPolicies(), mPowerStatsStore,
                accumulatedBatteryUsageStatsSpanSize, mMockClock, mMonotonicClock);
    }

    private static void assertBatteryConsumer(BatteryUsageStats stats, double expectedPowerMah,
            long expectedDurationMs) {
        AggregateBatteryConsumer aggregatedConsumer = stats.getAggregateBatteryConsumer(
                BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
        assertThat(aggregatedConsumer
                .getConsumedPower(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
                .getConsumedPower(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
                .isWithin(0.0001)
                .isWithin(0.0001)
                .of(expectedPowerMah);
                .of(360.0);  // 360 mA * 1.0 hour
        assertThat(aggregatedConsumer
        assertThat(stats.getAggregateBatteryConsumer(
                        BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
                .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
                .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
                .isEqualTo(expectedDurationMs);
                .isEqualTo(60 * MINUTE_IN_MS);
    }


    private static void assertBatteryConsumer(BatteryUsageStats stats, int uid,
            double expectedPowerMah, long expectedDurationMs) {
        final UidBatteryConsumer uidBatteryConsumer = stats.getUidBatteryConsumers().stream()
        final UidBatteryConsumer uidBatteryConsumer = stats.getUidBatteryConsumers().stream()
                .filter(u -> u.getUid() == uid).findFirst().get();
                .filter(uid -> uid.getUid() == APP_UID).findFirst().get();
        assertThat(uidBatteryConsumer
        assertThat(uidBatteryConsumer
                .getConsumedPower(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
                .getConsumedPower(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
                .isWithin(0.1)
                .isWithin(0.1)
                .of(expectedPowerMah);
                .of(360.0);
        assertThat(uidBatteryConsumer
        assertThat(uidBatteryConsumer
                .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
                .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
                .isEqualTo(expectedDurationMs);
                .isEqualTo(60 * MINUTE_IN_MS);

        assertThat(count[0]).isEqualTo(expectedNumberOfUpdates);

        stats.close();
    }
    }


    private void setTime(long timeMs) {
    private void setTime(long timeMs) {
+1 −7
Original line number Original line Diff line number Diff line
@@ -41,7 +41,6 @@ import android.util.SparseArray;
import android.util.Xml;
import android.util.Xml;


import com.android.internal.os.CpuScalingPolicies;
import com.android.internal.os.CpuScalingPolicies;
import com.android.internal.os.MonotonicClock;
import com.android.internal.os.PowerProfile;
import com.android.internal.os.PowerProfile;
import com.android.internal.power.EnergyConsumerStats;
import com.android.internal.power.EnergyConsumerStats;


@@ -66,7 +65,6 @@ public class BatteryUsageStatsRule implements TestRule {


    private final PowerProfile mPowerProfile;
    private final PowerProfile mPowerProfile;
    private final MockClock mMockClock = new MockClock();
    private final MockClock mMockClock = new MockClock();
    private final MonotonicClock mMonotonicClock = new MonotonicClock(666777, mMockClock);
    private String mTestName;
    private String mTestName;
    private boolean mCreateTempDirectory;
    private boolean mCreateTempDirectory;
    private File mHistoryDir;
    private File mHistoryDir;
@@ -120,7 +118,7 @@ public class BatteryUsageStatsRule implements TestRule {
            clearDirectory();
            clearDirectory();
        }
        }
        mBatteryStats = new MockBatteryStatsImpl(mBatteryStatsConfigBuilder.build(),
        mBatteryStats = new MockBatteryStatsImpl(mBatteryStatsConfigBuilder.build(),
                mMockClock, mMonotonicClock, mHistoryDir, mHandler, new PowerStatsUidResolver());
                mMockClock, mHistoryDir, mHandler, new PowerStatsUidResolver());
        mBatteryStats.setPowerProfile(mPowerProfile);
        mBatteryStats.setPowerProfile(mPowerProfile);
        mBatteryStats.setCpuScalingPolicies(new CpuScalingPolicies(mCpusByPolicy, mFreqsByPolicy));
        mBatteryStats.setCpuScalingPolicies(new CpuScalingPolicies(mCpusByPolicy, mFreqsByPolicy));
        synchronized (mBatteryStats) {
        synchronized (mBatteryStats) {
@@ -146,10 +144,6 @@ public class BatteryUsageStatsRule implements TestRule {
        return mMockClock;
        return mMockClock;
    }
    }


    public MonotonicClock getMonotonicClock() {
        return mMonotonicClock;
    }

    public Handler getHandler() {
    public Handler getHandler() {
        return mHandler;
        return mHandler;
    }
    }
Loading