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

Commit 56a4ea56 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "BatteryStats measured energy for Wifi & Bluetooth" into sc-dev

parents 6989c4d0 4127267e
Loading
Loading
Loading
Loading
+43 −7
Original line number Diff line number Diff line
@@ -986,13 +986,13 @@ public abstract class BatteryStats implements Parcelable {
        public abstract void getDeferredJobsLineLocked(StringBuilder sb, int which);

        /**
         * Returns the battery consumption (in microcoulombs) of the screen while on and uid active,
         * Returns the battery consumption (in microcoulombs) of bluetooth for this uid,
         * derived from on device power measurement data.
         * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
         *
         * {@hide}
         */
        public abstract long getScreenOnMeasuredBatteryConsumptionUC();
        public abstract long getBluetoothMeasuredBatteryConsumptionUC();

        /**
         * Returns the battery consumption (in microcoulombs) of the uid's cpu usage, derived from
@@ -1003,6 +1003,24 @@ public abstract class BatteryStats implements Parcelable {
         */
        public abstract long getCpuMeasuredBatteryConsumptionUC();

        /**
         * Returns the battery consumption (in microcoulombs) of the screen while on and uid active,
         * derived from on device power measurement data.
         * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
         *
         * {@hide}
         */
        public abstract long getScreenOnMeasuredBatteryConsumptionUC();

        /**
         * Returns the battery consumption (in microcoulombs) of wifi for this uid,
         * derived from on device power measurement data.
         * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
         *
         * {@hide}
         */
        public abstract long getWifiMeasuredBatteryConsumptionUC();

        /**
         * Returns the battery consumption (in microcoulombs) used by this uid for each
         * {@link android.hardware.power.stats.EnergyConsumer.ordinal} of (custom) energy consumer
@@ -2505,11 +2523,29 @@ public abstract class BatteryStats implements Parcelable {
    };

    /**
     * Returned value if power data is unavailable
     * Returned value if power data is unavailable.
     *
     * {@hide}
     */
    public static final long POWER_DATA_UNAVAILABLE = -1L;

    /**
     * Returns the battery consumption (in microcoulombs) of bluetooth, derived from on
     * device power measurement data.
     * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
     *
     * {@hide}
     */
    public static final long POWER_DATA_UNAVAILABLE = -1;
    public abstract long getBluetoothMeasuredBatteryConsumptionUC();

    /**
     * Returns the battery consumption (in microcoulombs) of the cpu, derived from on device power
     * measurement data.
     * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
     *
     * {@hide}
     */
    public abstract long getCpuMeasuredBatteryConsumptionUC();

    /**
     * Returns the battery consumption (in microcoulombs) of the screen while on, derived from on
@@ -2530,13 +2566,13 @@ public abstract class BatteryStats implements Parcelable {
    public abstract long getScreenDozeMeasuredBatteryConsumptionUC();

    /**
     * Returns the battery consumption (in microcoulombs) of the cpu, derived from on device power
     * measurement data.
     * Returns the battery consumption (in microcoulombs) of wifi, derived from on
     * device power measurement data.
     * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
     *
     * {@hide}
     */
    public abstract long getCpuMeasuredBatteryConsumptionUC();
    public abstract long getWifiMeasuredBatteryConsumptionUC();

    /**
     * Returns the battery consumption (in microcoulombs) that each
+2 −2
Original line number Diff line number Diff line
@@ -110,7 +110,7 @@ public final class WifiActivityEnergyInfo implements Parcelable {
        }
        // Calculate energy used using PowerProfile.
        PowerProfile powerProfile = new PowerProfile(context);
        final double rxIdleCurrent = powerProfile.getAveragePower(
        final double idleCurrent = powerProfile.getAveragePower(
                PowerProfile.POWER_WIFI_CONTROLLER_IDLE);
        final double rxCurrent = powerProfile.getAveragePower(
                PowerProfile.POWER_WIFI_CONTROLLER_RX);
@@ -121,7 +121,7 @@ public final class WifiActivityEnergyInfo implements Parcelable {

        return (long) ((txDurationMillis * txCurrent
                + rxDurationMillis * rxCurrent
                + idleDurationMillis * rxIdleCurrent)
                + idleDurationMillis * idleCurrent)
                * voltage);
    }

+226 −52

File changed.

Preview size limit exceeded, changes collapsed.

+34 −13
Original line number Diff line number Diff line
@@ -15,8 +15,11 @@
 */
package com.android.internal.os;

import static android.os.BatteryStats.POWER_DATA_UNAVAILABLE;

import android.os.BatteryConsumer;
import android.os.BatteryStats;
import android.os.BatteryStats.ControllerActivityCounter;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
import android.os.Process;
@@ -65,17 +68,19 @@ public class BluetoothPowerCalculator extends PowerCalculator {
                builder.getUidBatteryConsumerBuilders();
        for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) {
            final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i);
            calculateApp(app, total);
            calculateApp(app, total, query);
            if (app.getUid() == Process.BLUETOOTH_UID) {
                app.excludeFromBatteryUsageStats();
                systemBatteryConsumerBuilder.addUidBatteryConsumer(app);
            }
        }

        final BatteryStats.ControllerActivityCounter activityCounter =
        final long measuredChargeUC = query.shouldForceUsePowerProfileModel() ?
                POWER_DATA_UNAVAILABLE : batteryStats.getBluetoothMeasuredBatteryConsumptionUC();
        final ControllerActivityCounter activityCounter =
                batteryStats.getBluetoothControllerActivity();
        final long systemDurationMs = calculateDuration(activityCounter);
        final double systemPowerMah = calculatePower(activityCounter);
        final double systemPowerMah = calculatePowerMah(measuredChargeUC, activityCounter);

        // Subtract what the apps used, but clamp to 0.
        final long systemComponentDurationMs = Math.max(0, systemDurationMs - total.durationMs);
