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

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

Merge "Convert BatteryStats.dumpLocked from BatteryStatsHelper to BatteryUsageStats" into sc-dev

parents f774ba0d e43992bb
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package android.os;

import android.annotation.NonNull;

import java.io.PrintWriter;

/**
 * Contains power consumption data across the entire device.
 *
@@ -37,6 +39,11 @@ public final class AggregateBatteryConsumer extends BatteryConsumer implements P
        mConsumedPowerMah = source.readDouble();
    }

    @Override
    public void dump(PrintWriter pw, boolean skipEmptyComponents) {
        mPowerComponents.dump(pw, skipEmptyComponents);
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
+69 −3
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.os;
import android.annotation.IntDef;
import android.annotation.NonNull;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@@ -27,7 +28,7 @@ import java.lang.annotation.RetentionPolicy;
 *
 * @hide
 */
public class BatteryConsumer {
public abstract class BatteryConsumer {

    /**
     * Power usage component, describing the particular part of the system
@@ -85,12 +86,37 @@ public class BatteryConsumer {
    public static final int FIRST_CUSTOM_POWER_COMPONENT_ID = 1000;
    public static final int LAST_CUSTOM_POWER_COMPONENT_ID = 9999;

    private static final String[] sPowerComponentNames = new String[POWER_COMPONENT_COUNT];

    static {
        // Assign individually to avoid future mismatch
        sPowerComponentNames[POWER_COMPONENT_SCREEN] = "screen";
        sPowerComponentNames[POWER_COMPONENT_CPU] = "cpu";
        sPowerComponentNames[POWER_COMPONENT_BLUETOOTH] = "bluetooth";
        sPowerComponentNames[POWER_COMPONENT_CAMERA] = "camera";
        sPowerComponentNames[POWER_COMPONENT_AUDIO] = "audio";
        sPowerComponentNames[POWER_COMPONENT_VIDEO] = "video";
        sPowerComponentNames[POWER_COMPONENT_FLASHLIGHT] = "flashlight";
        sPowerComponentNames[POWER_COMPONENT_SYSTEM_SERVICES] = "system_services";
        sPowerComponentNames[POWER_COMPONENT_MOBILE_RADIO] = "mobile_radio";
        sPowerComponentNames[POWER_COMPONENT_SENSORS] = "sensors";
        sPowerComponentNames[POWER_COMPONENT_GNSS] = "gnss";
        sPowerComponentNames[POWER_COMPONENT_WIFI] = "wifi";
        sPowerComponentNames[POWER_COMPONENT_WAKELOCK] = "wakelock";
        sPowerComponentNames[POWER_COMPONENT_MEMORY] = "memory";
        sPowerComponentNames[POWER_COMPONENT_PHONE] = "phone";
        sPowerComponentNames[POWER_COMPONENT_AMBIENT_DISPLAY] = "ambient_display";
        sPowerComponentNames[POWER_COMPONENT_IDLE] = "idle";
        sPowerComponentNames[POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS] = "reattributed";
    }

    /**
     * Identifiers of models used for power estimation.
     *
     * @hide
     */
    @IntDef(prefix = {"POWER_MODEL_"}, value = {
            POWER_MODEL_UNDEFINED,
            POWER_MODEL_POWER_PROFILE,
            POWER_MODEL_MEASURED_ENERGY,
    })
@@ -98,16 +124,21 @@ public class BatteryConsumer {
    public @interface PowerModel {
    }

    /**
     * Unspecified power model.
     */
    public static final int POWER_MODEL_UNDEFINED = 0;

    /**
     * Power model that is based on average consumption rates that hardware components
     * consume in various states.
     */
    public static final int POWER_MODEL_POWER_PROFILE = 0;
    public static final int POWER_MODEL_POWER_PROFILE = 1;

    /**
     * Power model that is based on energy consumption measured by on-device power monitors.
     */
    public static final int POWER_MODEL_MEASURED_ENERGY = 1;
    public static final int POWER_MODEL_MEASURED_ENERGY = 2;

    protected final PowerComponents mPowerComponents;

@@ -197,6 +228,41 @@ public class BatteryConsumer {
        mPowerComponents.writeToParcel(dest, flags);
    }

    /**
     * Returns the name of the specified component.  Intended for logging and debugging.
     */
    public static String powerComponentIdToString(@BatteryConsumer.PowerComponent int componentId) {
        return sPowerComponentNames[componentId];
    }

    /**
     * Returns the name of the specified power model.  Intended for logging and debugging.
     */
    public static String powerModelToString(@BatteryConsumer.PowerModel int powerModel) {
        switch (powerModel) {
            case BatteryConsumer.POWER_MODEL_MEASURED_ENERGY:
                return "measured energy";
            case BatteryConsumer.POWER_MODEL_POWER_PROFILE:
                return "power profile";
            default:
                return "";
        }
    }

    /**
     * Prints the stats in a human-readable format.
     */
    public void dump(PrintWriter pw) {
        dump(pw, true);
    }

    /**
     * Prints the stats in a human-readable format.
     *
     * @param skipEmptyComponents if true, omit any power components with a zero amount.
     */
    public abstract void dump(PrintWriter pw, boolean skipEmptyComponents);

    protected abstract static class BaseBuilder<T extends BaseBuilder<?>> {
        final PowerComponents.Builder mPowerComponentsBuilder;

+10 −144
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import android.view.Display;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper;
import com.android.internal.os.BatteryUsageStatsProvider;

import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -5299,154 +5300,19 @@ public abstract class BatteryStats implements Parcelable {
        pw.println(getDischargeAmountScreenDozeSinceCharge());
        pw.println();

        final BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, this);
        final BatteryUsageStats stats = provider.getBatteryUsageStats(
                new BatteryUsageStatsQuery.Builder()
                        .setMaxStatsAgeMs(0)
                        .includePowerModels()
                        .build());
        stats.dump(pw, prefix);

        final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
        helper.create(this);
        helper.refreshStats(which, UserHandle.USER_ALL);
        List<BatterySipper> sippers = helper.getUsageList();
        if (sippers != null && sippers.size() > 0) {
            pw.print(prefix); pw.println("  Estimated power use (mAh):");
            pw.print(prefix); pw.print("    Capacity: ");
                    printmAh(pw, helper.getPowerProfile().getBatteryCapacity());
                    pw.print(", Computed drain: "); printmAh(pw, helper.getComputedPower());
                    pw.print(", actual drain: "); printmAh(pw, helper.getMinDrainedPower());
                    if (helper.getMinDrainedPower() != helper.getMaxDrainedPower()) {
                        pw.print("-"); printmAh(pw, helper.getMaxDrainedPower());
                    }
                    pw.println();
            for (int i=0; i<sippers.size(); i++) {
                final BatterySipper bs = sippers.get(i);
                pw.print(prefix);
                switch (bs.drainType) {
                    case AMBIENT_DISPLAY:
                        pw.print("    Ambient display: ");
                        break;
                    case IDLE:
                        pw.print("    Idle: ");
                        break;
                    case CELL:
                        pw.print("    Cell standby: ");
                        break;
                    case PHONE:
                        pw.print("    Phone calls: ");
                        break;
                    case WIFI:
                        pw.print("    Wifi: ");
                        break;
                    case BLUETOOTH:
                        pw.print("    Bluetooth: ");
                        break;
                    case SCREEN:
                        pw.print("    Screen: ");
                        break;
                    case FLASHLIGHT:
                        pw.print("    Flashlight: ");
                        break;
                    case APP:
                        pw.print("    Uid ");
                        UserHandle.formatUid(pw, bs.uidObj.getUid());
                        pw.print(": ");
                        break;
                    case USER:
                        pw.print("    User "); pw.print(bs.userId);
                        pw.print(": ");
                        break;
                    case UNACCOUNTED:
                        pw.print("    Unaccounted: ");
                        break;
                    case OVERCOUNTED:
                        pw.print("    Over-counted: ");
                        break;
                    case CAMERA:
                        pw.print("    Camera: ");
                        break;
                    default:
                        pw.print("    ???: ");
                        break;
                }
                printmAh(pw, bs.totalPowerMah);

                if (bs.usagePowerMah != bs.totalPowerMah) {
                    // If the usage (generic power) isn't the whole amount, we list out
                    // what components are involved in the calculation.

                    pw.print(" (");
                    if (bs.usagePowerMah != 0) {
                        pw.print(" usage=");
                        printmAh(pw, bs.usagePowerMah);
                    }
                    if (bs.cpuPowerMah != 0) {
                        pw.print(" cpu=");
                        printmAh(pw, bs.cpuPowerMah);
                    }
                    if (bs.wakeLockPowerMah != 0) {
                        pw.print(" wake=");
                        printmAh(pw, bs.wakeLockPowerMah);
                    }
                    if (bs.mobileRadioPowerMah != 0) {
                        pw.print(" radio=");
                        printmAh(pw, bs.mobileRadioPowerMah);
                    }
                    if (bs.wifiPowerMah != 0) {
                        pw.print(" wifi=");
                        printmAh(pw, bs.wifiPowerMah);
                    }
                    if (bs.bluetoothPowerMah != 0) {
                        pw.print(" bt=");
                        printmAh(pw, bs.bluetoothPowerMah);
                    }
                    if (bs.gpsPowerMah != 0) {
                        pw.print(" gps=");
                        printmAh(pw, bs.gpsPowerMah);
                    }
                    if (bs.sensorPowerMah != 0) {
                        pw.print(" sensor=");
                        printmAh(pw, bs.sensorPowerMah);
                    }
                    if (bs.cameraPowerMah != 0) {
                        pw.print(" camera=");
                        printmAh(pw, bs.cameraPowerMah);
                    }
                    if (bs.flashlightPowerMah != 0) {
                        pw.print(" flash=");
                        printmAh(pw, bs.flashlightPowerMah);
                    }
                    if (bs.customMeasuredPowerMah != null) {
                        for (int idx = 0; idx < bs.customMeasuredPowerMah.length; idx++) {
                            final double customPowerMah = bs.customMeasuredPowerMah[idx];
                            if (customPowerMah != 0) {
                                pw.print(" custom[" + idx + "]=");
                                printmAh(pw, customPowerMah);
                            }
                        }
                    }
                    pw.print(" )");
                }

                // If there is additional smearing information, include it.
                if (bs.totalSmearedPowerMah != bs.totalPowerMah) {
                    pw.print(" Including smearing: ");
                    printmAh(pw, bs.totalSmearedPowerMah);
                    pw.print(" (");
                    if (bs.screenPowerMah != 0) {
                        pw.print(" screen=");
                        printmAh(pw, bs.screenPowerMah);
                    }
                    if (bs.proportionalSmearMah != 0) {
                        pw.print(" proportional=");
                        printmAh(pw, bs.proportionalSmearMah);
                    }
                    pw.print(" )");
                }
                if (bs.shouldHide) {
                    pw.print(" Excluded from smearing");
                }

                pw.println();
            }
            pw.println();
        }

        sippers = helper.getMobilemsppList();
        final List<BatterySipper> sippers = helper.getMobilemsppList();
        if (sippers != null && sippers.size() > 0) {
            pw.print(prefix); pw.println("  Per-app mobile ms per packet:");
            long totalTime = 0;
+121 −0
Original line number Diff line number Diff line
@@ -23,10 +23,13 @@ import android.util.SparseArray;

import com.android.internal.os.BatteryStatsHistory;
import com.android.internal.os.BatteryStatsHistoryIterator;
import com.android.internal.os.PowerCalculator;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
@@ -73,6 +76,7 @@ public final class BatteryUsageStats implements Parcelable {

    private final int mDischargePercentage;
    private final long mStatsStartTimestampMs;
    private final double mBatteryCapacityMah;
    private final double mDischargedPowerLowerBound;
    private final double mDischargedPowerUpperBound;
    private final long mBatteryTimeRemainingMs;
@@ -86,6 +90,7 @@ public final class BatteryUsageStats implements Parcelable {

    private BatteryUsageStats(@NonNull Builder builder) {
        mStatsStartTimestampMs = builder.mStatsStartTimestampMs;
        mBatteryCapacityMah = builder.mBatteryCapacityMah;
        mDischargePercentage = builder.mDischargePercentage;
        mDischargedPowerLowerBound = builder.mDischargedPowerLowerBoundMah;
        mDischargedPowerUpperBound = builder.mDischargedPowerUpperBoundMah;
@@ -144,6 +149,13 @@ public final class BatteryUsageStats implements Parcelable {
                .getConsumedPower();
    }

    /**
     * Returns battery capacity in milli-amp-hours.
     */
    public double getBatteryCapacity() {
        return mBatteryCapacityMah;
    }

    /**
     * Portion of battery charge drained since BatteryStats reset (e.g. due to being fully
     * charged), as percentage of the full charge in the range [0:100]
@@ -217,6 +229,7 @@ public final class BatteryUsageStats implements Parcelable {

    private BatteryUsageStats(@NonNull Parcel source) {
        mStatsStartTimestampMs = source.readLong();
        mBatteryCapacityMah = source.readDouble();
        mDischargePercentage = source.readInt();
        mDischargedPowerLowerBound = source.readDouble();
        mDischargedPowerUpperBound = source.readDouble();
@@ -274,6 +287,7 @@ public final class BatteryUsageStats implements Parcelable {
    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeLong(mStatsStartTimestampMs);
        dest.writeDouble(mBatteryCapacityMah);
        dest.writeInt(mDischargePercentage);
        dest.writeDouble(mDischargedPowerLowerBound);
        dest.writeDouble(mDischargedPowerUpperBound);
@@ -321,6 +335,104 @@ public final class BatteryUsageStats implements Parcelable {
        }
    };

    /**
     * Prints the stats in a human-readable format.
     */
    public void dump(PrintWriter pw, String prefix) {
        pw.print(prefix);
        pw.println("  Estimated power use (mAh):");
        pw.print(prefix);
        pw.print("    Capacity: ");
        PowerCalculator.printPowerMah(pw, getBatteryCapacity());
        pw.print(", Computed drain: ");
        PowerCalculator.printPowerMah(pw, getConsumedPower());
        final Range<Double> dischargedPowerRange = getDischargedPowerRange();
        pw.print(", actual drain: ");
        PowerCalculator.printPowerMah(pw, dischargedPowerRange.getLower());
        if (!dischargedPowerRange.getLower().equals(dischargedPowerRange.getUpper())) {
            pw.print("-");
            PowerCalculator.printPowerMah(pw, dischargedPowerRange.getUpper());
        }
        pw.println();

        pw.println("    Global");
        final BatteryConsumer deviceConsumer = getAggregateBatteryConsumer(
                AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
        final BatteryConsumer appsConsumer = getAggregateBatteryConsumer(
                AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS);

        for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT;
                componentId++) {
            final double devicePowerMah = deviceConsumer.getConsumedPower(componentId);
            final double appsPowerMah = appsConsumer.getConsumedPower(componentId);
            if (devicePowerMah == 0 && appsPowerMah == 0) {
                continue;
            }

            final String componentName = BatteryConsumer.powerComponentIdToString(componentId);
            printPowerComponent(pw, prefix, componentName, devicePowerMah, appsPowerMah,
                    deviceConsumer.getPowerModel(componentId),
                    deviceConsumer.getUsageDurationMillis(componentId));
        }

        for (int componentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID;
                componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID
                        + mCustomPowerComponentNames.length;
                componentId++) {
            final double devicePowerMah =
                    deviceConsumer.getConsumedPowerForCustomComponent(componentId);
            final double appsPowerMah =
                    appsConsumer.getConsumedPowerForCustomComponent(componentId);
            if (devicePowerMah == 0 && appsPowerMah == 0) {
                continue;
            }

            printPowerComponent(pw, prefix, deviceConsumer.getCustomPowerComponentName(componentId),
                    devicePowerMah, appsPowerMah,
                    BatteryConsumer.POWER_MODEL_UNDEFINED,
                    deviceConsumer.getUsageDurationForCustomComponentMillis(componentId));
        }

        dumpSortedBatteryConsumers(pw, prefix, getUidBatteryConsumers());
        dumpSortedBatteryConsumers(pw, prefix, getUserBatteryConsumers());
    }

    private void printPowerComponent(PrintWriter pw, String prefix, String componentName,
            double devicePowerMah, double appsPowerMah, int powerModel, long durationMs) {
        StringBuilder sb = new StringBuilder();
        sb.append(prefix).append("      ").append(componentName).append(": ")
                .append(PowerCalculator.formatCharge(devicePowerMah));
        if (powerModel != BatteryConsumer.POWER_MODEL_UNDEFINED
                && powerModel != BatteryConsumer.POWER_MODEL_POWER_PROFILE) {
            sb.append(" [");
            sb.append(BatteryConsumer.powerModelToString(powerModel));
            sb.append("]");
        }
        sb.append(" apps: ").append(PowerCalculator.formatCharge(appsPowerMah));
        if (durationMs != 0) {
            sb.append(" duration: ");
            BatteryStats.formatTimeMs(sb, durationMs);
        }

        pw.println(sb.toString());
    }

    private void dumpSortedBatteryConsumers(PrintWriter pw, String prefix,
            List<? extends BatteryConsumer> batteryConsumers) {
        batteryConsumers.sort(
                Comparator.<BatteryConsumer>comparingDouble(BatteryConsumer::getConsumedPower)
                        .reversed());
        for (BatteryConsumer consumer : batteryConsumers) {
            if (consumer.getConsumedPower() == 0) {
                continue;
            }
            pw.print(prefix);
            pw.print("    ");
            consumer.dump(pw);
            pw.println();
        }
    }

    /**
     * Builder for BatteryUsageStats.
     */
@@ -329,6 +441,7 @@ public final class BatteryUsageStats implements Parcelable {
        private final String[] mCustomPowerComponentNames;
        private final boolean mIncludePowerModels;
        private long mStatsStartTimestampMs;
        private double mBatteryCapacityMah;
        private int mDischargePercentage;
        private double mDischargedPowerLowerBoundMah;
        private double mDischargedPowerUpperBoundMah;
@@ -364,6 +477,14 @@ public final class BatteryUsageStats implements Parcelable {
            return new BatteryUsageStats(this);
        }

        /**
         * Sets the battery capacity in milli-amp-hours.
         */
        public Builder setBatteryCapacity(double batteryCapacityMah) {
            mBatteryCapacityMah = batteryCapacityMah;
            return this;
        }

        /**
         * Sets the timestamp of the latest battery stats reset, in milliseconds.
         */
+35 −0
Original line number Diff line number Diff line
@@ -17,6 +17,10 @@ package android.os;

import android.annotation.NonNull;

import com.android.internal.os.PowerCalculator;

import java.io.PrintWriter;

/**
 * Contains details of battery attribution data broken down to individual power drain types
 * such as CPU, RAM, GPU etc.
@@ -202,6 +206,37 @@ class PowerComponents {
        return max;
    }

    public void dump(PrintWriter pw, boolean skipEmptyComponents) {
        String separator = "";
        for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT;
                componentId++) {
            final double componentPower = getConsumedPower(componentId);
            if (skipEmptyComponents && componentPower == 0) {
                continue;
            }
            pw.print(separator); separator = " ";
            pw.print(BatteryConsumer.powerComponentIdToString(componentId));
            pw.print("=");
            PowerCalculator.printPowerMah(pw, componentPower);
        }

        final int customComponentCount = getCustomPowerComponentCount();
        for (int customComponentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID;
                customComponentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID
                        + customComponentCount;
                customComponentId++) {
            final double customComponentPower =
                    getConsumedPowerForCustomComponent(customComponentId);
            if (skipEmptyComponents && customComponentPower == 0) {
                continue;
            }
            pw.print(separator); separator = " ";
            pw.print(getCustomPowerComponentName(customComponentId));
            pw.print("=");
            PowerCalculator.printPowerMah(pw, customComponentPower);
        }
    }

    /**
     * Builder for PowerComponents.
     */
Loading