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

Commit 906c9790 authored by ELIYAZ MOMIN's avatar ELIYAZ MOMIN Committed by Android (Google) Code Review
Browse files

Merge "Revert^2 "Add test for BatteryUsageStatsPerUid atom"" into main

parents d7a09ece 3d13e82d
Loading
Loading
Loading
Loading
+0 −30
Original line number Diff line number Diff line
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"],
}
+0 −28
Original line number Diff line number Diff line
<?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>
+47 −9
Original line number Diff line number Diff line
@@ -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(),
+1 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ android_ravenwood_test {
    name: "PowerStatsTestsRavenwood",
    static_libs: [
        "services.core",
        "platformprotosnano",
        "coretests-aidl",
        "ravenwood-junit",
        "truth",
+246 −17
Original line number Diff line number Diff line
@@ -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 = {

    @Test
    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,
            BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE
    };
                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 testGetStatsProto() {
    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")