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

Commit 0575637c authored by Michael Wachenschwanz's avatar Michael Wachenschwanz Committed by Android (Google) Code Review
Browse files

Merge "Add Power Model info to the BatteryUsageStats atom"

parents 582bfc69 cb02f0d9
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.os;
import android.annotation.NonNull;
import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
import android.util.proto.ProtoOutputStream;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -97,6 +98,19 @@ public final class AggregateBatteryConsumer extends BatteryConsumer {
        }
    }

    void writePowerComponentModelProto(@NonNull ProtoOutputStream proto) {
        for (int i = 0; i < POWER_COMPONENT_COUNT; i++) {
            final int powerModel = getPowerModel(i);
            if (powerModel == BatteryConsumer.POWER_MODEL_UNDEFINED) continue;

            final long token = proto.start(BatteryUsageStatsAtomsProto.COMPONENT_MODELS);
            proto.write(BatteryUsageStatsAtomsProto.PowerComponentModel.COMPONENT, i);
            proto.write(BatteryUsageStatsAtomsProto.PowerComponentModel.POWER_MODEL,
                    powerModelToProtoEnum(powerModel));
            proto.end(token);
        }
    }

    /**
     * Builder for DeviceBatteryConsumer.
     */
+15 −0
Original line number Diff line number Diff line
@@ -478,6 +478,21 @@ public abstract class BatteryConsumer {
        }
    }

    /**
     * Returns the equivalent PowerModel enum for the specified power model.
     * {@see BatteryUsageStatsAtomsProto.BatteryConsumerData.PowerComponentUsage.PowerModel}
     */
    public static int powerModelToProtoEnum(@BatteryConsumer.PowerModel int powerModel) {
        switch (powerModel) {
            case BatteryConsumer.POWER_MODEL_MEASURED_ENERGY:
                return BatteryUsageStatsAtomsProto.PowerComponentModel.MEASURED_ENERGY;
            case BatteryConsumer.POWER_MODEL_POWER_PROFILE:
                return BatteryUsageStatsAtomsProto.PowerComponentModel.POWER_PROFILE;
            default:
                return BatteryUsageStatsAtomsProto.PowerComponentModel.UNDEFINED;
        }
    }

    /**
     * Returns the name of the specified process state.  Intended for logging and debugging.
     */
