Loading core/java/android/os/BatteryConsumer.java +14 −1 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ public abstract class BatteryConsumer { POWER_COMPONENT_SENSORS, POWER_COMPONENT_GNSS, POWER_COMPONENT_SCREEN, POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS, }) @Retention(RetentionPolicy.SOURCE) public static @interface PowerComponent { Loading @@ -65,8 +66,12 @@ public abstract class BatteryConsumer { public static final int POWER_COMPONENT_SENSORS = 9; public static final int POWER_COMPONENT_GNSS = 10; public static final int POWER_COMPONENT_SCREEN = 13; // Power that is re-attributed to other battery consumers. For example, for System Server // this represents the power attributed to apps requesting system services. // The value should be negative or zero. public static final int POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS = 14; public static final int POWER_COMPONENT_COUNT = 14; public static final int POWER_COMPONENT_COUNT = 15; public static final int FIRST_CUSTOM_POWER_COMPONENT_ID = 1000; public static final int LAST_CUSTOM_POWER_COMPONENT_ID = 9999; Loading Loading @@ -236,5 +241,13 @@ public abstract class BatteryConsumer { componentUsageTimeMillis); return (T) this; } /** * Returns the total power accumulated by this builder so far. It may change * by the time the {@code build()} method is called. */ public double getTotalPower() { return mPowerComponentsBuilder.getTotalPower(); } } } core/java/android/os/PowerComponents.java +13 −5 Original line number Diff line number Diff line Loading @@ -38,11 +38,7 @@ class PowerComponents { mCustomPowerComponentCount = builder.mCustomPowerComponentCount; mPowerComponents = builder.mPowerComponents; mTimeComponents = builder.mTimeComponents; double totalPower = 0; for (int i = mPowerComponents.length - 1; i >= 0; i--) { totalPower += mPowerComponents[i]; } mTotalPowerConsumed = totalPower; mTotalPowerConsumed = builder.getTotalPower(); } PowerComponents(@NonNull Parcel source) { Loading Loading @@ -263,6 +259,18 @@ class PowerComponents { } } /** * Returns the total power accumulated by this builder so far. It may change * by the time the {@code build()} method is called. */ public double getTotalPower() { double totalPower = 0; for (int i = mPowerComponents.length - 1; i >= 0; i--) { totalPower += mPowerComponents[i]; } return totalPower; } /** * Creates a read-only object out of the Builder values. */ Loading core/java/com/android/internal/os/BatterySipper.java +10 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,11 @@ public class BatterySipper implements Comparable<BatterySipper> { public double systemServiceCpuPowerMah; public double[] customMeasuredPowerMah; // Power that is re-attributed to other sippers. For example, for System Server // this represents the power attributed to apps requesting system services. // The value should be negative or zero. public double powerReattributedToOtherSippersMah; // Do not include this sipper in results because it is included // in an aggregate sipper. public boolean isAggregated; Loading Loading @@ -263,6 +268,7 @@ public class BatterySipper implements Comparable<BatterySipper> { } } } powerReattributedToOtherSippersMah += other.powerReattributedToOtherSippersMah; } /** Loading @@ -281,6 +287,10 @@ public class BatterySipper implements Comparable<BatterySipper> { totalPowerMah += customMeasuredPowerMah[idx]; } } // powerAttributedToOtherSippersMah is negative or zero totalPowerMah = totalPowerMah + powerReattributedToOtherSippersMah; totalSmearedPowerMah = totalPowerMah + screenPowerMah + proportionalSmearMah; return totalPowerMah; Loading core/java/com/android/internal/os/BatteryUsageStatsProvider.java +7 −3 Original line number Diff line number Diff line Loading @@ -70,11 +70,14 @@ public class BatteryUsageStatsProvider { mPowerCalculators.add(new PhonePowerCalculator(mPowerProfile)); mPowerCalculators.add(new ScreenPowerCalculator(mPowerProfile)); mPowerCalculators.add(new AmbientDisplayPowerCalculator(mPowerProfile)); mPowerCalculators.add(new SystemServicePowerCalculator(mPowerProfile)); mPowerCalculators.add(new IdlePowerCalculator(mPowerProfile)); mPowerCalculators.add(new CustomMeasuredPowerCalculator(mPowerProfile)); mPowerCalculators.add(new UserPowerCalculator()); // It is important that SystemServicePowerCalculator be applied last, // because it re-attributes some of the power estimated by the other // calculators. mPowerCalculators.add(new SystemServicePowerCalculator(mPowerProfile)); } } return mPowerCalculators; Loading Loading @@ -128,7 +131,8 @@ public class BatteryUsageStatsProvider { final long uptimeUs = SystemClock.uptimeMillis() * 1000; final List<PowerCalculator> powerCalculators = getPowerCalculators(); for (PowerCalculator powerCalculator : powerCalculators) { for (int i = 0, count = powerCalculators.size(); i < count; i++) { PowerCalculator powerCalculator = powerCalculators.get(i); powerCalculator.calculate(batteryUsageStatsBuilder, mStats, realtimeUs, uptimeUs, query); } Loading core/java/com/android/internal/os/SystemServicePowerCalculator.java +81 −56 Original line number Diff line number Diff line Loading @@ -20,12 +20,12 @@ import android.os.BatteryConsumer; import android.os.BatteryStats; import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; import android.os.Process; import android.os.UidBatteryConsumer; import android.os.UserHandle; import android.util.Log; import android.util.SparseArray; import java.util.Arrays; import java.util.List; /** Loading @@ -36,87 +36,112 @@ public class SystemServicePowerCalculator extends PowerCalculator { private static final boolean DEBUG = false; private static final String TAG = "SystemServicePowerCalc"; private static final long MICROSEC_IN_HR = (long) 60 * 60 * 1000 * 1000; private final PowerProfile mPowerProfile; // Tracks system server CPU [cluster][speed] power in milliAmp-microseconds // Data organized like this: // Power estimators per CPU cluster, per CPU frequency. The array is flattened according // to this layout: // {cluster1-speed1, cluster1-speed2, ..., cluster2-speed1, cluster2-speed2, ...} private double[] mSystemServicePowerMaUs; private final UsageBasedPowerEstimator[] mPowerEstimators; public SystemServicePowerCalculator(PowerProfile powerProfile) { mPowerProfile = powerProfile; int numFreqs = 0; final int numCpuClusters = powerProfile.getNumCpuClusters(); for (int cluster = 0; cluster < numCpuClusters; cluster++) { numFreqs += powerProfile.getNumSpeedStepsInCpuCluster(cluster); } @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { calculateSystemServicePower(batteryStats); super.calculate(builder, batteryStats, rawRealtimeUs, rawUptimeUs, query); mPowerEstimators = new UsageBasedPowerEstimator[numFreqs]; int index = 0; for (int cluster = 0; cluster < numCpuClusters; cluster++) { final int numSpeeds = powerProfile.getNumSpeedStepsInCpuCluster(cluster); for (int speed = 0; speed < numSpeeds; speed++) { mPowerEstimators[index++] = new UsageBasedPowerEstimator( powerProfile.getAveragePowerForCpuCore(cluster, speed)); } } } @Override protected void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u, public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { double systemServicePowerMah = calculateSystemServicePower(batteryStats); final SparseArray<UidBatteryConsumer.Builder> uidBatteryConsumerBuilders = builder.getUidBatteryConsumerBuilders(); final UidBatteryConsumer.Builder systemServerConsumer = uidBatteryConsumerBuilders.get( Process.SYSTEM_UID); if (systemServerConsumer != null) { systemServicePowerMah = Math.min(systemServicePowerMah, systemServerConsumer.getTotalPower()); // The system server power needs to be adjusted because part of it got // distributed to applications systemServerConsumer.setConsumedPower( BatteryConsumer.POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS, -systemServicePowerMah); } for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) { final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i); if (app != systemServerConsumer) { final BatteryStats.Uid uid = app.getBatteryStatsUid(); app.setConsumedPower(BatteryConsumer.POWER_COMPONENT_SYSTEM_SERVICES, calculateSystemServerCpuPowerMah(u)); systemServicePowerMah * uid.getProportionalSystemServiceUsage()); } } } @Override public void calculate(List<BatterySipper> sippers, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, int statsType, SparseArray<UserHandle> asUsers) { calculateSystemServicePower(batteryStats); super.calculate(sippers, batteryStats, rawRealtimeUs, rawUptimeUs, statsType, asUsers); double systemServicePowerMah = calculateSystemServicePower(batteryStats); BatterySipper systemServerSipper = null; for (int i = sippers.size() - 1; i >= 0; i--) { final BatterySipper app = sippers.get(i); if (app.drainType == BatterySipper.DrainType.APP) { if (app.getUid() == Process.SYSTEM_UID) { systemServerSipper = app; break; } @Override protected void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs, long rawUptimeUs, int statsType) { app.systemServiceCpuPowerMah = calculateSystemServerCpuPowerMah(u); } private void calculateSystemServicePower(BatteryStats batteryStats) { final long[] systemServiceTimeAtCpuSpeeds = batteryStats.getSystemServiceTimeAtCpuSpeeds(); if (systemServiceTimeAtCpuSpeeds == null) { return; } if (mSystemServicePowerMaUs == null) { mSystemServicePowerMaUs = new double[systemServiceTimeAtCpuSpeeds.length]; if (systemServerSipper != null) { systemServicePowerMah = Math.min(systemServicePowerMah, systemServerSipper.sumPower()); // The system server power needs to be adjusted because part of it got // distributed to applications systemServerSipper.powerReattributedToOtherSippersMah = -systemServicePowerMah; } int index = 0; final int numCpuClusters = mPowerProfile.getNumCpuClusters(); for (int cluster = 0; cluster < numCpuClusters; cluster++) { final int numSpeeds = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); for (int speed = 0; speed < numSpeeds; speed++) { mSystemServicePowerMaUs[index] = systemServiceTimeAtCpuSpeeds[index] * mPowerProfile.getAveragePowerForCpuCore(cluster, speed); index++; for (int i = sippers.size() - 1; i >= 0; i--) { final BatterySipper app = sippers.get(i); if (app.drainType == BatterySipper.DrainType.APP) { if (app != systemServerSipper) { final BatteryStats.Uid uid = app.uidObj; app.systemServiceCpuPowerMah = systemServicePowerMah * uid.getProportionalSystemServiceUsage(); } } if (DEBUG) { Log.d(TAG, "System service power per CPU cluster and frequency:" + Arrays.toString(mSystemServicePowerMaUs)); } } private double calculateSystemServerCpuPowerMah(BatteryStats.Uid u) { double cpuPowerMaUs = 0; final double proportionalUsage = u.getProportionalSystemServiceUsage(); if (proportionalUsage > 0 && mSystemServicePowerMaUs != null) { for (int i = 0; i < mSystemServicePowerMaUs.length; i++) { cpuPowerMaUs += mSystemServicePowerMaUs[i] * proportionalUsage; private double calculateSystemServicePower(BatteryStats batteryStats) { final long[] systemServiceTimeAtCpuSpeeds = batteryStats.getSystemServiceTimeAtCpuSpeeds(); if (systemServiceTimeAtCpuSpeeds == null) { return 0; } // TODO(179210707): additionally account for CPU active and per cluster battery use double powerMah = 0; for (int i = 0; i < mPowerEstimators.length; i++) { powerMah += mPowerEstimators[i].calculatePower(systemServiceTimeAtCpuSpeeds[i]); } return cpuPowerMaUs / MICROSEC_IN_HR; if (DEBUG) { Log.d(TAG, "System service power:" + powerMah); } @Override public void reset() { mSystemServicePowerMaUs = null; return powerMah; } } Loading
core/java/android/os/BatteryConsumer.java +14 −1 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ public abstract class BatteryConsumer { POWER_COMPONENT_SENSORS, POWER_COMPONENT_GNSS, POWER_COMPONENT_SCREEN, POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS, }) @Retention(RetentionPolicy.SOURCE) public static @interface PowerComponent { Loading @@ -65,8 +66,12 @@ public abstract class BatteryConsumer { public static final int POWER_COMPONENT_SENSORS = 9; public static final int POWER_COMPONENT_GNSS = 10; public static final int POWER_COMPONENT_SCREEN = 13; // Power that is re-attributed to other battery consumers. For example, for System Server // this represents the power attributed to apps requesting system services. // The value should be negative or zero. public static final int POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS = 14; public static final int POWER_COMPONENT_COUNT = 14; public static final int POWER_COMPONENT_COUNT = 15; public static final int FIRST_CUSTOM_POWER_COMPONENT_ID = 1000; public static final int LAST_CUSTOM_POWER_COMPONENT_ID = 9999; Loading Loading @@ -236,5 +241,13 @@ public abstract class BatteryConsumer { componentUsageTimeMillis); return (T) this; } /** * Returns the total power accumulated by this builder so far. It may change * by the time the {@code build()} method is called. */ public double getTotalPower() { return mPowerComponentsBuilder.getTotalPower(); } } }
core/java/android/os/PowerComponents.java +13 −5 Original line number Diff line number Diff line Loading @@ -38,11 +38,7 @@ class PowerComponents { mCustomPowerComponentCount = builder.mCustomPowerComponentCount; mPowerComponents = builder.mPowerComponents; mTimeComponents = builder.mTimeComponents; double totalPower = 0; for (int i = mPowerComponents.length - 1; i >= 0; i--) { totalPower += mPowerComponents[i]; } mTotalPowerConsumed = totalPower; mTotalPowerConsumed = builder.getTotalPower(); } PowerComponents(@NonNull Parcel source) { Loading Loading @@ -263,6 +259,18 @@ class PowerComponents { } } /** * Returns the total power accumulated by this builder so far. It may change * by the time the {@code build()} method is called. */ public double getTotalPower() { double totalPower = 0; for (int i = mPowerComponents.length - 1; i >= 0; i--) { totalPower += mPowerComponents[i]; } return totalPower; } /** * Creates a read-only object out of the Builder values. */ Loading
core/java/com/android/internal/os/BatterySipper.java +10 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,11 @@ public class BatterySipper implements Comparable<BatterySipper> { public double systemServiceCpuPowerMah; public double[] customMeasuredPowerMah; // Power that is re-attributed to other sippers. For example, for System Server // this represents the power attributed to apps requesting system services. // The value should be negative or zero. public double powerReattributedToOtherSippersMah; // Do not include this sipper in results because it is included // in an aggregate sipper. public boolean isAggregated; Loading Loading @@ -263,6 +268,7 @@ public class BatterySipper implements Comparable<BatterySipper> { } } } powerReattributedToOtherSippersMah += other.powerReattributedToOtherSippersMah; } /** Loading @@ -281,6 +287,10 @@ public class BatterySipper implements Comparable<BatterySipper> { totalPowerMah += customMeasuredPowerMah[idx]; } } // powerAttributedToOtherSippersMah is negative or zero totalPowerMah = totalPowerMah + powerReattributedToOtherSippersMah; totalSmearedPowerMah = totalPowerMah + screenPowerMah + proportionalSmearMah; return totalPowerMah; Loading
core/java/com/android/internal/os/BatteryUsageStatsProvider.java +7 −3 Original line number Diff line number Diff line Loading @@ -70,11 +70,14 @@ public class BatteryUsageStatsProvider { mPowerCalculators.add(new PhonePowerCalculator(mPowerProfile)); mPowerCalculators.add(new ScreenPowerCalculator(mPowerProfile)); mPowerCalculators.add(new AmbientDisplayPowerCalculator(mPowerProfile)); mPowerCalculators.add(new SystemServicePowerCalculator(mPowerProfile)); mPowerCalculators.add(new IdlePowerCalculator(mPowerProfile)); mPowerCalculators.add(new CustomMeasuredPowerCalculator(mPowerProfile)); mPowerCalculators.add(new UserPowerCalculator()); // It is important that SystemServicePowerCalculator be applied last, // because it re-attributes some of the power estimated by the other // calculators. mPowerCalculators.add(new SystemServicePowerCalculator(mPowerProfile)); } } return mPowerCalculators; Loading Loading @@ -128,7 +131,8 @@ public class BatteryUsageStatsProvider { final long uptimeUs = SystemClock.uptimeMillis() * 1000; final List<PowerCalculator> powerCalculators = getPowerCalculators(); for (PowerCalculator powerCalculator : powerCalculators) { for (int i = 0, count = powerCalculators.size(); i < count; i++) { PowerCalculator powerCalculator = powerCalculators.get(i); powerCalculator.calculate(batteryUsageStatsBuilder, mStats, realtimeUs, uptimeUs, query); } Loading
core/java/com/android/internal/os/SystemServicePowerCalculator.java +81 −56 Original line number Diff line number Diff line Loading @@ -20,12 +20,12 @@ import android.os.BatteryConsumer; import android.os.BatteryStats; import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; import android.os.Process; import android.os.UidBatteryConsumer; import android.os.UserHandle; import android.util.Log; import android.util.SparseArray; import java.util.Arrays; import java.util.List; /** Loading @@ -36,87 +36,112 @@ public class SystemServicePowerCalculator extends PowerCalculator { private static final boolean DEBUG = false; private static final String TAG = "SystemServicePowerCalc"; private static final long MICROSEC_IN_HR = (long) 60 * 60 * 1000 * 1000; private final PowerProfile mPowerProfile; // Tracks system server CPU [cluster][speed] power in milliAmp-microseconds // Data organized like this: // Power estimators per CPU cluster, per CPU frequency. The array is flattened according // to this layout: // {cluster1-speed1, cluster1-speed2, ..., cluster2-speed1, cluster2-speed2, ...} private double[] mSystemServicePowerMaUs; private final UsageBasedPowerEstimator[] mPowerEstimators; public SystemServicePowerCalculator(PowerProfile powerProfile) { mPowerProfile = powerProfile; int numFreqs = 0; final int numCpuClusters = powerProfile.getNumCpuClusters(); for (int cluster = 0; cluster < numCpuClusters; cluster++) { numFreqs += powerProfile.getNumSpeedStepsInCpuCluster(cluster); } @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { calculateSystemServicePower(batteryStats); super.calculate(builder, batteryStats, rawRealtimeUs, rawUptimeUs, query); mPowerEstimators = new UsageBasedPowerEstimator[numFreqs]; int index = 0; for (int cluster = 0; cluster < numCpuClusters; cluster++) { final int numSpeeds = powerProfile.getNumSpeedStepsInCpuCluster(cluster); for (int speed = 0; speed < numSpeeds; speed++) { mPowerEstimators[index++] = new UsageBasedPowerEstimator( powerProfile.getAveragePowerForCpuCore(cluster, speed)); } } } @Override protected void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u, public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { double systemServicePowerMah = calculateSystemServicePower(batteryStats); final SparseArray<UidBatteryConsumer.Builder> uidBatteryConsumerBuilders = builder.getUidBatteryConsumerBuilders(); final UidBatteryConsumer.Builder systemServerConsumer = uidBatteryConsumerBuilders.get( Process.SYSTEM_UID); if (systemServerConsumer != null) { systemServicePowerMah = Math.min(systemServicePowerMah, systemServerConsumer.getTotalPower()); // The system server power needs to be adjusted because part of it got // distributed to applications systemServerConsumer.setConsumedPower( BatteryConsumer.POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS, -systemServicePowerMah); } for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) { final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i); if (app != systemServerConsumer) { final BatteryStats.Uid uid = app.getBatteryStatsUid(); app.setConsumedPower(BatteryConsumer.POWER_COMPONENT_SYSTEM_SERVICES, calculateSystemServerCpuPowerMah(u)); systemServicePowerMah * uid.getProportionalSystemServiceUsage()); } } } @Override public void calculate(List<BatterySipper> sippers, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, int statsType, SparseArray<UserHandle> asUsers) { calculateSystemServicePower(batteryStats); super.calculate(sippers, batteryStats, rawRealtimeUs, rawUptimeUs, statsType, asUsers); double systemServicePowerMah = calculateSystemServicePower(batteryStats); BatterySipper systemServerSipper = null; for (int i = sippers.size() - 1; i >= 0; i--) { final BatterySipper app = sippers.get(i); if (app.drainType == BatterySipper.DrainType.APP) { if (app.getUid() == Process.SYSTEM_UID) { systemServerSipper = app; break; } @Override protected void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs, long rawUptimeUs, int statsType) { app.systemServiceCpuPowerMah = calculateSystemServerCpuPowerMah(u); } private void calculateSystemServicePower(BatteryStats batteryStats) { final long[] systemServiceTimeAtCpuSpeeds = batteryStats.getSystemServiceTimeAtCpuSpeeds(); if (systemServiceTimeAtCpuSpeeds == null) { return; } if (mSystemServicePowerMaUs == null) { mSystemServicePowerMaUs = new double[systemServiceTimeAtCpuSpeeds.length]; if (systemServerSipper != null) { systemServicePowerMah = Math.min(systemServicePowerMah, systemServerSipper.sumPower()); // The system server power needs to be adjusted because part of it got // distributed to applications systemServerSipper.powerReattributedToOtherSippersMah = -systemServicePowerMah; } int index = 0; final int numCpuClusters = mPowerProfile.getNumCpuClusters(); for (int cluster = 0; cluster < numCpuClusters; cluster++) { final int numSpeeds = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); for (int speed = 0; speed < numSpeeds; speed++) { mSystemServicePowerMaUs[index] = systemServiceTimeAtCpuSpeeds[index] * mPowerProfile.getAveragePowerForCpuCore(cluster, speed); index++; for (int i = sippers.size() - 1; i >= 0; i--) { final BatterySipper app = sippers.get(i); if (app.drainType == BatterySipper.DrainType.APP) { if (app != systemServerSipper) { final BatteryStats.Uid uid = app.uidObj; app.systemServiceCpuPowerMah = systemServicePowerMah * uid.getProportionalSystemServiceUsage(); } } if (DEBUG) { Log.d(TAG, "System service power per CPU cluster and frequency:" + Arrays.toString(mSystemServicePowerMaUs)); } } private double calculateSystemServerCpuPowerMah(BatteryStats.Uid u) { double cpuPowerMaUs = 0; final double proportionalUsage = u.getProportionalSystemServiceUsage(); if (proportionalUsage > 0 && mSystemServicePowerMaUs != null) { for (int i = 0; i < mSystemServicePowerMaUs.length; i++) { cpuPowerMaUs += mSystemServicePowerMaUs[i] * proportionalUsage; private double calculateSystemServicePower(BatteryStats batteryStats) { final long[] systemServiceTimeAtCpuSpeeds = batteryStats.getSystemServiceTimeAtCpuSpeeds(); if (systemServiceTimeAtCpuSpeeds == null) { return 0; } // TODO(179210707): additionally account for CPU active and per cluster battery use double powerMah = 0; for (int i = 0; i < mPowerEstimators.length; i++) { powerMah += mPowerEstimators[i].calculatePower(systemServiceTimeAtCpuSpeeds[i]); } return cpuPowerMaUs / MICROSEC_IN_HR; if (DEBUG) { Log.d(TAG, "System service power:" + powerMah); } @Override public void reset() { mSystemServicePowerMaUs = null; return powerMah; } }