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

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

Merge "Proportionally attribute Mobile Radio Energy Consumption to Phone usage." into tm-qpr-dev

parents a76b1162 33d9beaf
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -2807,6 +2807,15 @@ public abstract class BatteryStats implements Parcelable {
     */
    public abstract long getMobileRadioMeasuredBatteryConsumptionUC();

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

    /**
     * Returns the battery consumption (in microcoulombs) of the screen while on, derived from on
     * device power measurement data.
+45 −10
Original line number Diff line number Diff line
@@ -166,8 +166,8 @@ public class BatteryStatsImpl extends BatteryStats {
    // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
    private static final int MAGIC = 0xBA757475; // 'BATSTATS'
    // Current on-disk Parcel version
    static final int VERSION = 210;
    // Current on-disk Parcel version. Must be updated when the format of the parcelable changes
    public static final int VERSION = 211;
    // The maximum number of names wakelocks we will keep track of
    // per uid; once the limit is reached, we batch the remaining wakelocks
@@ -6491,6 +6491,9 @@ public class BatteryStatsImpl extends BatteryStats {
            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
            mPhoneOn = true;
            mPhoneOnTimer.startRunningLocked(elapsedRealtimeMs);
            if (mConstants.PHONE_ON_EXTERNAL_STATS_COLLECTION) {
                scheduleSyncExternalStatsLocked("phone-on", ExternalStatsSync.UPDATE_RADIO);
            }
        }
    }
@@ -6509,6 +6512,7 @@ public class BatteryStatsImpl extends BatteryStats {
            addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
            mPhoneOn = false;
            mPhoneOnTimer.stopRunningLocked(elapsedRealtimeMs);
            scheduleSyncExternalStatsLocked("phone-off", ExternalStatsSync.UPDATE_RADIO);
        }
    }
@@ -8473,6 +8477,12 @@ public class BatteryStatsImpl extends BatteryStats {
        return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO);
    }
    @GuardedBy("this")
    @Override
    public long getPhoneEnergyConsumptionUC() {
        return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_PHONE);
    }
    @GuardedBy("this")
    @Override
    public long getScreenOnMeasuredBatteryConsumptionUC() {
@@ -13717,18 +13727,36 @@ public class BatteryStatsImpl extends BatteryStats {
        }
        synchronized (this) {
            final long totalRadioDurationMs =
                    mMobileRadioActiveTimer.getTimeSinceMarkLocked(
                            elapsedRealtimeMs * 1000) / 1000;
            mMobileRadioActiveTimer.setMark(elapsedRealtimeMs);
            final long phoneOnDurationMs = Math.min(totalRadioDurationMs,
                    mPhoneOnTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000);
            mPhoneOnTimer.setMark(elapsedRealtimeMs);
            if (!mOnBatteryInternal || mIgnoreNextExternalStats) {
                return;
            }
            final SparseDoubleArray uidEstimatedConsumptionMah;
            final long dataConsumedChargeUC;
            if (consumedChargeUC > 0 && mMobileRadioPowerCalculator != null
                    && mGlobalMeasuredEnergyStats != null) {
                // Crudely attribute power consumption. Added (totalRadioDurationMs / 2) to the
                // numerator for long rounding.
                final long phoneConsumedChargeUC =
                        (consumedChargeUC * phoneOnDurationMs + totalRadioDurationMs / 2)
                                / totalRadioDurationMs;
                dataConsumedChargeUC = consumedChargeUC - phoneConsumedChargeUC;
                mGlobalMeasuredEnergyStats.updateStandardBucket(
                        MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO, consumedChargeUC);
                        MeasuredEnergyStats.POWER_BUCKET_PHONE, phoneConsumedChargeUC);
                mGlobalMeasuredEnergyStats.updateStandardBucket(
                        MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO, dataConsumedChargeUC);
                uidEstimatedConsumptionMah = new SparseDoubleArray();
            } else {
                uidEstimatedConsumptionMah = null;
                dataConsumedChargeUC = POWER_DATA_UNAVAILABLE;
            }
            if (deltaInfo != null) {
@@ -13888,14 +13916,9 @@ public class BatteryStatsImpl extends BatteryStats {
                // Update the MeasuredEnergyStats information.
                if (uidEstimatedConsumptionMah != null) {
                    double totalEstimatedConsumptionMah = 0.0;
                    // Estimate total active radio power consumption since last mark.
                    final long totalRadioTimeMs = mMobileRadioActiveTimer.getTimeSinceMarkLocked(
                            elapsedRealtimeMs * 1000) / 1000;
                    mMobileRadioActiveTimer.setMark(elapsedRealtimeMs);
                    totalEstimatedConsumptionMah +=
                            mMobileRadioPowerCalculator.calcPowerFromRadioActiveDurationMah(
                                    totalRadioTimeMs);
                                    totalRadioDurationMs);
                    // Estimate idle power consumption at each signal strength level
                    final int numSignalStrengthLevels = mPhoneSignalStrengthsTimer.length;
@@ -13919,7 +13942,7 @@ public class BatteryStatsImpl extends BatteryStats {
                            mMobileRadioPowerCalculator.calcScanTimePowerMah(scanTimeMs);
                    distributeEnergyToUidsLocked(MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO,
                            consumedChargeUC, uidEstimatedConsumptionMah,
                            dataConsumedChargeUC, uidEstimatedConsumptionMah,
                            totalEstimatedConsumptionMah, elapsedRealtimeMs);
                }
@@ -16651,6 +16674,8 @@ public class BatteryStatsImpl extends BatteryStats {
        public static final String KEY_MAX_HISTORY_BUFFER_KB = "max_history_buffer_kb";
        public static final String KEY_BATTERY_CHARGED_DELAY_MS =
                "battery_charged_delay_ms";
        public static final String KEY_PHONE_ON_EXTERNAL_STATS_COLLECTION =
                "phone_on_external_stats_collection";
        private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true;
        private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 1_000;
@@ -16663,6 +16688,7 @@ public class BatteryStatsImpl extends BatteryStats {
        private static final int DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE = 64;
        private static final int DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB = 64; /*Kilo Bytes*/
        private static final int DEFAULT_BATTERY_CHARGED_DELAY_MS = 900000; /* 15 min */
        private static final boolean DEFAULT_PHONE_ON_EXTERNAL_STATS_COLLECTION = true;
        public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME;
        /* Do not set default value for KERNEL_UID_READERS_THROTTLE_TIME. Need to trigger an
@@ -16678,6 +16704,8 @@ public class BatteryStatsImpl extends BatteryStats {
        public int MAX_HISTORY_FILES;
        public int MAX_HISTORY_BUFFER; /*Bytes*/
        public int BATTERY_CHARGED_DELAY_MS = DEFAULT_BATTERY_CHARGED_DELAY_MS;
        public boolean PHONE_ON_EXTERNAL_STATS_COLLECTION =
                DEFAULT_PHONE_ON_EXTERNAL_STATS_COLLECTION;
        private ContentResolver mResolver;
        private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -16754,6 +16782,11 @@ public class BatteryStatsImpl extends BatteryStats {
                                DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB
                                : DEFAULT_MAX_HISTORY_BUFFER_KB)
                        * 1024;
                PHONE_ON_EXTERNAL_STATS_COLLECTION = mParser.getBoolean(
                        KEY_PHONE_ON_EXTERNAL_STATS_COLLECTION,
                        DEFAULT_PHONE_ON_EXTERNAL_STATS_COLLECTION);
                updateBatteryChargedDelayMsLocked();
            }
        }