+5 −2
Original line number Diff line number Diff line
@@ -276,7 +276,7 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
    /**
     * Returns a battery consumer for the specified battery consumer type.
     */
    public BatteryConsumer getAggregateBatteryConsumer(
    public AggregateBatteryConsumer getAggregateBatteryConsumer(
            @AggregateBatteryConsumerScope int scope) {
        return mAggregateBatteryConsumers[scope];
    }
@@ -450,7 +450,7 @@ public final class BatteryUsageStats implements Parcelable, Closeable {

    @NonNull
    private void writeStatsProto(ProtoOutputStream proto, int maxRawSize) {
        final BatteryConsumer deviceBatteryConsumer = getAggregateBatteryConsumer(
        final AggregateBatteryConsumer deviceBatteryConsumer = getAggregateBatteryConsumer(
                AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);

        proto.write(BatteryUsageStatsAtomsProto.SESSION_START_MILLIS, getStatsStartTimestamp());
@@ -462,6 +462,9 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
                getDischargeDurationMs());
        deviceBatteryConsumer.writeStatsProto(proto,
                BatteryUsageStatsAtomsProto.DEVICE_BATTERY_CONSUMER);
        if (mIncludesPowerModels) {
            deviceBatteryConsumer.writePowerComponentModelProto(proto);
        }
        writeUidBatteryConsumersProto(proto, maxRawSize);
    }

+17 −0
Original line number Diff line number Diff line
@@ -102,4 +102,21 @@ message BatteryUsageStatsAtomsProto {

    // Total amount of time battery was discharging during the reported session
    optional int64 discharge_duration_millis = 7;

    // Notes the power model used for a power component.
    message PowerComponentModel {
        // Holds android.os.PowerComponentEnum, or custom component value between 1000 and 9999.
        optional int32 component = 1;

        enum PowerModel {
            UNDEFINED = 0;
            POWER_PROFILE = 1;
            MEASURED_ENERGY = 2;
        }

        optional PowerModel power_model = 2;
    }

    // The power model used for each power component.
    repeated PowerComponentModel component_models = 8;
}
+45 −5
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;

import android.os.AggregateBatteryConsumer;
import android.os.BatteryConsumer;
import android.os.BatteryUsageStats;
import android.os.UidBatteryConsumer;
@@ -69,10 +70,17 @@ public class BatteryUsageStatsPulledTest {
        assertEquals(bus.getDischargeDurationMs(), proto.dischargeDurationMillis);

        assertEquals(3, proto.deviceBatteryConsumer.powerComponents.length); // Only 3 are non-empty

        final AggregateBatteryConsumer abc = bus.getAggregateBatteryConsumer(
                AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
        assertSameBatteryConsumer("For deviceBatteryConsumer",
                bus.getAggregateBatteryConsumer(AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE),
                proto.deviceBatteryConsumer);

        for (int i = 0; i < BatteryConsumer.POWER_COMPONENT_COUNT; i++) {
            assertPowerComponentModel(i, abc.getPowerModel(i), proto);
        }

        // Now for the UidBatteryConsumers.
        final List<android.os.UidBatteryConsumer> uidConsumers = bus.getUidBatteryConsumers();
        uidConsumers.sort((a, b) -> a.getUid() - b.getUid());
@@ -196,6 +204,34 @@ public class BatteryUsageStatsPulledTest {
        }
    }

    /**
     * Validates the PowerComponentModel object that matches powerComponent.
     */
    private void assertPowerComponentModel(int powerComponent,
            @BatteryConsumer.PowerModel int powerModel, BatteryUsageStatsAtomsProto proto) {
        boolean found = false;
        for (BatteryUsageStatsAtomsProto.PowerComponentModel powerComponentModel :
                proto.componentModels) {
            if (powerComponentModel.component == powerComponent) {
                if (found) {
                    fail("Power component " + BatteryConsumer.powerComponentIdToString(
                            powerComponent) + " found multiple times in the proto");
                }
                found = true;
                final int expectedPowerModel = BatteryConsumer.powerModelToProtoEnum(powerModel);
                assertEquals(expectedPowerModel, powerComponentModel.powerModel);
            }
        }
        if (!found) {
            final int model = BatteryConsumer.powerModelToProtoEnum(powerModel);
            assertEquals(
                    "Power component " + BatteryConsumer.powerComponentIdToString(powerComponent)
                            + " was not found in the proto but has a defined power model.",
                    BatteryUsageStatsAtomsProto.PowerComponentModel.UNDEFINED,
                    model);
        }
    }

    /** Converts charge from milliamp hours (mAh) to decicoulombs (dC). */
    private long convertMahToDc(double powerMah) {
        return (long) (powerMah * 36 + 0.5);
@@ -259,11 +295,14 @@ public class BatteryUsageStatsPulledTest {
        builder.getAggregateBatteryConsumerBuilder(AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
                .setConsumedPower(30000)
                .setConsumedPower(
                        BatteryConsumer.POWER_COMPONENT_CPU, 20100)
                        BatteryConsumer.POWER_COMPONENT_CPU, 20100,
                        BatteryConsumer.POWER_MODEL_POWER_PROFILE)
                .setConsumedPower(
                        BatteryConsumer.POWER_COMPONENT_AUDIO, 0) // Empty
                        BatteryConsumer.POWER_COMPONENT_AUDIO, 0,
                        BatteryConsumer.POWER_MODEL_POWER_PROFILE) // Empty
                .setConsumedPower(
                        BatteryConsumer.POWER_COMPONENT_CAMERA, 20150)
                        BatteryConsumer.POWER_COMPONENT_CAMERA, 20150,
                        BatteryConsumer.POWER_MODEL_MEASURED_ENERGY)
                .setConsumedPowerForCustomComponent(
                        BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20200)
                .setUsageDurationMillis(
@@ -275,7 +314,8 @@ public class BatteryUsageStatsPulledTest {
        builder.getAggregateBatteryConsumerBuilder(
                        BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
                .setConsumedPower(
                        BatteryConsumer.POWER_COMPONENT_CPU, 10100)
                        BatteryConsumer.POWER_COMPONENT_CPU, 10100,
                        BatteryConsumer.POWER_MODEL_POWER_PROFILE)
                .setConsumedPowerForCustomComponent(
                        BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10200);

@@ -285,7 +325,7 @@ public class BatteryUsageStatsPulledTest {
    @Test
    public void testLargeAtomTruncated() {
        final BatteryUsageStats.Builder builder =
                new BatteryUsageStats.Builder(new String[0]);
                new BatteryUsageStats.Builder(new String[0], true, false);
        // If not truncated, this BatteryUsageStats object would generate a proto buffer
        // significantly larger than 50 Kb
        for (int i = 0; i < 3000; i++) {
Loading