diff options
6 files changed, 130 insertions, 3 deletions
diff --git a/core/java/android/os/SystemBatteryConsumer.java b/core/java/android/os/SystemBatteryConsumer.java index a02f97f593f5..06cff904a215 100644 --- a/core/java/android/os/SystemBatteryConsumer.java +++ b/core/java/android/os/SystemBatteryConsumer.java @@ -51,6 +51,7 @@ public class SystemBatteryConsumer extends BatteryConsumer implements Parcelable // Reserved: UNACCOUNTED, // Reserved: USER, DRAIN_TYPE_WIFI, + DRAIN_TYPE_CUSTOM, }) @Retention(RetentionPolicy.SOURCE) public static @interface DrainType { @@ -66,6 +67,7 @@ public class SystemBatteryConsumer extends BatteryConsumer implements Parcelable public static final int DRAIN_TYPE_PHONE = 9; public static final int DRAIN_TYPE_SCREEN = 10; public static final int DRAIN_TYPE_WIFI = 13; + public static final int DRAIN_TYPE_CUSTOM = 14; @DrainType private final int mDrainType; diff --git a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java index db87a057175d..eef9fa74e83a 100644 --- a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java +++ b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java @@ -113,8 +113,13 @@ public class BatteryUsageStatsProvider { } private BatteryUsageStats getBatteryUsageStats(BatteryUsageStatsQuery query) { - // TODO(b/174186358): read extra power component number from configuration - final int customPowerComponentCount = 0; + final long[] customMeasuredEnergiesMicroJoules = + mStats.getCustomMeasuredEnergiesMicroJoules(); + final int customPowerComponentCount = customMeasuredEnergiesMicroJoules != null + ? customMeasuredEnergiesMicroJoules.length + : 0; + + // TODO(b/174186358): read extra time component number from configuration final int customTimeComponentCount = 0; final BatteryUsageStats.Builder batteryUsageStatsBuilder = diff --git a/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java b/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java index 4babe8d5fe96..2606d80eaa09 100644 --- a/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java +++ b/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java @@ -15,7 +15,12 @@ */ package com.android.internal.os; +import android.os.BatteryConsumer; import android.os.BatteryStats; +import android.os.BatteryUsageStats; +import android.os.BatteryUsageStatsQuery; +import android.os.SystemBatteryConsumer; +import android.os.UidBatteryConsumer; /** * Calculates the amount of power consumed by custom energy consumers (i.e. consumers of type @@ -26,6 +31,38 @@ public class CustomMeasuredPowerCalculator extends PowerCalculator { } @Override + public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, + long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { + super.calculate(builder, batteryStats, rawRealtimeUs, rawUptimeUs, query); + final double[] customMeasuredPowerMah = calculateMeasuredEnergiesMah( + batteryStats.getCustomMeasuredEnergiesMicroJoules()); + if (customMeasuredPowerMah != null) { + final SystemBatteryConsumer.Builder systemBatteryConsumerBuilder = + builder.getOrCreateSystemBatteryConsumerBuilder( + SystemBatteryConsumer.DRAIN_TYPE_CUSTOM); + for (int i = 0; i < customMeasuredPowerMah.length; i++) { + systemBatteryConsumerBuilder.setConsumedPowerForCustomComponent( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i, + customMeasuredPowerMah[i]); + } + } + } + + @Override + protected void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u, + long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { + final double[] customMeasuredPowerMah = calculateMeasuredEnergiesMah( + u.getCustomMeasuredEnergiesMicroJoules()); + if (customMeasuredPowerMah != null) { + for (int i = 0; i < customMeasuredPowerMah.length; i++) { + app.setConsumedPowerForCustomComponent( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i, + customMeasuredPowerMah[i]); + } + } + } + + @Override protected void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs, long rawUptimeUs, int statsType) { updateCustomMeasuredPowerMah(app, u.getCustomMeasuredEnergiesMicroJoules()); diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java index 3d43220bcb59..b819d9edb2a8 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java @@ -46,6 +46,7 @@ import org.junit.runners.Suite; BstatsCpuTimesValidationTest.class, CameraPowerCalculatorTest.class, CpuPowerCalculatorTest.class, + CustomMeasuredPowerCalculatorTest.class, DischargedPowerCalculatorTest.class, FlashlightPowerCalculatorTest.class, GnssPowerCalculatorTest.class, diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java index 997ff8a50a30..167994200ed7 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java @@ -146,7 +146,13 @@ public class BatteryUsageStatsRule implements TestRule { } BatteryUsageStats apply(BatteryUsageStatsQuery query, PowerCalculator... calculators) { - BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(0, 0); + final long[] customMeasuredEnergiesMicroJoules = + mBatteryStats.getCustomMeasuredEnergiesMicroJoules(); + final int customMeasuredEnergiesCount = customMeasuredEnergiesMicroJoules != null + ? customMeasuredEnergiesMicroJoules.length + : 0; + BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder( + customMeasuredEnergiesCount, 0); SparseArray<? extends BatteryStats.Uid> uidStats = mBatteryStats.getUidStats(); for (int i = 0; i < uidStats.size(); i++) { builder.getOrCreateUidBatteryConsumerBuilder(uidStats.valueAt(i)); diff --git a/core/tests/coretests/src/com/android/internal/os/CustomMeasuredPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/CustomMeasuredPowerCalculatorTest.java new file mode 100644 index 000000000000..a4ea8923794a --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/os/CustomMeasuredPowerCalculatorTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.os; + +import static com.google.common.truth.Truth.assertThat; + +import android.os.BatteryConsumer; +import android.os.Process; +import android.os.SystemBatteryConsumer; +import android.os.UidBatteryConsumer; +import android.util.SparseLongArray; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class CustomMeasuredPowerCalculatorTest { + private static final double PRECISION = 0.00001; + + private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42; + + @Rule + public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule(); + + @Test + public void testMeasuredEnergyCopiedIntoBatteryConsumers() { + final BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats(); + SparseLongArray uidEnergies = new SparseLongArray(); + uidEnergies.put(APP_UID, 30_000_000); + batteryStats.updateCustomMeasuredEnergyDataLocked(0, 100_000_000, uidEnergies); + + uidEnergies.put(APP_UID, 120_000_000); + batteryStats.updateCustomMeasuredEnergyDataLocked(1, 200_000_000, uidEnergies); + + CustomMeasuredPowerCalculator calculator = + new CustomMeasuredPowerCalculator(mStatsRule.getPowerProfile()); + + mStatsRule.apply(calculator); + + UidBatteryConsumer uid = mStatsRule.getUidBatteryConsumer(APP_UID); + assertThat(uid.getConsumedPowerForCustomComponent( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)) + .isWithin(PRECISION).of(2.252252); + assertThat(uid.getConsumedPowerForCustomComponent( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + 1)) + .isWithin(PRECISION).of(9.009009); + + SystemBatteryConsumer systemConsumer = mStatsRule.getSystemBatteryConsumer( + SystemBatteryConsumer.DRAIN_TYPE_CUSTOM); + assertThat(systemConsumer.getConsumedPowerForCustomComponent( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)) + .isWithin(PRECISION).of(7.5075075); + assertThat(systemConsumer.getConsumedPowerForCustomComponent( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + 1)) + .isWithin(PRECISION).of(15.015015); + } +} |