@@ -16808,6 +16841,8 @@ public class BatteryStatsImpl extends BatteryStats {
            pw.println(MAX_HISTORY_BUFFER/1024);
            pw.print(KEY_BATTERY_CHARGED_DELAY_MS); pw.print("=");
            pw.println(BATTERY_CHARGED_DELAY_MS);
            pw.print(KEY_PHONE_ON_EXTERNAL_STATS_COLLECTION); pw.print("=");
            pw.println(PHONE_ON_EXTERNAL_STATS_COLLECTION);
        }
    }
+19 −6
Original line number Diff line number Diff line
@@ -40,14 +40,27 @@ public class PhonePowerCalculator extends PowerCalculator {
    @Override
    public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats,
            long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) {
        final long energyConsumerUC = batteryStats.getPhoneEnergyConsumptionUC();
        final int powerModel = getPowerModel(energyConsumerUC, query);

        final long phoneOnTimeMs = batteryStats.getPhoneOnTime(rawRealtimeUs,
                BatteryStats.STATS_SINCE_CHARGED) / 1000;
        final double phoneOnPower = mPowerEstimator.calculatePower(phoneOnTimeMs);
        if (phoneOnPower != 0) {
        final double phoneOnPower;
        switch (powerModel) {
            case BatteryConsumer.POWER_MODEL_MEASURED_ENERGY:
                phoneOnPower = uCtoMah(energyConsumerUC);
                break;
            case BatteryConsumer.POWER_MODEL_POWER_PROFILE:
            default:
                phoneOnPower = mPowerEstimator.calculatePower(phoneOnTimeMs);
        }

        if (phoneOnPower == 0.0)  return;

        builder.getAggregateBatteryConsumerBuilder(
                        BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
                    .setConsumedPower(BatteryConsumer.POWER_COMPONENT_PHONE, phoneOnPower)
                .setConsumedPower(BatteryConsumer.POWER_COMPONENT_PHONE, phoneOnPower, powerModel)
                .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_PHONE, phoneOnTimeMs);
        }

    }
}
+3 −1
Original line number Diff line number Diff line
@@ -59,7 +59,9 @@ public class MeasuredEnergyStats {
    public static final int POWER_BUCKET_BLUETOOTH = 5;
    public static final int POWER_BUCKET_GNSS = 6;
    public static final int POWER_BUCKET_MOBILE_RADIO = 7;
    public static final int NUMBER_STANDARD_POWER_BUCKETS = 8; // Buckets above this are custom.
    public static final int POWER_BUCKET_CAMERA = 8;
    public static final int POWER_BUCKET_PHONE = 9;
    public static final int NUMBER_STANDARD_POWER_BUCKETS = 10;  // Buckets above this are custom.

    @IntDef(prefix = {"POWER_BUCKET_"}, value = {
            POWER_BUCKET_UNKNOWN,
+14 −6
Original line number Diff line number Diff line
@@ -245,6 +245,8 @@ public class MobileRadioPowerCalculatorTest {
        stats.noteNetworkInterfaceForTransports("cellular",
                new int[]{NetworkCapabilities.TRANSPORT_CELLULAR});

        stats.notePhoneOnLocked(9800, 9800);

        // Note application network activity
        NetworkStats networkStats = new NetworkStats(10000, 1)
                .addEntry(new NetworkStats.Entry("cellular", APP_UID, 0, 0,
@@ -257,27 +259,33 @@ public class MobileRadioPowerCalculatorTest {

        mStatsRule.setTime(12_000, 12_000);

        MobileRadioPowerCalculator calculator =
        MobileRadioPowerCalculator mobileRadioPowerCalculator =
                new MobileRadioPowerCalculator(mStatsRule.getPowerProfile());

        mStatsRule.apply(calculator);
        PhonePowerCalculator phonePowerCalculator =
                new PhonePowerCalculator(mStatsRule.getPowerProfile());
        mStatsRule.apply(mobileRadioPowerCalculator, phonePowerCalculator);

        UidBatteryConsumer uidConsumer = mStatsRule.getUidBatteryConsumer(APP_UID);
        assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                .isWithin(PRECISION).of(1.53934);
                .isWithin(PRECISION).of(1.38541);
        assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY);

        BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer();
        // 10_000_000 micro-Coulomb * 1/1000 milli/micro * 1/3600 hour/second = 2.77778 mAh
        assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                .isWithin(PRECISION).of(2.77778);
                .isWithin(PRECISION).of(2.5);
        assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY);

        assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_PHONE))
                .isWithin(PRECISION).of(0.27778);
        assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_PHONE))
                .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY);

        BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer();
        assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                .isWithin(PRECISION).of(1.53934);
                .isWithin(PRECISION).of(1.38541);
        assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
                .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY);
    }
Loading