@@ -91,11 +96,16 @@ public class BluetoothPowerCalculator extends PowerCalculator {
                        systemComponentPowerMah);
    }

    private void calculateApp(UidBatteryConsumer.Builder app, PowerAndDuration total) {
        final BatteryStats.ControllerActivityCounter activityCounter =
    private void calculateApp(UidBatteryConsumer.Builder app, PowerAndDuration total,
            BatteryUsageStatsQuery query) {

        final long measuredChargeUC = query.shouldForceUsePowerProfileModel() ?
                POWER_DATA_UNAVAILABLE :
                app.getBatteryStatsUid().getBluetoothMeasuredBatteryConsumptionUC();
        final ControllerActivityCounter activityCounter =
                app.getBatteryStatsUid().getBluetoothControllerActivity();
        final long durationMs = calculateDuration(activityCounter);
        final double powerMah = calculatePower(activityCounter);
        final double powerMah = calculatePowerMah(measuredChargeUC, activityCounter);

        app.setUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_BLUETOOTH, durationMs)
                .setConsumedPower(BatteryConsumer.POWER_COMPONENT_BLUETOOTH, powerMah);
@@ -121,10 +131,11 @@ public class BluetoothPowerCalculator extends PowerCalculator {
        }

        BatterySipper bs = new BatterySipper(BatterySipper.DrainType.BLUETOOTH, null, 0);
        final BatteryStats.ControllerActivityCounter activityCounter =
        final long measuredChargeUC = batteryStats.getBluetoothMeasuredBatteryConsumptionUC();
        final ControllerActivityCounter activityCounter =
                batteryStats.getBluetoothControllerActivity();
        final double systemPowerMah = calculatePower(activityCounter);
        final long systemDurationMs = calculateDuration(activityCounter);
        final double systemPowerMah = calculatePowerMah(measuredChargeUC, activityCounter);

        // Subtract what the apps used, but clamp to 0.
        final double powerMah = Math.max(0, systemPowerMah - total.powerMah);
@@ -152,10 +163,11 @@ public class BluetoothPowerCalculator extends PowerCalculator {

    private void calculateApp(BatterySipper app, BatteryStats.Uid u, int statsType,
            PowerAndDuration total) {
        final BatteryStats.ControllerActivityCounter activityCounter =
                u.getBluetoothControllerActivity();

        final long measuredChargeUC = u.getBluetoothMeasuredBatteryConsumptionUC();
        final ControllerActivityCounter activityCounter = u.getBluetoothControllerActivity();
        final long durationMs = calculateDuration(activityCounter);
        final double powerMah = calculatePower(activityCounter);
        final double powerMah = calculatePowerMah(measuredChargeUC, activityCounter);

        app.bluetoothRunningTimeMs = durationMs;
        app.bluetoothPowerMah = powerMah;
@@ -166,7 +178,7 @@ public class BluetoothPowerCalculator extends PowerCalculator {
        total.powerMah += powerMah;
    }

    private long calculateDuration(BatteryStats.ControllerActivityCounter counter) {
    private long calculateDuration(ControllerActivityCounter counter) {
        if (counter == null) {
            return 0;
        }
@@ -176,7 +188,11 @@ public class BluetoothPowerCalculator extends PowerCalculator {
                + counter.getTxTimeCounters()[0].getCountLocked(BatteryStats.STATS_SINCE_CHARGED);
    }

    private double calculatePower(BatteryStats.ControllerActivityCounter counter) {
    /** Returns bluetooth power usage based on the best data available. */
    private double calculatePowerMah(long measuredChargeUC, ControllerActivityCounter counter) {
        if (measuredChargeUC != POWER_DATA_UNAVAILABLE) {
            return uCtoMah(measuredChargeUC);
        }
        if (counter == null) {
            return 0;
        }
@@ -195,6 +211,11 @@ public class BluetoothPowerCalculator extends PowerCalculator {
                counter.getRxTimeCounter().getCountLocked(BatteryStats.STATS_SINCE_CHARGED);
        final long txTimeMs =
                counter.getTxTimeCounters()[0].getCountLocked(BatteryStats.STATS_SINCE_CHARGED);
        return calculatePowerMah(rxTimeMs, txTimeMs, idleTimeMs);
    }

    /** Returns estimated bluetooth power usage based on usage times. */
    public double calculatePowerMah(long rxTimeMs, long txTimeMs, long idleTimeMs) {
        return ((idleTimeMs * mIdleMa) + (rxTimeMs * mRxMa) + (txTimeMs * mTxMa))
                / (1000 * 60 * 60);
    }
+83 −46
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 */
package com.android.internal.os;

import static android.os.BatteryStats.POWER_DATA_UNAVAILABLE;

import android.os.BatteryConsumer;
import android.os.BatteryStats;
import android.os.BatteryUsageStats;
@@ -79,11 +81,6 @@ public class WifiPowerCalculator extends PowerCalculator {
    public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats,
            long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) {

        // batteryStats.hasWifiActivityReporting can change if we get energy data at a later point,
        // so always check this field.
        final boolean hasWifiPowerReporting =
                mHasWifiPowerController && batteryStats.hasWifiActivityReporting();

        final SystemBatteryConsumer.Builder systemBatteryConsumerBuilder =
                builder.getOrCreateSystemBatteryConsumerBuilder(
                        SystemBatteryConsumer.DRAIN_TYPE_WIFI);
@@ -97,7 +94,8 @@ public class WifiPowerCalculator extends PowerCalculator {
            final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i);
            calculateApp(powerDurationAndTraffic, app.getBatteryStatsUid(), rawRealtimeUs,
                    BatteryStats.STATS_SINCE_CHARGED,
                    hasWifiPowerReporting);
                    batteryStats.hasWifiActivityReporting(),
                    query.shouldForceUsePowerProfileModel());

            totalAppDurationMs += powerDurationAndTraffic.durationMs;
            totalAppPowerMah += powerDurationAndTraffic.powerMah;
@@ -115,7 +113,9 @@ public class WifiPowerCalculator extends PowerCalculator {

        calculateRemaining(powerDurationAndTraffic, batteryStats, rawRealtimeUs,
                BatteryStats.STATS_SINCE_CHARGED,
                hasWifiPowerReporting, totalAppDurationMs, totalAppPowerMah);
                batteryStats.hasWifiActivityReporting(),
                query.shouldForceUsePowerProfileModel(),
                totalAppDurationMs, totalAppPowerMah);

        systemBatteryConsumerBuilder
                .setUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_WIFI,
@@ -135,11 +135,6 @@ public class WifiPowerCalculator extends PowerCalculator {
    public void calculate(List<BatterySipper> sippers, BatteryStats batteryStats,
            long rawRealtimeUs, long rawUptimeUs, int statsType, SparseArray<UserHandle> asUsers) {

        // batteryStats.hasWifiActivityReporting can change if we get energy data at a later point,
        // so always check this field.
        final boolean hasWifiPowerReporting =
                mHasWifiPowerController && batteryStats.hasWifiActivityReporting();

        final BatterySipper bs = new BatterySipper(BatterySipper.DrainType.WIFI, null, 0);

        long totalAppDurationMs = 0;
@@ -149,7 +144,7 @@ public class WifiPowerCalculator extends PowerCalculator {
            final BatterySipper app = sippers.get(i);
            if (app.drainType == BatterySipper.DrainType.APP) {
                calculateApp(powerDurationAndTraffic, app.uidObj, rawRealtimeUs, statsType,
                        hasWifiPowerReporting);
                        batteryStats.hasWifiActivityReporting(), /* force use power model*/ false);

                totalAppDurationMs += powerDurationAndTraffic.durationMs;
                totalAppPowerMah += powerDurationAndTraffic.powerMah;
@@ -169,7 +164,8 @@ public class WifiPowerCalculator extends PowerCalculator {
        }

        calculateRemaining(powerDurationAndTraffic, batteryStats, rawRealtimeUs, statsType,
                hasWifiPowerReporting, totalAppDurationMs, totalAppPowerMah);
                batteryStats.hasWifiActivityReporting(), /* force use power model*/ false,
                totalAppDurationMs, totalAppPowerMah);

        bs.wifiRunningTimeMs += powerDurationAndTraffic.durationMs;
        bs.wifiPowerMah += powerDurationAndTraffic.powerMah;
@@ -180,8 +176,9 @@ public class WifiPowerCalculator extends PowerCalculator {
    }

    private void calculateApp(PowerDurationAndTraffic powerDurationAndTraffic, BatteryStats.Uid u,
            long rawRealtimeUs,
            int statsType, boolean hasWifiPowerReporting) {
            long rawRealtimeUs, int statsType,
            boolean hasWifiActivityReporting, boolean shouldForceUsePowerProfileModel) {

        powerDurationAndTraffic.wifiRxPackets = u.getNetworkActivityPackets(
                BatteryStats.NETWORK_WIFI_RX_DATA,
                statsType);
@@ -195,7 +192,14 @@ public class WifiPowerCalculator extends PowerCalculator {
                BatteryStats.NETWORK_WIFI_TX_DATA,
                statsType);

        if (hasWifiPowerReporting) {
        final long measuredChargeUC = u.getWifiMeasuredBatteryConsumptionUC();
        final boolean isMeasuredPowerAvailable
                = !shouldForceUsePowerProfileModel && measuredChargeUC != POWER_DATA_UNAVAILABLE;
        if (isMeasuredPowerAvailable) {
            powerDurationAndTraffic.powerMah = uCtoMah(measuredChargeUC);
        }

        if (hasWifiActivityReporting && mHasWifiPowerController) {
            final BatteryStats.ControllerActivityCounter counter = u.getWifiControllerActivity();
            if (counter != null) {
                final long idleTime = counter.getIdleTimeCounter().getCountLocked(statsType);
@@ -203,9 +207,10 @@ public class WifiPowerCalculator extends PowerCalculator {
                final long rxTime = counter.getRxTimeCounter().getCountLocked(statsType);

                powerDurationAndTraffic.durationMs = idleTime + rxTime + txTime;
                powerDurationAndTraffic.powerMah = mIdlePowerEstimator.calculatePower(idleTime)
                        + mTxPowerEstimator.calculatePower(txTime)
                        + mRxPowerEstimator.calculatePower(rxTime);
                if (!isMeasuredPowerAvailable) {
                    powerDurationAndTraffic.powerMah
                            = calcPowerFromControllerDataMah(rxTime, txTime, idleTime);
                }

                if (DEBUG && powerDurationAndTraffic.powerMah != 0) {
                    Log.d(TAG, "UID " + u.getUid() + ": idle=" + idleTime + "ms rx=" + rxTime
@@ -214,21 +219,20 @@ public class WifiPowerCalculator extends PowerCalculator {
                }
            }
        } else {
            final double wifiPacketPower = (
                    powerDurationAndTraffic.wifiRxPackets + powerDurationAndTraffic.wifiTxPackets)
                    * mWifiPowerPerPacket;
            final long wifiRunningTime = u.getWifiRunningTime(rawRealtimeUs, statsType) / 1000;
            powerDurationAndTraffic.durationMs = wifiRunningTime;

            if (!isMeasuredPowerAvailable) {
                final long wifiScanTimeMs = u.getWifiScanTime(rawRealtimeUs, statsType) / 1000;
            long batchScanTimeMs = 0;
                long batchTimeMs = 0;
                for (int bin = 0; bin < BatteryStats.Uid.NUM_WIFI_BATCHED_SCAN_BINS; bin++) {
                batchScanTimeMs += u.getWifiBatchedScanTime(bin, rawRealtimeUs, statsType) / 1000;
                    batchTimeMs += u.getWifiBatchedScanTime(bin, rawRealtimeUs, statsType) / 1000;
                }
                powerDurationAndTraffic.powerMah = calcPowerWithoutControllerDataMah(
                        powerDurationAndTraffic.wifiRxPackets,
                        powerDurationAndTraffic.wifiTxPackets,
                        wifiRunningTime, wifiScanTimeMs, batchTimeMs);
            }

            powerDurationAndTraffic.durationMs = wifiRunningTime;
            powerDurationAndTraffic.powerMah = wifiPacketPower
                    + mPowerOnPowerEstimator.calculatePower(wifiRunningTime)
                    + mScanPowerEstimator.calculatePower(wifiScanTimeMs)
                    + mBatchScanPowerEstimator.calculatePower(batchScanTimeMs);

            if (DEBUG && powerDurationAndTraffic.powerMah != 0) {
                Log.d(TAG, "UID " + u.getUid() + ": power=" + formatCharge(
@@ -238,12 +242,20 @@ public class WifiPowerCalculator extends PowerCalculator {
    }

    private void calculateRemaining(PowerDurationAndTraffic powerDurationAndTraffic,
            BatteryStats stats, long rawRealtimeUs,
            int statsType, boolean hasWifiPowerReporting, long totalAppDurationMs,
            double totalAppPowerMah) {
            BatteryStats stats, long rawRealtimeUs, int statsType,
            boolean hasWifiActivityReporting, boolean shouldForceUsePowerProfileModel,
            long totalAppDurationMs, double totalAppPowerMah) {

        long totalDurationMs;
        double totalPowerMah;
        if (hasWifiPowerReporting) {
        double totalPowerMah = 0;

        final long measuredChargeUC = stats.getWifiMeasuredBatteryConsumptionUC();
        final boolean isMeasuredPowerAvailable
                = !shouldForceUsePowerProfileModel && measuredChargeUC != POWER_DATA_UNAVAILABLE;
        if (isMeasuredPowerAvailable) {
            totalPowerMah = uCtoMah(measuredChargeUC);
        }
        if (hasWifiActivityReporting && mHasWifiPowerController) {
            final BatteryStats.ControllerActivityCounter counter =
                    stats.getWifiControllerActivity();

@@ -253,17 +265,19 @@ public class WifiPowerCalculator extends PowerCalculator {

            totalDurationMs = idleTimeMs + rxTimeMs + txTimeMs;

            totalPowerMah =
                    counter.getPowerCounter().getCountLocked(statsType) / (double) (1000 * 60 * 60);
            if (!isMeasuredPowerAvailable) {
                totalPowerMah = counter.getPowerCounter().getCountLocked(statsType)
                        / (double) (1000 * 60 * 60);
                if (totalPowerMah == 0) {
                    // Some controllers do not report power drain, so we can calculate it here.
                totalPowerMah = mIdlePowerEstimator.calculatePower(idleTimeMs)
                        + mTxPowerEstimator.calculatePower(txTimeMs)
                        + mRxPowerEstimator.calculatePower(rxTimeMs);
                    totalPowerMah = calcPowerFromControllerDataMah(rxTimeMs, txTimeMs, idleTimeMs);
                }
            }
        } else {
            totalDurationMs = stats.getGlobalWifiRunningTime(rawRealtimeUs, statsType) / 1000;
            totalPowerMah = mPowerOnPowerEstimator.calculatePower(totalDurationMs);
            if (!isMeasuredPowerAvailable) {
                totalPowerMah = calcGlobalPowerWithoutControllerDataMah(totalDurationMs);
            }
        }

        powerDurationAndTraffic.durationMs = Math.max(0, totalDurationMs - totalAppDurationMs);
@@ -274,6 +288,29 @@ public class WifiPowerCalculator extends PowerCalculator {
        }
    }

    /** Returns (global or uid) estimated wifi power used using WifiControllerActivity data. */
    public double calcPowerFromControllerDataMah(long rxTimeMs, long txTimeMs, long idleTimeMs) {
        return mRxPowerEstimator.calculatePower(rxTimeMs)
                + mTxPowerEstimator.calculatePower(txTimeMs)
                + mIdlePowerEstimator.calculatePower(idleTimeMs);
    }

    /** Returns per-uid estimated wifi power used using non-WifiControllerActivity data. */
    public double calcPowerWithoutControllerDataMah(long rxPackets, long txPackets,
            long wifiRunningTimeMs, long wifiScanTimeMs, long wifiBatchScanTimeMs) {
        return
                (rxPackets + txPackets) * mWifiPowerPerPacket
                + mPowerOnPowerEstimator.calculatePower(wifiRunningTimeMs)
                + mScanPowerEstimator.calculatePower(wifiScanTimeMs)
                + mBatchScanPowerEstimator.calculatePower(wifiBatchScanTimeMs);

    }

    /** Returns global estimated wifi power used using non-WifiControllerActivity data. */
    public double calcGlobalPowerWithoutControllerDataMah(long globalWifiRunningTimeMs) {
        return mPowerOnPowerEstimator.calculatePower(globalWifiRunningTimeMs);
    }

    /**
     * Return estimated power per Wi-Fi packet in mAh/packet where 1 packet = 2 KB.
     */
Loading