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

Commit 7582c4ac authored by Dmitri Plotnikov's avatar Dmitri Plotnikov Committed by Android (Google) Code Review
Browse files

Merge "Add process state to BatteryUsageStats atoms"

parents 54c1ea89 79978c19
Loading
Loading
Loading
Loading
+61 −17
Original line number Diff line number Diff line
@@ -223,7 +223,8 @@ class PowerComponents {
        for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT;
                componentId++) {

            final BatteryConsumer.Key key = mData.getKey(componentId, PROCESS_STATE_ANY);
            final BatteryConsumer.Key[] keys = mData.getKeys(componentId);
            for (BatteryConsumer.Key key : keys) {
                final long powerDeciCoulombs = convertMahToDeciCoulombs(getConsumedPower(key));
                final long durationMs = getUsageDurationMillis(key);

@@ -234,11 +235,20 @@ class PowerComponents {

                interestingData = true;
                if (proto == null) {
                // We're just asked whether there is data, not to actually write it. And there is.
                    // We're just asked whether there is data, not to actually write it.
                    // And there is.
                    return true;
                }

            writePowerComponent(proto, componentId, powerDeciCoulombs, durationMs);
                if (key.processState == PROCESS_STATE_ANY) {
                    writePowerComponentUsage(proto,
                            BatteryUsageStatsAtomsProto.BatteryConsumerData.POWER_COMPONENTS,
                            componentId, powerDeciCoulombs, durationMs);
                } else {
                    writePowerUsageSlice(proto, componentId, powerDeciCoulombs, durationMs,
                            key.processState);
                }
            }
        }
        for (int idx = 0; idx < mData.layout.customPowerComponentCount; idx++) {
            final int componentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + idx;
@@ -257,15 +267,49 @@ class PowerComponents {
                return true;
            }

            writePowerComponent(proto, componentId, powerDeciCoulombs, durationMs);
            writePowerComponentUsage(proto,
                    BatteryUsageStatsAtomsProto.BatteryConsumerData.POWER_COMPONENTS,
                    componentId, powerDeciCoulombs, durationMs);
        }
        return interestingData;
    }

    private void writePowerComponent(ProtoOutputStream proto, int componentId,
    private void writePowerUsageSlice(ProtoOutputStream proto, int componentId,
            long powerDeciCoulombs, long durationMs, int processState) {
        final long slicesToken =
                proto.start(BatteryUsageStatsAtomsProto.BatteryConsumerData.SLICES);
        writePowerComponentUsage(proto,
                BatteryUsageStatsAtomsProto.BatteryConsumerData.PowerComponentUsageSlice
                        .POWER_COMPONENT,
                componentId, powerDeciCoulombs, durationMs);

        final int procState;
        switch (processState) {
            case BatteryConsumer.PROCESS_STATE_FOREGROUND:
                procState = BatteryUsageStatsAtomsProto.BatteryConsumerData.PowerComponentUsageSlice
                        .FOREGROUND;
                break;
            case BatteryConsumer.PROCESS_STATE_BACKGROUND:
                procState = BatteryUsageStatsAtomsProto.BatteryConsumerData.PowerComponentUsageSlice
                        .BACKGROUND;
                break;
            case BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE:
                procState = BatteryUsageStatsAtomsProto.BatteryConsumerData.PowerComponentUsageSlice
                        .FOREGROUND_SERVICE;
                break;
            default:
                throw new IllegalArgumentException("Unknown process state: " + processState);
        }

        proto.write(BatteryUsageStatsAtomsProto.BatteryConsumerData.PowerComponentUsageSlice
                .PROCESS_STATE, procState);

        proto.end(slicesToken);
    }

    private void writePowerComponentUsage(ProtoOutputStream proto, long tag, int componentId,
            long powerDeciCoulombs, long durationMs) {
        final long token =
                proto.start(BatteryUsageStatsAtomsProto.BatteryConsumerData.POWER_COMPONENTS);
        final long token = proto.start(tag);
        proto.write(
                BatteryUsageStatsAtomsProto.BatteryConsumerData.PowerComponentUsage
                        .COMPONENT,
+20 −0
Original line number Diff line number Diff line
@@ -62,6 +62,26 @@ message BatteryUsageStatsAtomsProto {
            optional int64 duration_millis = 3;
        }
        repeated PowerComponentUsage power_components = 2;

        // Represents a slice of power attribution, e.g. "cpu while in the background"
        // or "wifi when running a background service".  Queries that care about
        // PowerComponentUsage slices need to be aware of all supported dimensions.
        // There are no roll-ups included in the slices - it is up to the clients
        // of this data to aggregate values as needed.
        message PowerComponentUsageSlice {
            optional PowerComponentUsage power_component = 1;

            enum ProcessState {
                UNSPECIFIED = 0;
                FOREGROUND = 1;
                BACKGROUND = 2;
                FOREGROUND_SERVICE = 3;
            }

            optional ProcessState process_state = 2;
        }

        repeated PowerComponentUsageSlice slices = 3;
    }

    // Total power usage for the device during this session.
+59 −4
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.when;

import android.os.BatteryConsumer;
import android.os.BatteryUsageStats;
import android.os.UidBatteryConsumer;
import android.os.nano.BatteryUsageStatsAtomsProto;
import android.os.nano.BatteryUsageStatsAtomsProto.BatteryConsumerData.PowerComponentUsage;

@@ -134,6 +135,43 @@ public class BatteryUsageStatsPulledTest {
                        componentProto.durationMillis);
            }
        }

        for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT;
                componentId++) {
            final BatteryConsumer.Key[] keys = consumer.getKeys(componentId);
            if (keys == null || keys.length <= 1) {
                continue;
            }

            for (BatteryConsumer.Key key : keys) {
                if (key.processState == 0) {
                    continue;
                }

                BatteryUsageStatsAtomsProto.BatteryConsumerData.PowerComponentUsageSlice
                        sliceProto = null;
                for (BatteryUsageStatsAtomsProto.BatteryConsumerData.PowerComponentUsageSlice
                        slice : consumerProto.slices) {
                    if (slice.powerComponent.component == componentId
                            && slice.processState == key.processState) {
                        sliceProto = slice;
                        break;
                    }
                }

                final long expectedPowerDc = convertMahToDc(consumer.getConsumedPower(key));
                final long expectedUsageDurationMillis = consumer.getUsageDurationMillis(key);
                if (expectedPowerDc == 0 && expectedUsageDurationMillis == 0) {
                    assertThat(sliceProto).isNull();
                } else {
                    assertThat(sliceProto).isNotNull();
                    assertThat(sliceProto.powerComponent.powerDeciCoulombs)
                            .isEqualTo(expectedPowerDc);
                    assertThat(sliceProto.powerComponent.durationMillis)
                            .isEqualTo(expectedUsageDurationMillis);
                }
            }
        }
    }

    private void assertSameUidBatteryConsumer(
@@ -172,14 +210,17 @@ public class BatteryUsageStatsPulledTest {
        final BatteryStatsImpl.Uid batteryStatsUid3 = batteryStats.getUidStatsLocked(UID_3);

        final BatteryUsageStats.Builder builder =
                new BatteryUsageStats.Builder(new String[]{"CustomConsumer1", "CustomConsumer2"})
                new BatteryUsageStats.Builder(new String[]{"CustomConsumer1", "CustomConsumer2"},
                        /* includePowerModels */ true,
                        /* includeProcessStats */true)
                        .setDischargePercentage(20)
                        .setDischargedPowerRange(1000, 2000)
                        .setStatsStartTimestamp(1000);
        builder.getOrCreateUidBatteryConsumerBuilder(batteryStatsUid0)
        final UidBatteryConsumer.Builder uidBuilder = builder.getOrCreateUidBatteryConsumerBuilder(
                batteryStatsUid0)
                .setPackageWithHighestDrain("myPackage0")
                .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_FOREGROUND, 1000)
                .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_BACKGROUND, 2000)
                .setTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND, 1000)
                .setTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND, 2000)
                .setConsumedPower(
                        BatteryConsumer.POWER_COMPONENT_SCREEN, 300)
                .setConsumedPower(
@@ -193,6 +234,20 @@ public class BatteryUsageStatsPulledTest {
                .setUsageDurationForCustomComponentMillis(
                        BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + 1, 800);

        final BatteryConsumer.Key keyFg = uidBuilder.getKey(BatteryConsumer.POWER_COMPONENT_CPU,
                BatteryConsumer.PROCESS_STATE_FOREGROUND);
        final BatteryConsumer.Key keyBg = uidBuilder.getKey(BatteryConsumer.POWER_COMPONENT_CPU,
                BatteryConsumer.PROCESS_STATE_BACKGROUND);
        final BatteryConsumer.Key keyFgs = uidBuilder.getKey(BatteryConsumer.POWER_COMPONENT_CPU,
                BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE);

        uidBuilder.setConsumedPower(keyFg, 9100, BatteryConsumer.POWER_MODEL_POWER_PROFILE)
                .setUsageDurationMillis(keyFg, 8100)
                .setConsumedPower(keyBg, 9200, BatteryConsumer.POWER_MODEL_MEASURED_ENERGY)
                .setUsageDurationMillis(keyBg, 8200)
                .setConsumedPower(keyFgs, 9300, BatteryConsumer.POWER_MODEL_MEASURED_ENERGY)
                .setUsageDurationMillis(keyFgs, 8300);

        builder.getOrCreateUidBatteryConsumerBuilder(batteryStatsUid1)
                .setPackageWithHighestDrain("myPackage1")
                .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_FOREGROUND, 1234);