From d3545200232e988bf994ea32b0acc6ba97f26484 Mon Sep 17 00:00:00 2001 From: Dmitri Plotnikov Date: Fri, 23 Apr 2021 15:08:29 -0700 Subject: [PATCH] Aggregate power data in AggregateBatteryConsumers as opposed to SystemBatteryConsumers, which will be removed in a follow-up CL Bug: 186006876 Test: atest FrameworksCoreTests:com.android.internal.os.BatteryStatsTests Change-Id: Ie4166217be211d92293c2a107762801a7d3c206f --- .../android/os/AggregateBatteryConsumer.java | 74 ++++++++++++++++ core/java/android/os/BatteryConsumer.java | 11 +-- core/java/android/os/BatteryUsageStats.java | 86 ++++++++++++++++++- .../os/AmbientDisplayPowerCalculator.java | 8 +- .../internal/os/AudioPowerCalculator.java | 33 ++++++- .../internal/os/BluetoothPowerCalculator.java | 12 +++ .../internal/os/CameraPowerCalculator.java | 19 ++++ .../internal/os/CpuPowerCalculator.java | 15 ++++ .../os/CustomMeasuredPowerCalculator.java | 60 ++++++++++--- .../os/FlashlightPowerCalculator.java | 19 ++++ .../internal/os/GnssPowerCalculator.java | 23 ++++- .../internal/os/IdlePowerCalculator.java | 4 + .../internal/os/MemoryPowerCalculator.java | 4 + .../os/MobileRadioPowerCalculator.java | 14 +++ .../internal/os/PhonePowerCalculator.java | 4 + .../internal/os/ScreenPowerCalculator.java | 15 ++++ .../internal/os/SensorPowerCalculator.java | 27 +++++- .../os/SystemServicePowerCalculator.java | 9 ++ .../internal/os/VideoPowerCalculator.java | 33 ++++++- .../internal/os/WakelockPowerCalculator.java | 28 +++++- .../internal/os/WifiPowerCalculator.java | 11 +++ .../res/drawable/gm_device_24.xml | 10 +++ .../BatteryConsumerData.java | 18 +++- .../BatteryConsumerInfoHelper.java | 36 ++++++-- .../BatteryConsumerPickerFragment.java | 30 +++++-- .../BatteryStatsViewerActivity.java | 9 +- .../os/AmbientDisplayPowerCalculatorTest.java | 21 ++--- .../internal/os/AudioPowerCalculatorTest.java | 14 +++ .../internal/os/BatteryUsageStatsRule.java | 11 +++ .../internal/os/BatteryUsageStatsTest.java | 50 +++++++++++ .../os/BluetoothPowerCalculatorTest.java | 34 ++++---- .../os/CameraPowerCalculatorTest.java | 20 ++++- .../internal/os/CpuPowerCalculatorTest.java | 24 ++++++ .../os/CustomMeasuredPowerCalculatorTest.java | 16 ++++ .../internal/os/GnssPowerCalculatorTest.java | 24 ++++++ .../internal/os/IdlePowerCalculatorTest.java | 12 +++ .../os/MobileRadioPowerCalculatorTest.java | 24 ++++++ .../os/ScreenPowerCalculatorTest.java | 39 +++++++++ .../os/SensorPowerCalculatorTest.java | 18 ++-- .../os/SystemServicePowerCalculatorTest.java | 6 ++ .../internal/os/VideoPowerCalculatorTest.java | 14 +++ .../os/WakelockPowerCalculatorTest.java | 10 +++ .../internal/os/WifiPowerCalculatorTest.java | 28 ++++++ 43 files changed, 887 insertions(+), 90 deletions(-) create mode 100644 core/java/android/os/AggregateBatteryConsumer.java create mode 100644 core/tests/batterystatstests/BatteryStatsViewer/res/drawable/gm_device_24.xml diff --git a/core/java/android/os/AggregateBatteryConsumer.java b/core/java/android/os/AggregateBatteryConsumer.java new file mode 100644 index 0000000000000..bcf41cce7e7ce --- /dev/null +++ b/core/java/android/os/AggregateBatteryConsumer.java @@ -0,0 +1,74 @@ +/* + * 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 android.os; + +import android.annotation.NonNull; + +/** + * Contains power consumption data across the entire device. + * + * {@hide} + */ +public final class AggregateBatteryConsumer extends BatteryConsumer implements Parcelable { + + public AggregateBatteryConsumer(@NonNull Builder builder) { + super(builder.mPowerComponentsBuilder.build()); + } + + private AggregateBatteryConsumer(@NonNull Parcel source) { + super(new PowerComponents(source)); + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + super.writeToParcel(dest, flags); + } + + @Override + public int describeContents() { + return 0; + } + + @NonNull + public static final Creator CREATOR = + new Creator() { + public AggregateBatteryConsumer createFromParcel(@NonNull Parcel source) { + return new AggregateBatteryConsumer(source); + } + + public AggregateBatteryConsumer[] newArray(int size) { + return new AggregateBatteryConsumer[size]; + } + }; + + /** + * Builder for DeviceBatteryConsumer. + */ + public static final class Builder extends BaseBuilder { + public Builder(@NonNull String[] customPowerComponentNames, boolean includePowerModels) { + super(customPowerComponentNames, includePowerModels); + } + + /** + * Creates a read-only object out of the Builder values. + */ + @NonNull + public AggregateBatteryConsumer build() { + return new AggregateBatteryConsumer(this); + } + } +} diff --git a/core/java/android/os/BatteryConsumer.java b/core/java/android/os/BatteryConsumer.java index 32ca92cc97b0f..6b628b0140e6a 100644 --- a/core/java/android/os/BatteryConsumer.java +++ b/core/java/android/os/BatteryConsumer.java @@ -27,7 +27,7 @@ import java.lang.annotation.RetentionPolicy; * * @hide */ -public abstract class BatteryConsumer { +public class BatteryConsumer { /** * Power usage component, describing the particular part of the system @@ -72,14 +72,15 @@ public abstract class BatteryConsumer { public static final int POWER_COMPONENT_WIFI = 11; public static final int POWER_COMPONENT_WAKELOCK = 12; public static final int POWER_COMPONENT_MEMORY = 13; - public static final int POWER_COMPONENT_PHONE = 13; - public static final int POWER_COMPONENT_IDLE = 15; + public static final int POWER_COMPONENT_PHONE = 14; + public static final int POWER_COMPONENT_AMBIENT_DISPLAY = 15; + public static final int POWER_COMPONENT_IDLE = 16; // 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 = 16; + public static final int POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS = 17; - public static final int POWER_COMPONENT_COUNT = 17; + public static final int POWER_COMPONENT_COUNT = 18; public static final int FIRST_CUSTOM_POWER_COMPONENT_ID = 1000; public static final int LAST_CUSTOM_POWER_COMPONENT_ID = 9999; diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java index efdef62d98ff5..e3af4834c3414 100644 --- a/core/java/android/os/BatteryUsageStats.java +++ b/core/java/android/os/BatteryUsageStats.java @@ -16,6 +16,7 @@ package android.os; +import android.annotation.IntDef; import android.annotation.NonNull; import android.util.Range; import android.util.SparseArray; @@ -23,15 +24,53 @@ import android.util.SparseArray; import com.android.internal.os.BatteryStatsHistory; import com.android.internal.os.BatteryStatsHistoryIterator; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; /** * Contains a snapshot of battery attribution data, on a per-subsystem and per-UID basis. + *

+ * The totals for the entire device are returned as AggregateBatteryConsumers, which can be + * obtained by calling {@link #getAggregateBatteryConsumer(int)}. + *

+ * Power attributed to individual apps is returned as UidBatteryConsumers, see + * {@link #getUidBatteryConsumers()}. * * @hide */ public final class BatteryUsageStats implements Parcelable { + + /** + * Scope of battery stats included in a BatteryConsumer: the entire device, just + * the apps, etc. + * + * @hide + */ + @IntDef(prefix = {"AGGREGATE_BATTERY_CONSUMER_SCOPE_"}, value = { + AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE, + AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS, + }) + @Retention(RetentionPolicy.SOURCE) + public static @interface AggregateBatteryConsumerScope { + } + + /** + * Power consumption by the entire device, since last charge. The power usage in this + * scope includes both the power attributed to apps and the power unattributed to any + * apps. + */ + public static final int AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE = 0; + + /** + * Aggregated power consumed by all applications, combined, since last charge. This is + * the sum of power reported in UidBatteryConsumers. + */ + public static final int AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS = 1; + + public static final int AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT = 2; + private final double mConsumedPower; private final int mDischargePercentage; private final long mStatsStartTimestampMs; @@ -43,6 +82,7 @@ public final class BatteryUsageStats implements Parcelable { private final List mUidBatteryConsumers; private final List mSystemBatteryConsumers; private final List mUserBatteryConsumers; + private final AggregateBatteryConsumer[] mAggregateBatteryConsumers; private final Parcel mHistoryBuffer; private final List mHistoryTagPool; @@ -57,6 +97,12 @@ public final class BatteryUsageStats implements Parcelable { mChargeTimeRemainingMs = builder.mChargeTimeRemainingMs; mCustomPowerComponentNames = builder.mCustomPowerComponentNames; + mAggregateBatteryConsumers = + new AggregateBatteryConsumer[AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT]; + for (int i = 0; i < AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT; i++) { + mAggregateBatteryConsumers[i] = builder.mAggregateBatteryConsumersBuilders[i].build(); + } + double totalPower = 0; final int uidBatteryConsumerCount = builder.mUidBatteryConsumerBuilders.size(); @@ -143,6 +189,14 @@ public final class BatteryUsageStats implements Parcelable { return mConsumedPower; } + /** + * Returns a battery consumer for the specified battery consumer type. + */ + public BatteryConsumer getAggregateBatteryConsumer( + @AggregateBatteryConsumerScope int scope) { + return mAggregateBatteryConsumers[scope]; + } + @NonNull public List getUidBatteryConsumers() { return mUidBatteryConsumers; @@ -185,6 +239,13 @@ public final class BatteryUsageStats implements Parcelable { mBatteryTimeRemainingMs = source.readLong(); mChargeTimeRemainingMs = source.readLong(); mCustomPowerComponentNames = source.readStringArray(); + mAggregateBatteryConsumers = + new AggregateBatteryConsumer[AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT]; + for (int i = 0; i < AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT; i++) { + mAggregateBatteryConsumers[i] = + AggregateBatteryConsumer.CREATOR.createFromParcel(source); + mAggregateBatteryConsumers[i].setCustomPowerComponentNames(mCustomPowerComponentNames); + } int uidCount = source.readInt(); mUidBatteryConsumers = new ArrayList<>(uidCount); for (int i = 0; i < uidCount; i++) { @@ -244,6 +305,9 @@ public final class BatteryUsageStats implements Parcelable { dest.writeLong(mBatteryTimeRemainingMs); dest.writeLong(mChargeTimeRemainingMs); dest.writeStringArray(mCustomPowerComponentNames); + for (int i = 0; i < AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT; i++) { + mAggregateBatteryConsumers[i].writeToParcel(dest, flags); + } dest.writeInt(mUidBatteryConsumers.size()); for (int i = mUidBatteryConsumers.size() - 1; i >= 0; i--) { mUidBatteryConsumers.get(i).writeToParcel(dest, flags); @@ -299,6 +363,8 @@ public final class BatteryUsageStats implements Parcelable { private double mDischargedPowerUpperBoundMah; private long mBatteryTimeRemainingMs = -1; private long mChargeTimeRemainingMs = -1; + private final AggregateBatteryConsumer.Builder[] mAggregateBatteryConsumersBuilders = + new AggregateBatteryConsumer.Builder[AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT]; private final SparseArray mUidBatteryConsumerBuilders = new SparseArray<>(); private final SparseArray mSystemBatteryConsumerBuilders = @@ -315,6 +381,10 @@ public final class BatteryUsageStats implements Parcelable { public Builder(@NonNull String[] customPowerComponentNames, boolean includePowerModels) { mCustomPowerComponentNames = customPowerComponentNames; mIncludePowerModels = includePowerModels; + for (int i = 0; i < AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT; i++) { + mAggregateBatteryConsumersBuilders[i] = new AggregateBatteryConsumer.Builder( + customPowerComponentNames, includePowerModels); + } } /** @@ -386,7 +456,17 @@ public final class BatteryUsageStats implements Parcelable { } /** - * Creates or returns a exiting UidBatteryConsumer, which represents battery attribution + * Creates or returns an AggregateBatteryConsumer builder, which represents aggregate + * battery consumption data for the specified scope. + */ + @NonNull + public AggregateBatteryConsumer.Builder getAggregateBatteryConsumerBuilder( + @AggregateBatteryConsumerScope int scope) { + return mAggregateBatteryConsumersBuilders[scope]; + } + + /** + * Creates or returns a UidBatteryConsumer, which represents battery attribution * data for an individual UID. */ @NonNull @@ -403,7 +483,7 @@ public final class BatteryUsageStats implements Parcelable { } /** - * Creates or returns a exiting SystemBatteryConsumer, which represents battery attribution + * Creates or returns a SystemBatteryConsumer, which represents battery attribution * data for a specific drain type. */ @NonNull @@ -419,7 +499,7 @@ public final class BatteryUsageStats implements Parcelable { } /** - * Creates or returns a exiting UserBatteryConsumer, which represents battery attribution + * Creates or returns a UserBatteryConsumer, which represents battery attribution * data for an individual {@link UserHandle}. */ @NonNull diff --git a/core/java/com/android/internal/os/AmbientDisplayPowerCalculator.java b/core/java/com/android/internal/os/AmbientDisplayPowerCalculator.java index 73d962effc003..100bf34203e76 100644 --- a/core/java/com/android/internal/os/AmbientDisplayPowerCalculator.java +++ b/core/java/com/android/internal/os/AmbientDisplayPowerCalculator.java @@ -50,8 +50,14 @@ public class AmbientDisplayPowerCalculator extends PowerCalculator { BatteryStats.STATS_SINCE_CHARGED); final double powerMah = getMeasuredOrEstimatedPower(powerModel, measuredEnergyUC, mPowerEstimator, durationMs); + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY, durationMs) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY, + powerMah, powerModel); + builder.getOrCreateSystemBatteryConsumerBuilder( - SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY) + SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY) .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, powerMah, powerModel) .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN, durationMs); } diff --git a/core/java/com/android/internal/os/AudioPowerCalculator.java b/core/java/com/android/internal/os/AudioPowerCalculator.java index 9da8191f37475..2eab506bbb6c6 100644 --- a/core/java/com/android/internal/os/AudioPowerCalculator.java +++ b/core/java/com/android/internal/os/AudioPowerCalculator.java @@ -17,8 +17,10 @@ package com.android.internal.os; import android.os.BatteryConsumer; import android.os.BatteryStats; +import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; import android.os.UidBatteryConsumer; +import android.util.SparseArray; /** * A {@link PowerCalculator} to calculate power consumed by audio hardware. @@ -31,18 +33,47 @@ public class AudioPowerCalculator extends PowerCalculator { // TODO(b/175344313): improve the model by taking into account different audio routes private final UsageBasedPowerEstimator mPowerEstimator; + private static class PowerAndDuration { + public long durationMs; + public double powerMah; + } + public AudioPowerCalculator(PowerProfile powerProfile) { mPowerEstimator = new UsageBasedPowerEstimator( powerProfile.getAveragePower(PowerProfile.POWER_AUDIO)); } @Override - protected void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u, + public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { + final PowerAndDuration total = new PowerAndDuration(); + + final SparseArray uidBatteryConsumerBuilders = + builder.getUidBatteryConsumerBuilders(); + for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) { + final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i); + calculateApp(app, total, app.getBatteryStatsUid(), rawRealtimeUs); + } + + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_AUDIO, total.durationMs) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_AUDIO, total.powerMah); + + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_AUDIO, total.durationMs) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_AUDIO, total.powerMah); + } + + private void calculateApp(UidBatteryConsumer.Builder app, PowerAndDuration total, + BatteryStats.Uid u, long rawRealtimeUs) { final long durationMs = mPowerEstimator.calculateDuration(u.getAudioTurnedOnTimer(), rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED); final double powerMah = mPowerEstimator.calculatePower(durationMs); app.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_AUDIO, durationMs) .setConsumedPower(BatteryConsumer.POWER_COMPONENT_AUDIO, powerMah); + total.durationMs += durationMs; + total.powerMah += powerMah; } } diff --git a/core/java/com/android/internal/os/BluetoothPowerCalculator.java b/core/java/com/android/internal/os/BluetoothPowerCalculator.java index 2c32e48c9685a..36f871b286556 100644 --- a/core/java/com/android/internal/os/BluetoothPowerCalculator.java +++ b/core/java/com/android/internal/os/BluetoothPowerCalculator.java @@ -93,6 +93,18 @@ public class BluetoothPowerCalculator extends PowerCalculator { .setConsumedPower(BatteryConsumer.POWER_COMPONENT_BLUETOOTH, Math.max(systemPowerMah, total.powerMah), powerModel) .setPowerConsumedByApps(total.powerMah); + + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_BLUETOOTH, systemDurationMs) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_BLUETOOTH, + Math.max(systemPowerMah, total.powerMah), powerModel); + + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_BLUETOOTH, total.durationMs) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_BLUETOOTH, total.powerMah, + powerModel); } private void calculateApp(UidBatteryConsumer.Builder app, PowerAndDuration total, diff --git a/core/java/com/android/internal/os/CameraPowerCalculator.java b/core/java/com/android/internal/os/CameraPowerCalculator.java index e56e7beddecba..ddcabe869b326 100644 --- a/core/java/com/android/internal/os/CameraPowerCalculator.java +++ b/core/java/com/android/internal/os/CameraPowerCalculator.java @@ -17,6 +17,7 @@ package com.android.internal.os; import android.os.BatteryConsumer; import android.os.BatteryStats; +import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; import android.os.UidBatteryConsumer; @@ -35,6 +36,24 @@ public class CameraPowerCalculator extends PowerCalculator { profile.getAveragePower(PowerProfile.POWER_CAMERA)); } + @Override + public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, + long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { + super.calculate(builder, batteryStats, rawRealtimeUs, rawUptimeUs, query); + + final long durationMs = batteryStats.getCameraOnTime(rawRealtimeUs, + BatteryStats.STATS_SINCE_CHARGED) / 1000; + final double powerMah = mPowerEstimator.calculatePower(durationMs); + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_CAMERA, durationMs) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA, powerMah); + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_CAMERA, durationMs) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA, powerMah); + } + @Override protected void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/CpuPowerCalculator.java b/core/java/com/android/internal/os/CpuPowerCalculator.java index 2a55aa9daf6cc..0d041c4440d21 100644 --- a/core/java/com/android/internal/os/CpuPowerCalculator.java +++ b/core/java/com/android/internal/os/CpuPowerCalculator.java @@ -80,13 +80,28 @@ public class CpuPowerCalculator extends PowerCalculator { @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { + double totalPowerMah = 0; + Result result = new Result(); final SparseArray uidBatteryConsumerBuilders = builder.getUidBatteryConsumerBuilders(); for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) { final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i); calculateApp(app, app.getBatteryStatsUid(), query, result); + totalPowerMah += result.powerMah; } + + final long consumptionUC = batteryStats.getCpuMeasuredBatteryConsumptionUC(); + final int powerModel = getPowerModel(consumptionUC, query); + + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, totalPowerMah); + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, + powerModel == BatteryConsumer.POWER_MODEL_MEASURED_ENERGY + ? uCtoMah(consumptionUC) : totalPowerMah, powerModel); } private void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u, diff --git a/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java b/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java index 9941e30f5d1cd..9af11fe7614a6 100644 --- a/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java +++ b/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java @@ -15,12 +15,14 @@ */ package com.android.internal.os; +import android.os.AggregateBatteryConsumer; import android.os.BatteryConsumer; import android.os.BatteryStats; import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; import android.os.SystemBatteryConsumer; import android.os.UidBatteryConsumer; +import android.util.SparseArray; /** * Calculates the amount of power consumed by custom energy consumers (i.e. consumers of type @@ -33,7 +35,15 @@ 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); + double[] totalAppPowerMah = null; + + final SparseArray uidBatteryConsumerBuilders = + builder.getUidBatteryConsumerBuilders(); + for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) { + final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i); + totalAppPowerMah = calculateApp(app, app.getBatteryStatsUid(), totalAppPowerMah); + } + final double[] customMeasuredPowerMah = calculateMeasuredEnergiesMah( batteryStats.getCustomConsumerMeasuredBatteryConsumptionUC()); if (customMeasuredPowerMah != null) { @@ -45,21 +55,51 @@ public class CustomMeasuredPowerCalculator extends PowerCalculator { 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.getCustomConsumerMeasuredBatteryConsumptionUC()); - if (customMeasuredPowerMah != null) { + final AggregateBatteryConsumer.Builder deviceBatteryConsumerBuilder = + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE); for (int i = 0; i < customMeasuredPowerMah.length; i++) { - app.setConsumedPowerForCustomComponent( + deviceBatteryConsumerBuilder.setConsumedPowerForCustomComponent( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i, customMeasuredPowerMah[i]); } } + if (totalAppPowerMah != null) { + final AggregateBatteryConsumer.Builder appsBatteryConsumerBuilder = + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS); + for (int i = 0; i < totalAppPowerMah.length; i++) { + appsBatteryConsumerBuilder.setConsumedPowerForCustomComponent( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i, + totalAppPowerMah[i]); + } + } + } + + private double[] calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u, + double[] totalPowerMah) { + double[] newTotalPowerMah = null; + final double[] customMeasuredPowerMah = calculateMeasuredEnergiesMah( + u.getCustomConsumerMeasuredBatteryConsumptionUC()); + if (customMeasuredPowerMah != null) { + if (totalPowerMah == null) { + newTotalPowerMah = new double[customMeasuredPowerMah.length]; + } else if (totalPowerMah.length != customMeasuredPowerMah.length) { + newTotalPowerMah = new double[customMeasuredPowerMah.length]; + System.arraycopy(totalPowerMah, 0, newTotalPowerMah, 0, + customMeasuredPowerMah.length); + } else { + newTotalPowerMah = totalPowerMah; + } + for (int i = 0; i < customMeasuredPowerMah.length; i++) { + app.setConsumedPowerForCustomComponent( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i, + customMeasuredPowerMah[i]); + newTotalPowerMah[i] += customMeasuredPowerMah[i]; + } + } + return newTotalPowerMah; } @Override diff --git a/core/java/com/android/internal/os/FlashlightPowerCalculator.java b/core/java/com/android/internal/os/FlashlightPowerCalculator.java index cbe0cde2f5b79..32df17c51aace 100644 --- a/core/java/com/android/internal/os/FlashlightPowerCalculator.java +++ b/core/java/com/android/internal/os/FlashlightPowerCalculator.java @@ -17,6 +17,7 @@ package com.android.internal.os; import android.os.BatteryConsumer; import android.os.BatteryStats; +import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; import android.os.UidBatteryConsumer; @@ -33,6 +34,24 @@ public class FlashlightPowerCalculator extends PowerCalculator { profile.getAveragePower(PowerProfile.POWER_FLASHLIGHT)); } + @Override + public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, + long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { + super.calculate(builder, batteryStats, rawRealtimeUs, rawUptimeUs, query); + + final long durationMs = batteryStats.getFlashlightOnTime(rawRealtimeUs, + BatteryStats.STATS_SINCE_CHARGED) / 1000; + final double powerMah = mPowerEstimator.calculatePower(durationMs); + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT, durationMs) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT, powerMah); + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT, durationMs) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT, powerMah); + } + @Override protected void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { diff --git a/core/java/com/android/internal/os/GnssPowerCalculator.java b/core/java/com/android/internal/os/GnssPowerCalculator.java index 7eb4b4a9bb1cd..a508e039fe714 100644 --- a/core/java/com/android/internal/os/GnssPowerCalculator.java +++ b/core/java/com/android/internal/os/GnssPowerCalculator.java @@ -46,6 +46,7 @@ public class GnssPowerCalculator extends PowerCalculator { @Override public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { + double appsPowerMah = 0; final double averageGnssPowerMa = getAverageGnssPower(batteryStats, rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED); final SparseArray uidBatteryConsumerBuilders = @@ -55,12 +56,27 @@ public class GnssPowerCalculator extends PowerCalculator { final long consumptionUC = app.getBatteryStatsUid().getGnssMeasuredBatteryConsumptionUC(); final int powerModel = getPowerModel(consumptionUC, query); - calculateApp(app, app.getBatteryStatsUid(), powerModel, rawRealtimeUs, - averageGnssPowerMa, consumptionUC); + appsPowerMah += calculateApp(app, app.getBatteryStatsUid(), powerModel, + rawRealtimeUs, averageGnssPowerMa, consumptionUC); } + + final long consumptionUC = batteryStats.getGnssMeasuredBatteryConsumptionUC(); + final int powerModel = getPowerModel(consumptionUC, query); + double powerMah; + if (powerModel == BatteryConsumer.POWER_MODEL_MEASURED_ENERGY) { + powerMah = uCtoMah(consumptionUC); + } else { + powerMah = appsPowerMah; + } + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS, powerMah, powerModel); + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS, appsPowerMah, powerModel); } - private void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u, + private double calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u, @BatteryConsumer.PowerModel int powerModel, long rawRealtimeUs, double averageGnssPowerMa, long measuredChargeUC) { final long durationMs = computeDuration(u, rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED); @@ -76,6 +92,7 @@ public class GnssPowerCalculator extends PowerCalculator { app.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_GNSS, durationMs) .setConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS, powerMah, powerModel); + return powerMah; } @Override diff --git a/core/java/com/android/internal/os/IdlePowerCalculator.java b/core/java/com/android/internal/os/IdlePowerCalculator.java index 0c80deb492594..cf68ab9a2066d 100644 --- a/core/java/com/android/internal/os/IdlePowerCalculator.java +++ b/core/java/com/android/internal/os/IdlePowerCalculator.java @@ -56,6 +56,10 @@ public class IdlePowerCalculator extends PowerCalculator { builder.getOrCreateSystemBatteryConsumerBuilder(SystemBatteryConsumer.DRAIN_TYPE_IDLE) .setConsumedPower(BatteryConsumer.POWER_COMPONENT_IDLE, mPowerMah) .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_IDLE, mDurationMs); + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_IDLE, mPowerMah) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_IDLE, mDurationMs); } } diff --git a/core/java/com/android/internal/os/MemoryPowerCalculator.java b/core/java/com/android/internal/os/MemoryPowerCalculator.java index 5d5c1558f7169..950d1ecec3b3d 100644 --- a/core/java/com/android/internal/os/MemoryPowerCalculator.java +++ b/core/java/com/android/internal/os/MemoryPowerCalculator.java @@ -34,6 +34,10 @@ public class MemoryPowerCalculator extends PowerCalculator { builder.getOrCreateSystemBatteryConsumerBuilder(SystemBatteryConsumer.DRAIN_TYPE_MEMORY) .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_MEMORY, durationMs) .setConsumedPower(BatteryConsumer.POWER_COMPONENT_MEMORY, powerMah); + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_MEMORY, durationMs) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_MEMORY, powerMah); } @Override diff --git a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java index 4db15a44231e5..a1bab6eb21f69 100644 --- a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java +++ b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java @@ -113,6 +113,20 @@ public class MobileRadioPowerCalculator extends PowerCalculator { total.remainingPowerMah + total.totalAppPowerMah, powerModel) .setPowerConsumedByApps(total.totalAppPowerMah); + + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO, + total.durationMs) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO, + total.remainingPowerMah + total.totalAppPowerMah, powerModel); + + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO, + total.durationMs) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO, + total.totalAppPowerMah, powerModel); } } diff --git a/core/java/com/android/internal/os/PhonePowerCalculator.java b/core/java/com/android/internal/os/PhonePowerCalculator.java index 2e3bff32cc389..f8997cbbd9c94 100644 --- a/core/java/com/android/internal/os/PhonePowerCalculator.java +++ b/core/java/com/android/internal/os/PhonePowerCalculator.java @@ -47,6 +47,10 @@ public class PhonePowerCalculator extends PowerCalculator { builder.getOrCreateSystemBatteryConsumerBuilder(SystemBatteryConsumer.DRAIN_TYPE_PHONE) .setConsumedPower(BatteryConsumer.POWER_COMPONENT_PHONE, phoneOnPower) .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_PHONE, phoneOnTimeMs); + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_PHONE, phoneOnPower) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_PHONE, phoneOnTimeMs); } } diff --git a/core/java/com/android/internal/os/ScreenPowerCalculator.java b/core/java/com/android/internal/os/ScreenPowerCalculator.java index dc0f719c042bc..44bed2a54a102 100644 --- a/core/java/com/android/internal/os/ScreenPowerCalculator.java +++ b/core/java/com/android/internal/os/ScreenPowerCalculator.java @@ -68,6 +68,7 @@ public class ScreenPowerCalculator extends PowerCalculator { rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED, consumptionUC); double totalAppPower = 0; + long totalAppDuration = 0; // Now deal with each app's UidBatteryConsumer. The results are stored in the // BatteryConsumer.POWER_COMPONENT_SCREEN power component, which is considered smeared, @@ -86,6 +87,7 @@ public class ScreenPowerCalculator extends PowerCalculator { .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, appPowerAndDuration.powerMah, powerModel); totalAppPower += appPowerAndDuration.powerMah; + totalAppDuration += appPowerAndDuration.durationMs; } break; case BatteryConsumer.POWER_MODEL_POWER_PROFILE: @@ -93,8 +95,21 @@ public class ScreenPowerCalculator extends PowerCalculator { smearScreenBatteryDrain(uidBatteryConsumerBuilders, totalPowerAndDuration, rawRealtimeUs); totalAppPower = totalPowerAndDuration.powerMah; + totalAppDuration = totalPowerAndDuration.durationMs; } + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, + Math.max(totalPowerAndDuration.powerMah, totalAppPower), powerModel) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN, + totalPowerAndDuration.durationMs); + + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, totalAppPower, powerModel) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN, totalAppDuration); + builder.getOrCreateSystemBatteryConsumerBuilder(SystemBatteryConsumer.DRAIN_TYPE_SCREEN) .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN, totalPowerAndDuration.durationMs) diff --git a/core/java/com/android/internal/os/SensorPowerCalculator.java b/core/java/com/android/internal/os/SensorPowerCalculator.java index d18b7b1f69c2d..83e5b5702b6c6 100644 --- a/core/java/com/android/internal/os/SensorPowerCalculator.java +++ b/core/java/com/android/internal/os/SensorPowerCalculator.java @@ -19,6 +19,7 @@ import android.hardware.Sensor; import android.hardware.SensorManager; import android.os.BatteryConsumer; import android.os.BatteryStats; +import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; import android.os.UidBatteryConsumer; import android.util.SparseArray; @@ -38,12 +39,32 @@ public class SensorPowerCalculator extends PowerCalculator { } @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 appsPowerMah = 0; + final SparseArray uidBatteryConsumerBuilders = + builder.getUidBatteryConsumerBuilders(); + for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) { + final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i); + appsPowerMah += calculateApp(app, app.getBatteryStatsUid(), rawRealtimeUs); + } + + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SENSORS, appsPowerMah); + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SENSORS, appsPowerMah); + } + + private double calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u, + long rawRealtimeUs) { + final double powerMah = calculatePowerMah(u, rawRealtimeUs, + BatteryStats.STATS_SINCE_CHARGED); app.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SENSORS, calculateDuration(u, rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED)) - .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SENSORS, - calculatePowerMah(u, rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED)); + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SENSORS, powerMah); + return powerMah; } @Override diff --git a/core/java/com/android/internal/os/SystemServicePowerCalculator.java b/core/java/com/android/internal/os/SystemServicePowerCalculator.java index b4d5f97a14e7c..a26abc2ffab09 100644 --- a/core/java/com/android/internal/os/SystemServicePowerCalculator.java +++ b/core/java/com/android/internal/os/SystemServicePowerCalculator.java @@ -87,6 +87,15 @@ public class SystemServicePowerCalculator extends PowerCalculator { systemServicePowerMah * uid.getProportionalSystemServiceUsage()); } } + + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SYSTEM_SERVICES, + systemServicePowerMah); + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SYSTEM_SERVICES, + systemServicePowerMah); } @Override diff --git a/core/java/com/android/internal/os/VideoPowerCalculator.java b/core/java/com/android/internal/os/VideoPowerCalculator.java index 0cad9a72ceec5..47916a6b09148 100644 --- a/core/java/com/android/internal/os/VideoPowerCalculator.java +++ b/core/java/com/android/internal/os/VideoPowerCalculator.java @@ -17,8 +17,10 @@ package com.android.internal.os; import android.os.BatteryConsumer; import android.os.BatteryStats; +import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; import android.os.UidBatteryConsumer; +import android.util.SparseArray; /** * A {@link PowerCalculator} to calculate power consumed by video hardware. @@ -28,18 +30,47 @@ import android.os.UidBatteryConsumer; public class VideoPowerCalculator extends PowerCalculator { private final UsageBasedPowerEstimator mPowerEstimator; + private static class PowerAndDuration { + public long durationMs; + public double powerMah; + } + public VideoPowerCalculator(PowerProfile powerProfile) { mPowerEstimator = new UsageBasedPowerEstimator( powerProfile.getAveragePower(PowerProfile.POWER_VIDEO)); } @Override - protected void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u, + public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { + final PowerAndDuration total = new PowerAndDuration(); + + final SparseArray uidBatteryConsumerBuilders = + builder.getUidBatteryConsumerBuilders(); + for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) { + final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i); + calculateApp(app, total, app.getBatteryStatsUid(), rawRealtimeUs); + } + + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_VIDEO, total.durationMs) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_VIDEO, total.powerMah); + + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_VIDEO, total.durationMs) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_VIDEO, total.powerMah); + } + + private void calculateApp(UidBatteryConsumer.Builder app, PowerAndDuration total, + BatteryStats.Uid u, long rawRealtimeUs) { final long durationMs = mPowerEstimator.calculateDuration(u.getVideoTurnedOnTimer(), rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED); final double powerMah = mPowerEstimator.calculatePower(durationMs); app.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_VIDEO, durationMs) .setConsumedPower(BatteryConsumer.POWER_COMPONENT_VIDEO, powerMah); + total.durationMs += durationMs; + total.powerMah += powerMah; } } diff --git a/core/java/com/android/internal/os/WakelockPowerCalculator.java b/core/java/com/android/internal/os/WakelockPowerCalculator.java index 194b6b82cd53d..d5941072acf9d 100644 --- a/core/java/com/android/internal/os/WakelockPowerCalculator.java +++ b/core/java/com/android/internal/os/WakelockPowerCalculator.java @@ -51,6 +51,7 @@ public class WakelockPowerCalculator extends PowerCalculator { double osPowerMah = 0; long osDurationMs = 0; long totalAppDurationMs = 0; + double appPowerMah = 0; final SparseArray uidBatteryConsumerBuilders = builder.getUidBatteryConsumerBuilders(); for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) { @@ -60,6 +61,7 @@ public class WakelockPowerCalculator extends PowerCalculator { app.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WAKELOCK, result.durationMs) .setConsumedPower(BatteryConsumer.POWER_COMPONENT_WAKELOCK, result.powerMah); totalAppDurationMs += result.durationMs; + appPowerMah += result.powerMah; if (app.getUid() == Process.ROOT_UID) { osBatteryConsumer = app; @@ -71,13 +73,24 @@ public class WakelockPowerCalculator extends PowerCalculator { // The device has probably been awake for longer than the screen on // time and application wake lock time would account for. Assign // this remainder to the OS, if possible. + calculateRemaining(result, batteryStats, rawRealtimeUs, rawUptimeUs, + BatteryStats.STATS_SINCE_CHARGED, osPowerMah, osDurationMs, totalAppDurationMs); if (osBatteryConsumer != null) { - calculateRemaining(result, batteryStats, rawRealtimeUs, rawUptimeUs, - BatteryStats.STATS_SINCE_CHARGED, osPowerMah, osDurationMs, totalAppDurationMs); osBatteryConsumer.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WAKELOCK, result.durationMs) .setConsumedPower(BatteryConsumer.POWER_COMPONENT_WAKELOCK, result.powerMah); } + + final long wakeTimeMillis = + calculateWakeTimeMillis(batteryStats, rawRealtimeUs, rawUptimeUs); + final double powerMah = mPowerEstimator.calculatePower(wakeTimeMillis); + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WAKELOCK, wakeTimeMillis) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_WAKELOCK, powerMah); + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_WAKELOCK, appPowerMah); } @Override @@ -145,8 +158,7 @@ public class WakelockPowerCalculator extends PowerCalculator { private void calculateRemaining(PowerAndDuration result, BatteryStats stats, long rawRealtimeUs, long rawUptimeUs, int statsType, double osPowerMah, long osDurationMs, long totalAppDurationMs) { - final long wakeTimeMillis = stats.getBatteryUptime(rawUptimeUs) / 1000 - - stats.getScreenOnTime(rawRealtimeUs, statsType) / 1000 + final long wakeTimeMillis = calculateWakeTimeMillis(stats, rawRealtimeUs, rawUptimeUs) - totalAppDurationMs; if (wakeTimeMillis > 0) { final double power = mPowerEstimator.calculatePower(wakeTimeMillis); @@ -157,4 +169,12 @@ public class WakelockPowerCalculator extends PowerCalculator { result.powerMah = osPowerMah + power; } } + + private long calculateWakeTimeMillis(BatteryStats batteryStats, long rawRealtimeUs, + long rawUptimeUs) { + final long batteryUptimeUs = batteryStats.getBatteryUptime(rawUptimeUs); + final long screenOnTimeUs = + batteryStats.getScreenOnTime(rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED); + return (batteryUptimeUs - screenOnTimeUs) / 1000; + } } diff --git a/core/java/com/android/internal/os/WifiPowerCalculator.java b/core/java/com/android/internal/os/WifiPowerCalculator.java index ef5b147e00e4d..2dfc4ee69e14b 100644 --- a/core/java/com/android/internal/os/WifiPowerCalculator.java +++ b/core/java/com/android/internal/os/WifiPowerCalculator.java @@ -123,6 +123,17 @@ public class WifiPowerCalculator extends PowerCalculator { .setConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI, totalAppPowerMah + powerDurationAndTraffic.powerMah, powerModel) .setPowerConsumedByApps(totalAppPowerMah); + + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) + .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WIFI, + powerDurationAndTraffic.durationMs) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI, + totalAppPowerMah + powerDurationAndTraffic.powerMah, powerModel); + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI, + totalAppPowerMah, powerModel); } /** diff --git a/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/gm_device_24.xml b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/gm_device_24.xml new file mode 100644 index 0000000000000..223cdf45b1665 --- /dev/null +++ b/core/tests/batterystatstests/BatteryStatsViewer/res/drawable/gm_device_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java index a15a8d8b3f476..da6dc76a68d24 100644 --- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java +++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java @@ -63,7 +63,7 @@ public class BatteryConsumerData { } mBatteryConsumerInfo = BatteryConsumerInfoHelper.makeBatteryConsumerInfo( - context.getPackageManager(), requestedBatteryConsumer); + requestedBatteryConsumer, batteryConsumerId, context.getPackageManager()); double[] totalPowerByComponentMah = new double[BatteryConsumer.POWER_COMPONENT_COUNT]; double[] totalModeledPowerByComponentMah = @@ -119,11 +119,20 @@ public class BatteryConsumerData { private BatteryConsumer getRequestedBatteryConsumer(BatteryUsageStats batteryUsageStats, String batteryConsumerId) { + for (int scope = 0; + scope < BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT; + scope++) { + if (batteryConsumerId(scope).equals(batteryConsumerId)) { + return batteryUsageStats.getAggregateBatteryConsumer(scope); + } + } + for (BatteryConsumer consumer : batteryUsageStats.getUidBatteryConsumers()) { if (batteryConsumerId(consumer).equals(batteryConsumerId)) { return consumer; } } + for (BatteryConsumer consumer : batteryUsageStats.getSystemBatteryConsumers()) { if (batteryConsumerId(consumer).equals(batteryConsumerId)) { return consumer; @@ -209,4 +218,9 @@ public class BatteryConsumerData { return ""; } } -} + + public static String batteryConsumerId( + @BatteryUsageStats.AggregateBatteryConsumerScope int scope) { + return "SYS|" + scope; + } +} \ No newline at end of file diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java index 6288e0b886d15..c37b48bb5e6ae 100644 --- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java +++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java @@ -16,9 +16,12 @@ package com.android.frameworks.core.batterystatsviewer; +import static com.android.frameworks.core.batterystatsviewer.BatteryConsumerData.batteryConsumerId; + import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.BatteryConsumer; +import android.os.BatteryUsageStats; import android.os.Process; import android.os.SystemBatteryConsumer; import android.os.UidBatteryConsumer; @@ -41,10 +44,11 @@ class BatteryConsumerInfoHelper { } @NonNull - public static BatteryConsumerInfo makeBatteryConsumerInfo(PackageManager packageManager, - @NonNull BatteryConsumer batteryConsumer) { + public static BatteryConsumerInfo makeBatteryConsumerInfo( + @NonNull BatteryConsumer batteryConsumer, String batteryConsumerId, + PackageManager packageManager) { BatteryConsumerInfo info = new BatteryConsumerInfo(); - info.id = BatteryConsumerData.batteryConsumerId(batteryConsumer); + info.id = batteryConsumerId; info.powerMah = batteryConsumer.getConsumedPower(); if (batteryConsumer instanceof UidBatteryConsumer) { @@ -100,6 +104,15 @@ class BatteryConsumerInfoHelper { info.packages = sb; } } + // Default the app icon to System Server. This includes root, dex2oat and other UIDs. + if (info.iconInfo == null) { + try { + info.iconInfo = + packageManager.getApplicationInfo(SYSTEM_SERVER_PACKAGE_NAME, 0); + } catch (PackageManager.NameNotFoundException nameNotFoundException) { + // Won't happen + } + } } else if (batteryConsumer instanceof SystemBatteryConsumer) { final SystemBatteryConsumer systemBatteryConsumer = (SystemBatteryConsumer) batteryConsumer; @@ -108,17 +121,26 @@ class BatteryConsumerInfoHelper { drainType); info.label = name.charAt(0) + name.substring(1).toLowerCase().replace('_', ' '); info.isSystemBatteryConsumer = true; - } - - // Default the app icon to System Server. This includes root, dex2oat and other UIDs. - if (info.iconInfo == null) { try { info.iconInfo = packageManager.getApplicationInfo(SYSTEM_SERVER_PACKAGE_NAME, 0); } catch (PackageManager.NameNotFoundException nameNotFoundException) { // Won't happen } + } else { + for (int scope = 0; + scope < BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT; + scope++) { + if (batteryConsumerId(scope).equals(batteryConsumerId)) { + final String name = DebugUtils.constantToString(BatteryUsageStats.class, + "AGGREGATE_BATTERY_CONSUMER_SCOPE_", scope) + .replace('_', ' '); + info.label = name; + break; + } + } } + return info; } } diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerFragment.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerFragment.java index 49220877d31e9..daa6dae37f509 100644 --- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerFragment.java +++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerFragment.java @@ -112,14 +112,25 @@ public class BatteryConsumerPickerFragment extends Fragment { @Override public List loadInBackground() { final BatteryUsageStats batteryUsageStats = mBatteryStatsManager.getBatteryUsageStats(); - List batteryConsumerList = new ArrayList<>(); + + for (int scope = 0; + scope < BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT; + scope++) { + batteryConsumerList.add( + BatteryConsumerInfoHelper.makeBatteryConsumerInfo( + batteryUsageStats.getAggregateBatteryConsumer(scope), + BatteryConsumerData.batteryConsumerId(scope), + mPackageManager)); + } + switch (mPickerType) { case PICKER_TYPE_APP: for (UidBatteryConsumer consumer : batteryUsageStats.getUidBatteryConsumers()) { batteryConsumerList.add( - BatteryConsumerInfoHelper.makeBatteryConsumerInfo(mPackageManager, - consumer)); + BatteryConsumerInfoHelper.makeBatteryConsumerInfo(consumer, + BatteryConsumerData.batteryConsumerId(consumer), + mPackageManager)); } break; case PICKER_TYPE_DRAIN: @@ -127,8 +138,9 @@ public class BatteryConsumerPickerFragment extends Fragment { for (SystemBatteryConsumer consumer : batteryUsageStats.getSystemBatteryConsumers()) { batteryConsumerList.add( - BatteryConsumerInfoHelper.makeBatteryConsumerInfo(mPackageManager, - consumer)); + BatteryConsumerInfoHelper.makeBatteryConsumerInfo(consumer, + BatteryConsumerData.batteryConsumerId(consumer), + mPackageManager)); } break; } @@ -208,8 +220,12 @@ public class BatteryConsumerPickerFragment extends Fragment { } viewHolder.powerView.setText( String.format(Locale.getDefault(), "%.1f mAh", item.powerMah)); - viewHolder.iconView.setImageDrawable( - item.iconInfo.loadIcon(getContext().getPackageManager())); + if (item.iconInfo != null) { + viewHolder.iconView.setImageDrawable( + item.iconInfo.loadIcon(getContext().getPackageManager())); + } else { + viewHolder.iconView.setImageResource(R.drawable.gm_device_24); + } if (item.packages != null) { viewHolder.packagesView.setText(item.packages); viewHolder.packagesView.setVisibility(View.VISIBLE); diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java index 03dde04519cef..f84e97a14297e 100644 --- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java +++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java @@ -183,9 +183,12 @@ public class BatteryStatsViewerActivity extends ComponentActivity { } else { mDetailsView.setVisibility(View.GONE); } - mIconView.setImageDrawable( - batteryConsumerInfo.iconInfo.loadIcon(getPackageManager())); - + if (batteryConsumerInfo.iconInfo != null) { + mIconView.setImageDrawable( + batteryConsumerInfo.iconInfo.loadIcon(getPackageManager())); + } else { + mIconView.setImageResource(R.drawable.gm_device_24); + } if (batteryConsumerInfo.packages != null) { mPackagesView.setText(batteryConsumerInfo.packages); mPackagesView.setVisibility(View.VISIBLE); diff --git a/core/tests/coretests/src/com/android/internal/os/AmbientDisplayPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/AmbientDisplayPowerCalculatorTest.java index 236c3daac272a..4a5528d2ca36a 100644 --- a/core/tests/coretests/src/com/android/internal/os/AmbientDisplayPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/AmbientDisplayPowerCalculatorTest.java @@ -19,7 +19,6 @@ package com.android.internal.os; import static com.google.common.truth.Truth.assertThat; import android.os.BatteryConsumer; -import android.os.SystemBatteryConsumer; import android.view.Display; import androidx.test.filters.SmallTest; @@ -62,15 +61,13 @@ public class AmbientDisplayPowerCalculatorTest { mStatsRule.apply(calculator); - SystemBatteryConsumer consumer = - mStatsRule.getSystemBatteryConsumer( - SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY); - assertThat(consumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN)) + BatteryConsumer consumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(consumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY)) .isEqualTo(90 * MINUTE_IN_MS); // 100,000,00 uC / 1000 (micro-/milli-) / 360 (seconds/hour) = 27.777778 mAh - assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN)) + assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY)) .isWithin(PRECISION).of(27.777778); - assertThat(consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN)) + assertThat(consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY)) .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); } @@ -88,14 +85,12 @@ public class AmbientDisplayPowerCalculatorTest { mStatsRule.apply(BatteryUsageStatsRule.POWER_PROFILE_MODEL_ONLY, calculator); - SystemBatteryConsumer consumer = - mStatsRule.getSystemBatteryConsumer( - SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY); - assertThat(consumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN)) + BatteryConsumer consumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(consumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY)) .isEqualTo(90 * MINUTE_IN_MS); - assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN)) + assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY)) .isWithin(PRECISION).of(15.0); - assertThat(consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN)) + assertThat(consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY)) .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE); } } diff --git a/core/tests/coretests/src/com/android/internal/os/AudioPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/AudioPowerCalculatorTest.java index c694d67cd97b4..81940edaed6af 100644 --- a/core/tests/coretests/src/com/android/internal/os/AudioPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/AudioPowerCalculatorTest.java @@ -56,5 +56,19 @@ public class AudioPowerCalculatorTest { .isEqualTo(1000); assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_AUDIO)) .isWithin(PRECISION).of(0.1); + + final BatteryConsumer deviceBatteryConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(deviceBatteryConsumer + .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_AUDIO)) + .isEqualTo(1000); + assertThat(deviceBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_AUDIO)) + .isWithin(PRECISION).of(0.1); + + final BatteryConsumer appsBatteryConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(appsBatteryConsumer + .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_AUDIO)) + .isEqualTo(1000); + assertThat(appsBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_AUDIO)) + .isWithin(PRECISION).of(0.1); } } 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 41fe372d5d9c9..4533fcb39cfe4 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java @@ -23,6 +23,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.net.NetworkStats; +import android.os.BatteryConsumer; import android.os.BatteryStats; import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; @@ -186,6 +187,16 @@ public class BatteryUsageStatsRule implements TestRule { return mBatteryUsageStats; } + public BatteryConsumer getDeviceBatteryConsumer() { + return mBatteryUsageStats.getAggregateBatteryConsumer( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE); + } + + public BatteryConsumer getAppsBatteryConsumer() { + return mBatteryUsageStats.getAggregateBatteryConsumer( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS); + } + public UidBatteryConsumer getUidBatteryConsumer(int uid) { for (UidBatteryConsumer ubc : mBatteryUsageStats.getUidBatteryConsumers()) { if (ubc.getUid() == uid) { diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java index 55302bcf3b8df..ad9906b918d7a 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java @@ -98,6 +98,28 @@ public class BatteryUsageStatsTest { BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10400) .setPowerConsumedByApps(20000); + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS) + .setConsumedPower( + BatteryConsumer.POWER_COMPONENT_CPU, 10100) + .setConsumedPowerForCustomComponent( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10200) + .setUsageDurationMillis( + BatteryConsumer.POWER_COMPONENT_CPU, 10300) + .setUsageDurationForCustomComponentMillis( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10400); + + builder.getAggregateBatteryConsumerBuilder( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) + .setConsumedPower( + BatteryConsumer.POWER_COMPONENT_CPU, 20100) + .setConsumedPowerForCustomComponent( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20200) + .setUsageDurationMillis( + BatteryConsumer.POWER_COMPONENT_CPU, 20300) + .setUsageDurationForCustomComponentMillis( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20400); + return builder.build(); } @@ -162,5 +184,33 @@ public class BatteryUsageStatsTest { fail("Unexpected drain type " + systemBatteryConsumer.getDrainType()); } } + + final BatteryConsumer appsBatteryConsumer = batteryUsageStats.getAggregateBatteryConsumer( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS); + assertThat(appsBatteryConsumer.getConsumedPower( + BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(10100); + assertThat(appsBatteryConsumer.getConsumedPowerForCustomComponent( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(10200); + assertThat(appsBatteryConsumer.getUsageDurationMillis( + BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(10300); + assertThat(appsBatteryConsumer.getUsageDurationForCustomComponentMillis( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(10400); + assertThat(appsBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1); + assertThat(appsBatteryConsumer.getCustomPowerComponentName( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo("FOO"); + + final BatteryConsumer deviceBatteryConsumer = batteryUsageStats.getAggregateBatteryConsumer( + BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE); + assertThat(deviceBatteryConsumer.getConsumedPower( + BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(20100); + assertThat(deviceBatteryConsumer.getConsumedPowerForCustomComponent( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(20200); + assertThat(deviceBatteryConsumer.getUsageDurationMillis( + BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(20300); + assertThat(deviceBatteryConsumer.getUsageDurationForCustomComponentMillis( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(20400); + assertThat(deviceBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1); + assertThat(deviceBatteryConsumer.getCustomPowerComponentName( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo("FOO"); } } diff --git a/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java index 8723195ab6fe7..a0de6d3c4573a 100644 --- a/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java @@ -24,7 +24,6 @@ import android.bluetooth.UidTraffic; import android.os.BatteryConsumer; import android.os.BatteryUsageStatsQuery; import android.os.Process; -import android.os.SystemBatteryConsumer; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -70,8 +69,11 @@ public class BluetoothPowerCalculatorTest { mStatsRule.getUidBatteryConsumer(APP_UID), 0.24722, 15000, BatteryConsumer.POWER_MODEL_POWER_PROFILE); assertBluetoothPowerAndDuration( - mStatsRule.getSystemBatteryConsumer(SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH), - 0.51944, 9000, 0.51944, 0.36111, BatteryConsumer.POWER_MODEL_POWER_PROFILE); + mStatsRule.getDeviceBatteryConsumer(), + 0.40555, 24000, BatteryConsumer.POWER_MODEL_POWER_PROFILE); + assertBluetoothPowerAndDuration( + mStatsRule.getAppsBatteryConsumer(), + 0.36111, 21000, BatteryConsumer.POWER_MODEL_POWER_PROFILE); } @Test @@ -98,8 +100,11 @@ public class BluetoothPowerCalculatorTest { mStatsRule.getUidBatteryConsumer(APP_UID), 0.2, 15000, BatteryConsumer.POWER_MODEL_POWER_PROFILE); assertBluetoothPowerAndDuration( - mStatsRule.getSystemBatteryConsumer(SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH), - 0.45, 9000, 0.45, 0.3, BatteryConsumer.POWER_MODEL_POWER_PROFILE); + mStatsRule.getDeviceBatteryConsumer(), + 0.35, 24000, BatteryConsumer.POWER_MODEL_POWER_PROFILE); + assertBluetoothPowerAndDuration( + mStatsRule.getAppsBatteryConsumer(), + 0.3, 21000, BatteryConsumer.POWER_MODEL_POWER_PROFILE); } @Test @@ -123,8 +128,11 @@ public class BluetoothPowerCalculatorTest { mStatsRule.getUidBatteryConsumer(APP_UID), 0.22950, 8416, BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); assertBluetoothPowerAndDuration( - mStatsRule.getSystemBatteryConsumer(SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH), - 0.43712, 3584, 0.43712, 0.33329, BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); + mStatsRule.getDeviceBatteryConsumer(), + 0.33333, 12000, BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); + assertBluetoothPowerAndDuration( + mStatsRule.getAppsBatteryConsumer(), + 0.33329, 11999, BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); } private void setDurationsAndPower( @@ -151,16 +159,4 @@ public class BluetoothPowerCalculatorTest { assertThat(usageDurationMillis).isEqualTo(durationMs); } - - private void assertBluetoothPowerAndDuration(@Nullable SystemBatteryConsumer batteryConsumer, - double powerMah, int durationMs, double consumedPower, double attributedPower, - @BatteryConsumer.PowerModel int powerModel) { - assertBluetoothPowerAndDuration(batteryConsumer, powerMah, durationMs, powerModel); - - assertThat(batteryConsumer.getConsumedPower()) - .isWithin(PRECISION).of(consumedPower); - - assertThat(batteryConsumer.getPowerConsumedByApps()) - .isWithin(PRECISION).of(attributedPower); - } } diff --git a/core/tests/coretests/src/com/android/internal/os/CameraPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/CameraPowerCalculatorTest.java index 61eb173837e8d..c40d8a0138c18 100644 --- a/core/tests/coretests/src/com/android/internal/os/CameraPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/CameraPowerCalculatorTest.java @@ -42,9 +42,9 @@ public class CameraPowerCalculatorTest { @Test public void testTimerBasedModel() { - BatteryStatsImpl.Uid uidStats = mStatsRule.getUidStats(APP_UID); - uidStats.noteCameraTurnedOnLocked(1000); - uidStats.noteCameraTurnedOffLocked(2000); + BatteryStatsImpl stats = mStatsRule.getBatteryStats(); + stats.noteCameraOnLocked(APP_UID, 1000, 1000); + stats.noteCameraOffLocked(APP_UID, 2000, 2000); CameraPowerCalculator calculator = new CameraPowerCalculator(mStatsRule.getPowerProfile()); @@ -56,5 +56,19 @@ public class CameraPowerCalculatorTest { .isEqualTo(1000); assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA)) .isWithin(PRECISION).of(0.1); + + final BatteryConsumer deviceBatteryConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(deviceBatteryConsumer + .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_CAMERA)) + .isEqualTo(1000); + assertThat(deviceBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA)) + .isWithin(PRECISION).of(0.1); + + final BatteryConsumer appsBatteryConsumer = mStatsRule.getAppsBatteryConsumer(); + assertThat(appsBatteryConsumer + .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_CAMERA)) + .isEqualTo(1000); + assertThat(appsBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA)) + .isWithin(PRECISION).of(0.1); } } diff --git a/core/tests/coretests/src/com/android/internal/os/CpuPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/CpuPowerCalculatorTest.java index 1a99fb0fd40fb..152d246bc3728 100644 --- a/core/tests/coretests/src/com/android/internal/os/CpuPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/CpuPowerCalculatorTest.java @@ -160,6 +160,18 @@ public class CpuPowerCalculatorTest { assertThat(uidConsumer2.getPowerModel(BatteryConsumer.POWER_COMPONENT_CPU)) .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE); assertThat(uidConsumer2.getPackageWithHighestDrain()).isNull(); + + final BatteryConsumer deviceBatteryConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(deviceBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU)) + .isWithin(PRECISION).of(3.76455); + assertThat(deviceBatteryConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CPU)) + .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE); + + final BatteryConsumer appsBatteryConsumer = mStatsRule.getAppsBatteryConsumer(); + assertThat(appsBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU)) + .isWithin(PRECISION).of(3.76455); + assertThat(appsBatteryConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CPU)) + .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE); } @Test @@ -224,5 +236,17 @@ public class CpuPowerCalculatorTest { assertThat(uidConsumer2.getPowerModel(BatteryConsumer.POWER_COMPONENT_CPU)) .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); assertThat(uidConsumer2.getPackageWithHighestDrain()).isNull(); + + final BatteryConsumer deviceBatteryConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(deviceBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU)) + .isWithin(PRECISION).of(10.62949); + assertThat(deviceBatteryConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CPU)) + .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); + + final BatteryConsumer appsBatteryConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(appsBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU)) + .isWithin(PRECISION).of(10.62949); + assertThat(appsBatteryConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CPU)) + .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); } } diff --git a/core/tests/coretests/src/com/android/internal/os/CustomMeasuredPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/CustomMeasuredPowerCalculatorTest.java index f0111171b83c4..3fb274323720c 100644 --- a/core/tests/coretests/src/com/android/internal/os/CustomMeasuredPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/CustomMeasuredPowerCalculatorTest.java @@ -76,5 +76,21 @@ public class CustomMeasuredPowerCalculatorTest { assertThat(systemConsumer.getConsumedPowerForCustomComponent( BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + 1)) .isWithin(PRECISION).of(55.55555); + + final BatteryConsumer deviceBatteryConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(deviceBatteryConsumer.getConsumedPowerForCustomComponent( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)) + .isWithin(PRECISION).of(27.77777); + assertThat(deviceBatteryConsumer.getConsumedPowerForCustomComponent( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + 1)) + .isWithin(PRECISION).of(55.55555); + + final BatteryConsumer appsBatteryConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(appsBatteryConsumer.getConsumedPowerForCustomComponent( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)) + .isWithin(PRECISION).of(27.77777); + assertThat(appsBatteryConsumer.getConsumedPowerForCustomComponent( + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + 1)) + .isWithin(PRECISION).of(55.55555); } } diff --git a/core/tests/coretests/src/com/android/internal/os/GnssPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/GnssPowerCalculatorTest.java index 7ea799ff51738..196443056d324 100644 --- a/core/tests/coretests/src/com/android/internal/os/GnssPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/GnssPowerCalculatorTest.java @@ -62,6 +62,18 @@ public class GnssPowerCalculatorTest { .isWithin(PRECISION).of(0.1); assertThat(consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_GNSS)) .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE); + + BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS)) + .isWithin(PRECISION).of(0.1); + assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_GNSS)) + .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE); + + BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer(); + assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS)) + .isWithin(PRECISION).of(0.1); + assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_GNSS)) + .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE); } @Test @@ -97,5 +109,17 @@ public class GnssPowerCalculatorTest { .isWithin(PRECISION).of(5.55555); assertThat(consumer2.getPowerModel(BatteryConsumer.POWER_COMPONENT_GNSS)) .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); + + BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS)) + .isWithin(PRECISION).of(8.333333); + assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_GNSS)) + .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); + + BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer(); + assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS)) + .isWithin(PRECISION).of(8.333333); + assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_GNSS)) + .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); } } diff --git a/core/tests/coretests/src/com/android/internal/os/IdlePowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/IdlePowerCalculatorTest.java index 2331eebf6dd1f..159d53a4cf5bc 100644 --- a/core/tests/coretests/src/com/android/internal/os/IdlePowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/IdlePowerCalculatorTest.java @@ -52,5 +52,17 @@ public class IdlePowerCalculatorTest { .isEqualTo(3000); assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_IDLE)) .isWithin(PRECISION).of(0.7); + + BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(deviceConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_IDLE)) + .isEqualTo(3000); + assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_IDLE)) + .isWithin(PRECISION).of(0.7); + + BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer(); + assertThat(appsConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_IDLE)) + .isEqualTo(0); + assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_IDLE)) + .isWithin(PRECISION).of(0); } } diff --git a/core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java index 5b84a1b320c76..4f5417fe7955f 100644 --- a/core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java @@ -116,6 +116,18 @@ public class MobileRadioPowerCalculatorTest { .isWithin(PRECISION).of(0.8); assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)) .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE); + + BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)) + .isWithin(PRECISION).of(2.2444); + assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)) + .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE); + + BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer(); + assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)) + .isWithin(PRECISION).of(0.8); + assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)) + .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE); } @Test @@ -175,5 +187,17 @@ public class MobileRadioPowerCalculatorTest { .isWithin(PRECISION).of(1.53934); assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)) .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); + + BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)) + .isWithin(PRECISION).of(4.31711); + assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)) + .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); + + BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer(); + assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)) + .isWithin(PRECISION).of(1.53934); + assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)) + .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); } } diff --git a/core/tests/coretests/src/com/android/internal/os/ScreenPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/ScreenPowerCalculatorTest.java index 93c71068457e1..144da38e4cb3b 100644 --- a/core/tests/coretests/src/com/android/internal/os/ScreenPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/ScreenPowerCalculatorTest.java @@ -120,6 +120,29 @@ public class ScreenPowerCalculatorTest { .isWithin(PRECISION).of(101.85185); assertThat(uid2.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN)) .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); + + BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(deviceConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN)) + .isEqualTo(80 * MINUTE_IN_MS); + + // 600000000 uAs * (1 mA / 1000 uA) * (1 h / 3600 s) = 166.66666 mAh + assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN)) + .isWithin(PRECISION).of(166.66666); + assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN)) + .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); + assertThat(deviceConsumer.getConsumedPower()) + .isWithin(PRECISION).of(166.66666); + + BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer(); + assertThat(appsConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN)) + .isEqualTo(80 * MINUTE_IN_MS); + + assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN)) + .isWithin(PRECISION).of(166.66666); + assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN)) + .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); + assertThat(appsConsumer.getConsumedPower()) + .isWithin(PRECISION).of(166.66666); } @Test @@ -185,6 +208,22 @@ public class ScreenPowerCalculatorTest { .isWithin(PRECISION).of(69.0); assertThat(uid2.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN)) .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE); + + BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(deviceConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN)) + .isEqualTo(80 * MINUTE_IN_MS); + assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN)) + .isWithin(PRECISION).of(92); + assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN)) + .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE); + + BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer(); + assertThat(appsConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN)) + .isEqualTo(80 * MINUTE_IN_MS); + assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN)) + .isWithin(PRECISION).of(92); + assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN)) + .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE); } private void setProcState(int uid, int procState, boolean resumed, long realtimeMs, diff --git a/core/tests/coretests/src/com/android/internal/os/SensorPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/SensorPowerCalculatorTest.java index 74235b28d43b4..7563e39127669 100644 --- a/core/tests/coretests/src/com/android/internal/os/SensorPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/SensorPowerCalculatorTest.java @@ -59,11 +59,11 @@ public class SensorPowerCalculatorTest { when(sensorManager.getSensorList(Sensor.TYPE_ALL)) .thenReturn(List.of(sensor1, sensor2)); - BatteryStatsImpl.Uid uidStats = mStatsRule.getUidStats(APP_UID); - uidStats.noteStartSensor(SENSOR_HANDLE_1, 1000); - uidStats.noteStopSensor(SENSOR_HANDLE_1, 2000); - uidStats.noteStartSensor(SENSOR_HANDLE_2, 3000); - uidStats.noteStopSensor(SENSOR_HANDLE_2, 5000); + final BatteryStatsImpl stats = mStatsRule.getBatteryStats(); + stats.noteStartSensorLocked(APP_UID, SENSOR_HANDLE_1, 1000, 1000); + stats.noteStopSensorLocked(APP_UID, SENSOR_HANDLE_1, 2000, 2000); + stats.noteStartSensorLocked(APP_UID, SENSOR_HANDLE_2, 3000, 3000); + stats.noteStopSensorLocked(APP_UID, SENSOR_HANDLE_2, 5000, 5000); SensorPowerCalculator calculator = new SensorPowerCalculator(sensorManager); @@ -74,6 +74,14 @@ public class SensorPowerCalculatorTest { .isEqualTo(3000); assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SENSORS)) .isWithin(PRECISION).of(0.5); + + BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SENSORS)) + .isWithin(PRECISION).of(0.5); + + BatteryConsumer appsConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SENSORS)) + .isWithin(PRECISION).of(0.5); } private Sensor createSensor(int handle, int type, double power) { diff --git a/core/tests/coretests/src/com/android/internal/os/SystemServicePowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/SystemServicePowerCalculatorTest.java index 58e2513897acb..cd45060b7cc42 100644 --- a/core/tests/coretests/src/com/android/internal/os/SystemServicePowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/SystemServicePowerCalculatorTest.java @@ -133,6 +133,12 @@ public class SystemServicePowerCalculatorTest { assertThat(mStatsRule.getUidBatteryConsumer(Process.SYSTEM_UID) .getConsumedPower(BatteryConsumer.POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS)) .isWithin(PRECISION).of(-18.888888); + assertThat(mStatsRule.getDeviceBatteryConsumer() + .getConsumedPower(BatteryConsumer.POWER_COMPONENT_SYSTEM_SERVICES)) + .isWithin(PRECISION).of(18.888888); + assertThat(mStatsRule.getAppsBatteryConsumer() + .getConsumedPower(BatteryConsumer.POWER_COMPONENT_SYSTEM_SERVICES)) + .isWithin(PRECISION).of(18.888888); } private static class MockKernelCpuUidFreqTimeReader extends diff --git a/core/tests/coretests/src/com/android/internal/os/VideoPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/VideoPowerCalculatorTest.java index fa0dbc76d5c6b..ae61d31e7af4a 100644 --- a/core/tests/coretests/src/com/android/internal/os/VideoPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/VideoPowerCalculatorTest.java @@ -56,5 +56,19 @@ public class VideoPowerCalculatorTest { .isEqualTo(1000); assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_VIDEO)) .isWithin(PRECISION).of(0.1); + + final BatteryConsumer deviceBatteryConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(deviceBatteryConsumer + .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_VIDEO)) + .isEqualTo(1000); + assertThat(deviceBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_VIDEO)) + .isWithin(PRECISION).of(0.1); + + final BatteryConsumer appsBatteryConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(appsBatteryConsumer + .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_VIDEO)) + .isEqualTo(1000); + assertThat(appsBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_VIDEO)) + .isWithin(PRECISION).of(0.1); } } diff --git a/core/tests/coretests/src/com/android/internal/os/WakelockPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/WakelockPowerCalculatorTest.java index 9d3ed55a0729c..82830f23fec30 100644 --- a/core/tests/coretests/src/com/android/internal/os/WakelockPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/WakelockPowerCalculatorTest.java @@ -72,5 +72,15 @@ public class WakelockPowerCalculatorTest { .isEqualTo(5000); assertThat(osConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WAKELOCK)) .isWithin(PRECISION).of(0.5); + + BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(deviceConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WAKELOCK)) + .isEqualTo(6000); + assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WAKELOCK)) + .isWithin(PRECISION).of(0.6); + + BatteryConsumer appConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(appConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WAKELOCK)) + .isWithin(PRECISION).of(0.6); } } diff --git a/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java index 4a7cf1e21abea..f8655c5b89d27 100644 --- a/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java @@ -104,6 +104,20 @@ public class WifiPowerCalculatorTest { .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE); assertThat(systemConsumer.getPowerConsumedByApps()) .isWithin(PRECISION).of(0.466333); + + BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(deviceConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WIFI)) + .isEqualTo(4002); + assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI)) + .isWithin(PRECISION).of(0.86666); + assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI)) + .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE); + + BatteryConsumer appsConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI)) + .isWithin(PRECISION).of(0.866666); + assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI)) + .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE); } @Test @@ -136,6 +150,20 @@ public class WifiPowerCalculatorTest { .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); assertThat(systemConsumer.getPowerConsumedByApps()) .isWithin(PRECISION).of(0.14946); + + BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(deviceConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WIFI)) + .isEqualTo(4002); + assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI)) + .isWithin(PRECISION).of(0.27777); + assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI)) + .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); + + BatteryConsumer appsConsumer = mStatsRule.getDeviceBatteryConsumer(); + assertThat(appsConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI)) + .isWithin(PRECISION).of(0.277777); + assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI)) + .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY); } /** Sets up batterystats object with prepopulated network & timer data for Timer-model tests. */