diff options
| author | 2024-07-16 22:55:57 +0000 | |
|---|---|---|
| committer | 2024-07-16 22:55:57 +0000 | |
| commit | d08a8dd79528090362fe9e584d9015dc00ffdecf (patch) | |
| tree | ba5be02cf84cee1d3cd08036cbc59fd2d66fde1c | |
| parent | d2715b13c06ec5fb6760537556b12da38bc46092 (diff) | |
| parent | 689b7d58e88c3e909e4edc79086100cab7c285ce (diff) | |
Merge "Add test for BatteryUsageStatsPerUid atom" into main
| -rw-r--r-- | core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp | 30 | ||||
| -rw-r--r-- | core/tests/batterystatstests/BatteryUsageStatsProtoTests/AndroidManifest.xml | 28 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/BatteryStatsService.java | 56 | ||||
| -rw-r--r-- | services/tests/powerstatstests/Android.bp | 1 | ||||
| -rw-r--r-- | services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsAtomTest.java (renamed from core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java) | 263 |
5 files changed, 294 insertions, 84 deletions
diff --git a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp deleted file mode 100644 index 1fb5f2c0789b..000000000000 --- a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp +++ /dev/null @@ -1,30 +0,0 @@ -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -android_test { - name: "BatteryUsageStatsProtoTests", - srcs: ["src/**/*.java"], - - static_libs: [ - "androidx.test.rules", - "junit", - "mockito-target-minus-junit4", - "platform-test-annotations", - "platformprotosnano", - "statsdprotolite", - "truth", - ], - - libs: ["android.test.runner"], - - platform_apis: true, - certificate: "platform", - - test_suites: ["device-tests"], -} diff --git a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/AndroidManifest.xml b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/AndroidManifest.xml deleted file mode 100644 index 9128dca2080b..000000000000 --- a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/AndroidManifest.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ Copyright (C) 2021 The Android Open Source Project - ~ - ~ Licensed under the Apache License, Version 2.0 (the "License"); - ~ you may not use this file except in compliance with the License. - ~ You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, software - ~ distributed under the License is distributed on an "AS IS" BASIS, - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ~ See the License for the specific language governing permissions and - ~ limitations under the License. - --> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.frameworks.core.batteryusagestatsprototests"> - - <uses-permission android:name="android.permission.BATTERY_STATS"/> - - <instrumentation - android:name="androidx.test.runner.AndroidJUnitRunner" - android:targetPackage="com.android.frameworks.core.batteryusagestatsprototests" - android:label="BatteryUsageStats Proto Tests" /> - -</manifest> diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 67985efcd7bc..092ee16f3342 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -102,6 +102,7 @@ import android.util.StatsEvent; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IBatteryStats; import com.android.internal.os.BinderCallsStats; import com.android.internal.os.Clock; @@ -1191,7 +1192,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub .setMinConsumedPowerThreshold(minConsumedPowerThreshold) .build(); bus = getBatteryUsageStats(List.of(query)).get(0); - return StatsPerUidLogger.logStats(bus, data); + return new StatsPerUidLogger(new FrameworkStatsLogger()).logStats(bus, data); } default: throw new UnsupportedOperationException("Unknown tagId=" + atomTag); @@ -1204,7 +1205,35 @@ public final class BatteryStatsService extends IBatteryStats.Stub } } - private static class StatsPerUidLogger { + public static class FrameworkStatsLogger { + /** + * Wrapper for the FrameworkStatsLog.buildStatsEvent method that makes it easier + * for mocking. + */ + @VisibleForTesting + public StatsEvent buildStatsEvent(long sessionStartTs, long sessionEndTs, + long sessionDuration, int sessionDischargePercentage, long sessionDischargeDuration, + int uid, @BatteryConsumer.ProcessState int processState, long timeInStateMillis, + String powerComponentName, float totalConsumedPowerMah, float powerComponentMah, + long powerComponentDurationMillis) { + return FrameworkStatsLog.buildStatsEvent( + FrameworkStatsLog.BATTERY_USAGE_STATS_PER_UID, + sessionStartTs, + sessionEndTs, + sessionDuration, + sessionDischargePercentage, + sessionDischargeDuration, + uid, + processState, + timeInStateMillis, + powerComponentName, + totalConsumedPowerMah, + powerComponentMah, + powerComponentDurationMillis); + } + } + + public static class StatsPerUidLogger { private static final int STATSD_METRIC_MAX_DIMENSIONS_COUNT = 3000; @@ -1224,7 +1253,18 @@ public final class BatteryStatsService extends IBatteryStats.Stub long dischargeDuration) {} ; - static int logStats(BatteryUsageStats bus, List<StatsEvent> data) { + private final FrameworkStatsLogger mFrameworkStatsLogger; + + public StatsPerUidLogger(FrameworkStatsLogger frameworkStatsLogger) { + mFrameworkStatsLogger = frameworkStatsLogger; + } + + /** + * Generates StatsEvents for the supplied battery usage stats and adds them to + * the supplied list. + */ + @VisibleForTesting + public int logStats(BatteryUsageStats bus, List<StatsEvent> data) { final SessionInfo sessionInfo = new SessionInfo( bus.getStatsStartTimestamp(), @@ -1340,7 +1380,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub return StatsManager.PULL_SUCCESS; } - private static boolean addStatsForPredefinedComponent( + private boolean addStatsForPredefinedComponent( List<StatsEvent> data, SessionInfo sessionInfo, int uid, @@ -1380,7 +1420,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub powerComponentDurationMillis); } - private static boolean addStatsForCustomComponent( + private boolean addStatsForCustomComponent( List<StatsEvent> data, SessionInfo sessionInfo, int uid, @@ -1422,7 +1462,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub * Returns true on success and false if reached max atoms capacity and no more atoms should * be added */ - private static boolean addStatsAtom( + private boolean addStatsAtom( List<StatsEvent> data, SessionInfo sessionInfo, int uid, @@ -1432,9 +1472,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub float totalConsumedPowerMah, float powerComponentMah, long powerComponentDurationMillis) { - data.add( - FrameworkStatsLog.buildStatsEvent( - FrameworkStatsLog.BATTERY_USAGE_STATS_PER_UID, + data.add(mFrameworkStatsLogger.buildStatsEvent( sessionInfo.startTs(), sessionInfo.endTs(), sessionInfo.duration(), diff --git a/services/tests/powerstatstests/Android.bp b/services/tests/powerstatstests/Android.bp index f2b4136c51ed..b2a5b02c49e1 100644 --- a/services/tests/powerstatstests/Android.bp +++ b/services/tests/powerstatstests/Android.bp @@ -59,6 +59,7 @@ android_ravenwood_test { name: "PowerStatsTestsRavenwood", static_libs: [ "services.core", + "platformprotosnano", "coretests-aidl", "ravenwood-junit", "truth", diff --git a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsAtomTest.java index ac1f7d0e345f..62efbc3cfa35 100644 --- a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsAtomTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.android.internal.os; +package com.android.server.power.stats; import static android.os.BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE; @@ -23,39 +23,262 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import android.os.AggregateBatteryConsumer; import android.os.BatteryConsumer; import android.os.BatteryUsageStats; +import android.os.Process; import android.os.UidBatteryConsumer; import android.os.nano.BatteryUsageStatsAtomsProto; import android.os.nano.BatteryUsageStatsAtomsProto.BatteryConsumerData.PowerComponentUsage; +import android.platform.test.ravenwood.RavenwoodRule; +import android.util.StatsEvent; import androidx.test.filters.SmallTest; +import com.android.server.am.BatteryStatsService; + import com.google.protobuf.nano.InvalidProtocolBufferNanoException; +import org.junit.Rule; import org.junit.Test; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; - @SmallTest -public class BatteryUsageStatsPulledTest { +public class BatteryUsageStatsAtomTest { + + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); private static final int UID_0 = 1000; private static final int UID_1 = 2000; private static final int UID_2 = 3000; private static final int UID_3 = 4000; - private static final int[] UID_USAGE_TIME_PROCESS_STATES = { - BatteryConsumer.PROCESS_STATE_FOREGROUND, - BatteryConsumer.PROCESS_STATE_BACKGROUND, - BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE - }; @Test - public void testGetStatsProto() { + public void testAtom_BatteryUsageStatsPerUid() { + final BatteryUsageStats bus = buildBatteryUsageStats(); + BatteryStatsService.FrameworkStatsLogger statsLogger = + mock(BatteryStatsService.FrameworkStatsLogger.class); + + List<StatsEvent> actual = new ArrayList<>(); + new BatteryStatsService.StatsPerUidLogger(statsLogger).logStats(bus, actual); + + // Device-wide totals + verify(statsLogger).buildStatsEvent( + 1000L, + 20000L, + 10000L, + 20, + 1234L, + Process.INVALID_UID, + BatteryConsumer.PROCESS_STATE_UNSPECIFIED, + 0L, + "cpu", + 30000.0f, + 20100.0f, + 20300L + ); + verify(statsLogger).buildStatsEvent( + 1000L, + 20000L, + 10000L, + 20, + 1234L, + Process.INVALID_UID, + BatteryConsumer.PROCESS_STATE_UNSPECIFIED, + 0L, + "camera", + 30000.0f, + 20150.0f, + 0L + ); + verify(statsLogger).buildStatsEvent( + 1000L, + 20000L, + 10000L, + 20, + 1234L, + Process.INVALID_UID, + BatteryConsumer.PROCESS_STATE_UNSPECIFIED, + 0L, + "CustomConsumer1", + 30000.0f, + 20200.0f, + 20400L + ); + + // Per-proc state estimates for UID_0 + verify(statsLogger).buildStatsEvent( + 1000L, + 20000L, + 10000L, + 20, + 1234L, + UID_0, + BatteryConsumer.PROCESS_STATE_UNSPECIFIED, + 0L, + "screen", + 1650.0f, + 300.0f, + 0L + ); + verify(statsLogger).buildStatsEvent( + 1000L, + 20000L, + 10000L, + 20, + 1234L, + UID_0, + BatteryConsumer.PROCESS_STATE_UNSPECIFIED, + 0L, + "cpu", + 1650.0f, + 400.0f, + 600L + ); + verify(statsLogger).buildStatsEvent( + 1000L, + 20000L, + 10000L, + 20, + 1234L, + UID_0, + BatteryConsumer.PROCESS_STATE_FOREGROUND, + 1000L, + "cpu", + 1650.0f, + 9100.0f, + 8100L + ); + verify(statsLogger).buildStatsEvent( + 1000L, + 20000L, + 10000L, + 20, + 1234L, + UID_0, + BatteryConsumer.PROCESS_STATE_BACKGROUND, + 2000L, + "cpu", + 1650.0f, + 9200.0f, + 8200L + ); + verify(statsLogger).buildStatsEvent( + 1000L, + 20000L, + 10000L, + 20, + 1234L, + UID_0, + BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE, + 0L, + "cpu", + 1650.0f, + 9300.0f, + 8400L + ); + verify(statsLogger).buildStatsEvent( + 1000L, + 20000L, + 10000L, + 20, + 1234L, + UID_0, + BatteryConsumer.PROCESS_STATE_CACHED, + 0L, + "cpu", + 1650.0f, + 9400.0f, + 0L + ); + verify(statsLogger).buildStatsEvent( + 1000L, + 20000L, + 10000L, + 20, + 1234L, + UID_0, + BatteryConsumer.PROCESS_STATE_FOREGROUND, + 1000L, + "CustomConsumer1", + 1650.0f, + 450.0f, + 0L + ); + verify(statsLogger).buildStatsEvent( + 1000L, + 20000L, + 10000L, + 20, + 1234L, + UID_0, + BatteryConsumer.PROCESS_STATE_BACKGROUND, + 2000L, + "CustomConsumer1", + 1650.0f, + 450.0f, + 0L + ); + verify(statsLogger).buildStatsEvent( + 1000L, + 20000L, + 10000L, + 20, + 1234L, + UID_0, + BatteryConsumer.PROCESS_STATE_FOREGROUND, + 1000L, + "CustomConsumer2", + 1650.0f, + 500.0f, + 800L + ); + verify(statsLogger).buildStatsEvent( + 1000L, + 20000L, + 10000L, + 20, + 1234L, + UID_0, + BatteryConsumer.PROCESS_STATE_BACKGROUND, + 2000L, + "CustomConsumer2", + 1650.0f, + 500.0f, + 800L + ); + + // Nothing for UID_1, because its power consumption is 0 + + // Only "screen" is populated for UID_2 + verify(statsLogger).buildStatsEvent( + 1000L, + 20000L, + 10000L, + 20, + 1234L, + UID_2, + BatteryConsumer.PROCESS_STATE_UNSPECIFIED, + 0L, + "screen", + 766.0f, + 766.0f, + 0L + ); + + verifyNoMoreInteractions(statsLogger); + } + + @Test + public void testAtom_BatteryUsageStatsAtomsProto() { final BatteryUsageStats bus = buildBatteryUsageStats(); final byte[] bytes = bus.getStatsProto(); BatteryUsageStatsAtomsProto proto; @@ -68,9 +291,7 @@ public class BatteryUsageStatsPulledTest { assertEquals(bus.getStatsStartTimestamp(), proto.sessionStartMillis); assertEquals(bus.getStatsEndTimestamp(), proto.sessionEndMillis); - assertEquals( - bus.getStatsEndTimestamp() - bus.getStatsStartTimestamp(), - proto.sessionDurationMillis); + assertEquals(10000, proto.sessionDurationMillis); assertEquals(bus.getDischargePercentage(), proto.sessionDischargePercentage); assertEquals(bus.getDischargeDurationMs(), proto.dischargeDurationMillis); @@ -90,8 +311,8 @@ public class BatteryUsageStatsPulledTest { final List<android.os.UidBatteryConsumer> uidConsumers = bus.getUidBatteryConsumers(); uidConsumers.sort((a, b) -> a.getUid() - b.getUid()); - final BatteryUsageStatsAtomsProto.UidBatteryConsumer[] uidConsumersProto - = proto.uidBatteryConsumers; + final BatteryUsageStatsAtomsProto.UidBatteryConsumer[] uidConsumersProto = + proto.uidBatteryConsumers; Arrays.sort(uidConsumersProto, (a, b) -> a.uid - b.uid); // UID_0 - After sorting, UID_0 should be in position 0 for both data structures @@ -186,6 +407,12 @@ public class BatteryUsageStatsPulledTest { } } + private static final int[] UID_USAGE_TIME_PROCESS_STATES = { + BatteryConsumer.PROCESS_STATE_FOREGROUND, + BatteryConsumer.PROCESS_STATE_BACKGROUND, + BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE + }; + private void assertSameUidBatteryConsumer( android.os.UidBatteryConsumer uidConsumer, BatteryUsageStatsAtomsProto.UidBatteryConsumer uidConsumerProto, @@ -195,10 +422,10 @@ public class BatteryUsageStatsPulledTest { assertEquals("Uid consumers had mismatched uids", uid, uidConsumer.getUid()); assertEquals("For uid " + uid, - uidConsumer.getTimeInStateMs(android.os.UidBatteryConsumer.STATE_FOREGROUND), + uidConsumer.getTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_FOREGROUND), uidConsumerProto.timeInForegroundMillis); assertEquals("For uid " + uid, - uidConsumer.getTimeInStateMs(android.os.UidBatteryConsumer.STATE_BACKGROUND), + uidConsumer.getTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_BACKGROUND), uidConsumerProto.timeInBackgroundMillis); for (int processState : UID_USAGE_TIME_PROCESS_STATES) { final long timeInStateMillis = uidConsumer.getTimeInProcessStateMs(processState); @@ -265,7 +492,9 @@ public class BatteryUsageStatsPulledTest { .setDischargePercentage(20) .setDischargedPowerRange(1000, 2000) .setDischargeDurationMs(1234) - .setStatsStartTimestamp(1000); + .setStatsStartTimestamp(1000) + .setStatsEndTimestamp(20000) + .setStatsDuration(10000); final UidBatteryConsumer.Builder uidBuilder = builder .getOrCreateUidBatteryConsumerBuilder(UID_0) .setPackageWithHighestDrain("myPackage0") |