Loading core/java/android/os/BatteryConsumer.java +45 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,28 @@ public abstract class BatteryConsumer { public static final int FIRST_CUSTOM_POWER_COMPONENT_ID = 1000; public static final int LAST_CUSTOM_POWER_COMPONENT_ID = 9999; /** * Time usage component, describing the particular part of the system * that was used for the corresponding amount of time. * * @hide */ @IntDef(prefix = {"TIME_COMPONENT_"}, value = { TIME_COMPONENT_CPU, TIME_COMPONENT_CPU_FOREGROUND, }) @Retention(RetentionPolicy.SOURCE) public static @interface TimeComponent { } public static final int TIME_COMPONENT_CPU = 0; public static final int TIME_COMPONENT_CPU_FOREGROUND = 1; public static final int TIME_COMPONENT_COUNT = 2; public static final int FIRST_CUSTOM_TIME_COMPONENT_ID = 1000; public static final int LAST_CUSTOM_TIME_COMPONENT_ID = 9999; private final PowerComponents mPowerComponents; protected BatteryConsumer(@NonNull PowerComponents powerComponents) { Loading Loading @@ -83,6 +105,29 @@ public abstract class BatteryConsumer { return mPowerComponents.getConsumedPowerForCustomComponent(componentId); } /** * Returns the amount of time since BatteryStats reset used by the specified component, e.g. * CPU, WiFi etc. * * @param componentId The ID of the time component, e.g. * {@link UidBatteryConsumer#TIME_COMPONENT_CPU}. * @return Amount of time in milliseconds. */ public long getUsageDurationMillis(@TimeComponent int componentId) { return mPowerComponents.getUsageDurationMillis(componentId); } /** * Returns the amount of usage time attributed to the specified custom component * since BatteryStats reset. * * @param componentId The ID of the custom power component. * @return Amount of time in milliseconds. */ public long getUsageDurationForCustomComponentMillis(int componentId) { return mPowerComponents.getUsageDurationForCustomComponentMillis(componentId); } protected void writeToParcel(Parcel dest, int flags) { mPowerComponents.writeToParcel(dest, flags); } Loading core/java/android/os/BatteryUsageStats.java +15 −4 Original line number Diff line number Diff line Loading @@ -35,7 +35,11 @@ public final class BatteryUsageStats implements Parcelable { private BatteryUsageStats(@NonNull Builder builder) { mConsumedPower = builder.mConsumedPower; mDischargePercentage = builder.mDischargePercentage; mUidBatteryConsumers = builder.mUidBatteryConsumers; final int uidBatteryConsumerCount = builder.mUidBatteryConsumerBuilders.size(); mUidBatteryConsumers = new ArrayList<>(uidBatteryConsumerCount); for (int i = 0; i < uidBatteryConsumerCount; i++) { mUidBatteryConsumers.add(builder.mUidBatteryConsumerBuilders.get(i).build()); } } /** Loading Loading @@ -95,7 +99,8 @@ public final class BatteryUsageStats implements Parcelable { public static final class Builder { private double mConsumedPower; private int mDischargePercentage; private final ArrayList<UidBatteryConsumer> mUidBatteryConsumers = new ArrayList<>(); private final ArrayList<UidBatteryConsumer.Builder> mUidBatteryConsumerBuilders = new ArrayList<>(); /** * Constructs a read-only object using the Builder values. Loading Loading @@ -130,9 +135,15 @@ public final class BatteryUsageStats implements Parcelable { * individual UID. */ @NonNull public Builder addUidBatteryConsumer(@NonNull UidBatteryConsumer uidBatteryConsumer) { mUidBatteryConsumers.add(uidBatteryConsumer); public Builder addUidBatteryConsumerBuilder( @NonNull UidBatteryConsumer.Builder uidBatteryConsumer) { mUidBatteryConsumerBuilders.add(uidBatteryConsumer); return this; } @NonNull public List<UidBatteryConsumer.Builder> getUidBatteryConsumerBuilders() { return mUidBatteryConsumerBuilders; } } } core/java/android/os/PowerComponents.java +96 −2 Original line number Diff line number Diff line Loading @@ -29,21 +29,25 @@ class PowerComponents { private final double mTotalPowerConsumed; private final double[] mPowerComponents; private final long[] mTimeComponents; PowerComponents(@NonNull Builder builder) { mTotalPowerConsumed = builder.mTotalPowerConsumed; mPowerComponents = builder.mPowerComponents; mTimeComponents = builder.mTimeComponents; } PowerComponents(@NonNull Parcel source) { mTotalPowerConsumed = source.readDouble(); mPowerComponents = source.createDoubleArray(); mTimeComponents = source.createLongArray(); } /** Writes contents to Parcel */ void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeDouble(mTotalPowerConsumed); dest.writeDoubleArray(mPowerComponents); dest.writeLongArray(mTimeComponents); } /** Loading Loading @@ -93,16 +97,59 @@ class PowerComponents { } } /** * Returns the amount of time used by the specified component, e.g. CPU, WiFi etc. * * @param componentId The ID of the time component, e.g. * {@link UidBatteryConsumer#TIME_COMPONENT_CPU}. * @return Amount of time in milliseconds. */ public long getUsageDurationMillis(@UidBatteryConsumer.TimeComponent int componentId) { if (componentId >= UidBatteryConsumer.TIME_COMPONENT_COUNT) { throw new IllegalArgumentException( "Unsupported time component ID: " + componentId); } try { return mTimeComponents[componentId]; } catch (ArrayIndexOutOfBoundsException e) { throw new IllegalArgumentException("Unsupported power component ID: " + componentId); } } /** * Returns the amount of usage time attributed to the specified custom component. * * @param componentId The ID of the custom power component. * @return Amount of time in milliseconds. */ public long getUsageDurationForCustomComponentMillis(int componentId) { if (componentId < UidBatteryConsumer.FIRST_CUSTOM_TIME_COMPONENT_ID) { throw new IllegalArgumentException( "Unsupported custom time component ID: " + componentId); } try { return mTimeComponents[ UidBatteryConsumer.TIME_COMPONENT_COUNT + componentId - UidBatteryConsumer.FIRST_CUSTOM_TIME_COMPONENT_ID]; } catch (ArrayIndexOutOfBoundsException e) { throw new IllegalArgumentException( "Unsupported custom time component ID: " + componentId); } } /** * Builder for PowerComponents. */ static final class Builder { private double mTotalPowerConsumed; private final double[] mPowerComponents; private final long[] mTimeComponents; Builder(int customPowerComponentCount) { mPowerComponents = new double[BatteryConsumer.POWER_COMPONENT_COUNT Builder(int customPowerComponentCount, int customTimeComponentCount) { mPowerComponents = new double[UidBatteryConsumer.POWER_COMPONENT_COUNT + customPowerComponentCount]; mTimeComponents = new long[UidBatteryConsumer.TIME_COMPONENT_COUNT + customTimeComponentCount]; } /** Loading Loading @@ -159,6 +206,53 @@ class PowerComponents { return this; } /** * Sets the amount of time used by the specified component, e.g. CPU, WiFi etc. * * @param componentId The ID of the time component, e.g. * {@link UidBatteryConsumer#TIME_COMPONENT_CPU}. * @param componentUsageDurationMillis Amount of time in milliseconds. */ @NonNull public Builder setUsageDurationMillis(@UidBatteryConsumer.TimeComponent int componentId, long componentUsageDurationMillis) { if (componentId >= UidBatteryConsumer.TIME_COMPONENT_COUNT) { throw new IllegalArgumentException( "Unsupported time component ID: " + componentId); } try { mTimeComponents[componentId] = componentUsageDurationMillis; } catch (ArrayIndexOutOfBoundsException e) { throw new IllegalArgumentException( "Unsupported time component ID: " + componentId); } return this; } /** * Sets the amount of time used by the specified custom component. * * @param componentId The ID of the custom power component. * @param componentUsageDurationMillis Amount of time in milliseconds. */ @NonNull public Builder setUsageDurationForCustomComponentMillis(int componentId, long componentUsageDurationMillis) { if (componentId < UidBatteryConsumer.FIRST_CUSTOM_TIME_COMPONENT_ID) { throw new IllegalArgumentException( "Unsupported custom time component ID: " + componentId); } try { mTimeComponents[UidBatteryConsumer.TIME_COMPONENT_COUNT + componentId - UidBatteryConsumer.FIRST_CUSTOM_TIME_COMPONENT_ID] = componentUsageDurationMillis; } catch (ArrayIndexOutOfBoundsException e) { throw new IllegalArgumentException( "Unsupported custom time component ID: " + componentId); } return this; } /** * Creates a read-only object out of the Builder values. */ Loading core/java/android/os/UidBatteryConsumer.java +45 −4 Original line number Diff line number Diff line Loading @@ -82,12 +82,24 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela */ public static final class Builder { private final PowerComponents.Builder mPowerComponentsBuilder; private final BatteryStats.Uid mBatteryStatsUid; private final int mUid; private String mPackageWithHighestDrain; public Builder(int customPowerComponentCount, int uid) { mPowerComponentsBuilder = new PowerComponents.Builder(customPowerComponentCount); mUid = uid; public Builder(int customPowerComponentCount, int customTimeComponentCount, BatteryStats.Uid batteryStatsUid) { mPowerComponentsBuilder = new PowerComponents.Builder(customPowerComponentCount, customTimeComponentCount); mBatteryStatsUid = batteryStatsUid; mUid = batteryStatsUid.getUid(); } public BatteryStats.Uid getBatteryStatsUid() { return mBatteryStatsUid; } public int getUid() { return mUid; } /** Loading Loading @@ -132,6 +144,35 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela return this; } /** * Sets the amount of time used by the specified component, e.g. CPU, WiFi etc. * * @param componentId The ID of the time component, e.g. * {@link UidBatteryConsumer#TIME_COMPONENT_CPU}. * @param componentUsageDurationMillis Amount of time in milliseconds. */ @NonNull public Builder setUsageDurationMillis(@UidBatteryConsumer.TimeComponent int componentId, long componentUsageDurationMillis) { mPowerComponentsBuilder.setUsageDurationMillis(componentId, componentUsageDurationMillis); return this; } /** * Sets the amount of time used by the specified custom component. * * @param componentId The ID of the custom power component. * @param componentUsageDurationMillis Amount of time in milliseconds. */ @NonNull public Builder setUsageDurationForCustomComponentMillis(int componentId, long componentUsageDurationMillis) { mPowerComponentsBuilder.setUsageDurationForCustomComponentMillis(componentId, componentUsageDurationMillis); return this; } /** * Sets the name of the package owned by this UID that consumed the highest amount * of power since BatteryStats reset. Loading core/java/com/android/internal/os/BatteryUsageStatsProvider.java +73 −9 Original line number Diff line number Diff line Loading @@ -17,13 +17,18 @@ package com.android.internal.os; import android.content.Context; import android.os.BatteryConsumer; import android.hardware.SensorManager; import android.net.ConnectivityManager; import android.os.BatteryStats; import android.os.BatteryUsageStats; import android.os.Bundle; import android.os.SystemClock; import android.os.UidBatteryConsumer; import android.os.UserHandle; import android.os.UserManager; import android.util.SparseArray; import java.util.ArrayList; import java.util.List; /** Loading @@ -33,10 +38,53 @@ import java.util.List; public class BatteryUsageStatsProvider { private final Context mContext; private final BatteryStatsImpl mStats; private final PowerProfile mPowerProfile; private final Object mLock = new Object(); private List<PowerCalculator> mPowerCalculators; public BatteryUsageStatsProvider(Context context, BatteryStatsImpl stats) { mContext = context; mStats = stats; mPowerProfile = new PowerProfile(mContext); } private List<PowerCalculator> getPowerCalculators() { synchronized (mLock) { if (mPowerCalculators == null) { mPowerCalculators = new ArrayList<>(); // Power calculators are applied in the order of registration mPowerCalculators.add(new CpuPowerCalculator(mPowerProfile)); mPowerCalculators.add(new MemoryPowerCalculator(mPowerProfile)); mPowerCalculators.add(new WakelockPowerCalculator(mPowerProfile)); if (!isWifiOnlyDevice(mContext)) { mPowerCalculators.add(new MobileRadioPowerCalculator(mPowerProfile)); } mPowerCalculators.add(new WifiPowerCalculator(mPowerProfile)); mPowerCalculators.add(new BluetoothPowerCalculator(mPowerProfile)); mPowerCalculators.add(new SensorPowerCalculator(mPowerProfile, mContext.getSystemService(SensorManager.class))); mPowerCalculators.add(new CameraPowerCalculator(mPowerProfile)); mPowerCalculators.add(new FlashlightPowerCalculator(mPowerProfile)); mPowerCalculators.add(new MediaPowerCalculator(mPowerProfile)); mPowerCalculators.add(new PhonePowerCalculator(mPowerProfile)); mPowerCalculators.add(new ScreenPowerCalculator(mPowerProfile)); mPowerCalculators.add(new AmbientDisplayPowerCalculator(mPowerProfile)); mPowerCalculators.add(new SystemServicePowerCalculator(mPowerProfile)); mPowerCalculators.add(new IdlePowerCalculator(mPowerProfile)); mPowerCalculators.add(new UserPowerCalculator()); } } return mPowerCalculators; } private static boolean isWifiOnlyDevice(Context context) { ConnectivityManager cm = context.getSystemService(ConnectivityManager.class); if (cm == null) { return false; } return !cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE); } /** Loading @@ -49,11 +97,19 @@ public class BatteryUsageStatsProvider { false /* collectBatteryBroadcast */); batteryStatsHelper.create((Bundle) null); final UserManager userManager = mContext.getSystemService(UserManager.class); batteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, userManager.getUserProfiles()); final List<UserHandle> asUsers = userManager.getUserProfiles(); final int n = asUsers.size(); SparseArray<UserHandle> users = new SparseArray<>(n); for (int i = 0; i < n; ++i) { UserHandle userHandle = asUsers.get(i); users.put(userHandle.getIdentifier(), userHandle); } batteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, users); // TODO(b/174186358): read extra power component number from configuration final int customPowerComponentCount = 0; final int customTimeComponentCount = 0; final BatteryUsageStats.Builder batteryUsageStatsBuilder = new BatteryUsageStats.Builder() .setDischargePercentage(batteryStatsHelper.getStats().getDischargeAmount(0)) .setConsumedPower(batteryStatsHelper.getTotalPower()); Loading @@ -62,15 +118,23 @@ public class BatteryUsageStatsProvider { for (int i = 0; i < usageList.size(); i++) { final BatterySipper sipper = usageList.get(i); if (sipper.drainType == BatterySipper.DrainType.APP) { batteryUsageStatsBuilder.addUidBatteryConsumer( new UidBatteryConsumer.Builder(customPowerComponentCount, sipper.getUid()) batteryUsageStatsBuilder.addUidBatteryConsumerBuilder( new UidBatteryConsumer.Builder(customPowerComponentCount, customTimeComponentCount, sipper.uidObj) .setPackageWithHighestDrain(sipper.packageWithHighestDrain) .setConsumedPower(sipper.sumPower()) .setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, sipper.cpuPowerMah) .build()); .setConsumedPower(sipper.sumPower())); } } final long realtimeUs = SystemClock.elapsedRealtime() * 1000; final long uptimeUs = SystemClock.uptimeMillis() * 1000; final List<PowerCalculator> powerCalculators = getPowerCalculators(); for (PowerCalculator powerCalculator : powerCalculators) { powerCalculator.calculate(batteryUsageStatsBuilder, mStats, realtimeUs, uptimeUs, BatteryStats.STATS_SINCE_CHARGED, users); } return batteryUsageStatsBuilder.build(); } } Loading
core/java/android/os/BatteryConsumer.java +45 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,28 @@ public abstract class BatteryConsumer { public static final int FIRST_CUSTOM_POWER_COMPONENT_ID = 1000; public static final int LAST_CUSTOM_POWER_COMPONENT_ID = 9999; /** * Time usage component, describing the particular part of the system * that was used for the corresponding amount of time. * * @hide */ @IntDef(prefix = {"TIME_COMPONENT_"}, value = { TIME_COMPONENT_CPU, TIME_COMPONENT_CPU_FOREGROUND, }) @Retention(RetentionPolicy.SOURCE) public static @interface TimeComponent { } public static final int TIME_COMPONENT_CPU = 0; public static final int TIME_COMPONENT_CPU_FOREGROUND = 1; public static final int TIME_COMPONENT_COUNT = 2; public static final int FIRST_CUSTOM_TIME_COMPONENT_ID = 1000; public static final int LAST_CUSTOM_TIME_COMPONENT_ID = 9999; private final PowerComponents mPowerComponents; protected BatteryConsumer(@NonNull PowerComponents powerComponents) { Loading Loading @@ -83,6 +105,29 @@ public abstract class BatteryConsumer { return mPowerComponents.getConsumedPowerForCustomComponent(componentId); } /** * Returns the amount of time since BatteryStats reset used by the specified component, e.g. * CPU, WiFi etc. * * @param componentId The ID of the time component, e.g. * {@link UidBatteryConsumer#TIME_COMPONENT_CPU}. * @return Amount of time in milliseconds. */ public long getUsageDurationMillis(@TimeComponent int componentId) { return mPowerComponents.getUsageDurationMillis(componentId); } /** * Returns the amount of usage time attributed to the specified custom component * since BatteryStats reset. * * @param componentId The ID of the custom power component. * @return Amount of time in milliseconds. */ public long getUsageDurationForCustomComponentMillis(int componentId) { return mPowerComponents.getUsageDurationForCustomComponentMillis(componentId); } protected void writeToParcel(Parcel dest, int flags) { mPowerComponents.writeToParcel(dest, flags); } Loading
core/java/android/os/BatteryUsageStats.java +15 −4 Original line number Diff line number Diff line Loading @@ -35,7 +35,11 @@ public final class BatteryUsageStats implements Parcelable { private BatteryUsageStats(@NonNull Builder builder) { mConsumedPower = builder.mConsumedPower; mDischargePercentage = builder.mDischargePercentage; mUidBatteryConsumers = builder.mUidBatteryConsumers; final int uidBatteryConsumerCount = builder.mUidBatteryConsumerBuilders.size(); mUidBatteryConsumers = new ArrayList<>(uidBatteryConsumerCount); for (int i = 0; i < uidBatteryConsumerCount; i++) { mUidBatteryConsumers.add(builder.mUidBatteryConsumerBuilders.get(i).build()); } } /** Loading Loading @@ -95,7 +99,8 @@ public final class BatteryUsageStats implements Parcelable { public static final class Builder { private double mConsumedPower; private int mDischargePercentage; private final ArrayList<UidBatteryConsumer> mUidBatteryConsumers = new ArrayList<>(); private final ArrayList<UidBatteryConsumer.Builder> mUidBatteryConsumerBuilders = new ArrayList<>(); /** * Constructs a read-only object using the Builder values. Loading Loading @@ -130,9 +135,15 @@ public final class BatteryUsageStats implements Parcelable { * individual UID. */ @NonNull public Builder addUidBatteryConsumer(@NonNull UidBatteryConsumer uidBatteryConsumer) { mUidBatteryConsumers.add(uidBatteryConsumer); public Builder addUidBatteryConsumerBuilder( @NonNull UidBatteryConsumer.Builder uidBatteryConsumer) { mUidBatteryConsumerBuilders.add(uidBatteryConsumer); return this; } @NonNull public List<UidBatteryConsumer.Builder> getUidBatteryConsumerBuilders() { return mUidBatteryConsumerBuilders; } } }
core/java/android/os/PowerComponents.java +96 −2 Original line number Diff line number Diff line Loading @@ -29,21 +29,25 @@ class PowerComponents { private final double mTotalPowerConsumed; private final double[] mPowerComponents; private final long[] mTimeComponents; PowerComponents(@NonNull Builder builder) { mTotalPowerConsumed = builder.mTotalPowerConsumed; mPowerComponents = builder.mPowerComponents; mTimeComponents = builder.mTimeComponents; } PowerComponents(@NonNull Parcel source) { mTotalPowerConsumed = source.readDouble(); mPowerComponents = source.createDoubleArray(); mTimeComponents = source.createLongArray(); } /** Writes contents to Parcel */ void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeDouble(mTotalPowerConsumed); dest.writeDoubleArray(mPowerComponents); dest.writeLongArray(mTimeComponents); } /** Loading Loading @@ -93,16 +97,59 @@ class PowerComponents { } } /** * Returns the amount of time used by the specified component, e.g. CPU, WiFi etc. * * @param componentId The ID of the time component, e.g. * {@link UidBatteryConsumer#TIME_COMPONENT_CPU}. * @return Amount of time in milliseconds. */ public long getUsageDurationMillis(@UidBatteryConsumer.TimeComponent int componentId) { if (componentId >= UidBatteryConsumer.TIME_COMPONENT_COUNT) { throw new IllegalArgumentException( "Unsupported time component ID: " + componentId); } try { return mTimeComponents[componentId]; } catch (ArrayIndexOutOfBoundsException e) { throw new IllegalArgumentException("Unsupported power component ID: " + componentId); } } /** * Returns the amount of usage time attributed to the specified custom component. * * @param componentId The ID of the custom power component. * @return Amount of time in milliseconds. */ public long getUsageDurationForCustomComponentMillis(int componentId) { if (componentId < UidBatteryConsumer.FIRST_CUSTOM_TIME_COMPONENT_ID) { throw new IllegalArgumentException( "Unsupported custom time component ID: " + componentId); } try { return mTimeComponents[ UidBatteryConsumer.TIME_COMPONENT_COUNT + componentId - UidBatteryConsumer.FIRST_CUSTOM_TIME_COMPONENT_ID]; } catch (ArrayIndexOutOfBoundsException e) { throw new IllegalArgumentException( "Unsupported custom time component ID: " + componentId); } } /** * Builder for PowerComponents. */ static final class Builder { private double mTotalPowerConsumed; private final double[] mPowerComponents; private final long[] mTimeComponents; Builder(int customPowerComponentCount) { mPowerComponents = new double[BatteryConsumer.POWER_COMPONENT_COUNT Builder(int customPowerComponentCount, int customTimeComponentCount) { mPowerComponents = new double[UidBatteryConsumer.POWER_COMPONENT_COUNT + customPowerComponentCount]; mTimeComponents = new long[UidBatteryConsumer.TIME_COMPONENT_COUNT + customTimeComponentCount]; } /** Loading Loading @@ -159,6 +206,53 @@ class PowerComponents { return this; } /** * Sets the amount of time used by the specified component, e.g. CPU, WiFi etc. * * @param componentId The ID of the time component, e.g. * {@link UidBatteryConsumer#TIME_COMPONENT_CPU}. * @param componentUsageDurationMillis Amount of time in milliseconds. */ @NonNull public Builder setUsageDurationMillis(@UidBatteryConsumer.TimeComponent int componentId, long componentUsageDurationMillis) { if (componentId >= UidBatteryConsumer.TIME_COMPONENT_COUNT) { throw new IllegalArgumentException( "Unsupported time component ID: " + componentId); } try { mTimeComponents[componentId] = componentUsageDurationMillis; } catch (ArrayIndexOutOfBoundsException e) { throw new IllegalArgumentException( "Unsupported time component ID: " + componentId); } return this; } /** * Sets the amount of time used by the specified custom component. * * @param componentId The ID of the custom power component. * @param componentUsageDurationMillis Amount of time in milliseconds. */ @NonNull public Builder setUsageDurationForCustomComponentMillis(int componentId, long componentUsageDurationMillis) { if (componentId < UidBatteryConsumer.FIRST_CUSTOM_TIME_COMPONENT_ID) { throw new IllegalArgumentException( "Unsupported custom time component ID: " + componentId); } try { mTimeComponents[UidBatteryConsumer.TIME_COMPONENT_COUNT + componentId - UidBatteryConsumer.FIRST_CUSTOM_TIME_COMPONENT_ID] = componentUsageDurationMillis; } catch (ArrayIndexOutOfBoundsException e) { throw new IllegalArgumentException( "Unsupported custom time component ID: " + componentId); } return this; } /** * Creates a read-only object out of the Builder values. */ Loading
core/java/android/os/UidBatteryConsumer.java +45 −4 Original line number Diff line number Diff line Loading @@ -82,12 +82,24 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela */ public static final class Builder { private final PowerComponents.Builder mPowerComponentsBuilder; private final BatteryStats.Uid mBatteryStatsUid; private final int mUid; private String mPackageWithHighestDrain; public Builder(int customPowerComponentCount, int uid) { mPowerComponentsBuilder = new PowerComponents.Builder(customPowerComponentCount); mUid = uid; public Builder(int customPowerComponentCount, int customTimeComponentCount, BatteryStats.Uid batteryStatsUid) { mPowerComponentsBuilder = new PowerComponents.Builder(customPowerComponentCount, customTimeComponentCount); mBatteryStatsUid = batteryStatsUid; mUid = batteryStatsUid.getUid(); } public BatteryStats.Uid getBatteryStatsUid() { return mBatteryStatsUid; } public int getUid() { return mUid; } /** Loading Loading @@ -132,6 +144,35 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela return this; } /** * Sets the amount of time used by the specified component, e.g. CPU, WiFi etc. * * @param componentId The ID of the time component, e.g. * {@link UidBatteryConsumer#TIME_COMPONENT_CPU}. * @param componentUsageDurationMillis Amount of time in milliseconds. */ @NonNull public Builder setUsageDurationMillis(@UidBatteryConsumer.TimeComponent int componentId, long componentUsageDurationMillis) { mPowerComponentsBuilder.setUsageDurationMillis(componentId, componentUsageDurationMillis); return this; } /** * Sets the amount of time used by the specified custom component. * * @param componentId The ID of the custom power component. * @param componentUsageDurationMillis Amount of time in milliseconds. */ @NonNull public Builder setUsageDurationForCustomComponentMillis(int componentId, long componentUsageDurationMillis) { mPowerComponentsBuilder.setUsageDurationForCustomComponentMillis(componentId, componentUsageDurationMillis); return this; } /** * Sets the name of the package owned by this UID that consumed the highest amount * of power since BatteryStats reset. Loading
core/java/com/android/internal/os/BatteryUsageStatsProvider.java +73 −9 Original line number Diff line number Diff line Loading @@ -17,13 +17,18 @@ package com.android.internal.os; import android.content.Context; import android.os.BatteryConsumer; import android.hardware.SensorManager; import android.net.ConnectivityManager; import android.os.BatteryStats; import android.os.BatteryUsageStats; import android.os.Bundle; import android.os.SystemClock; import android.os.UidBatteryConsumer; import android.os.UserHandle; import android.os.UserManager; import android.util.SparseArray; import java.util.ArrayList; import java.util.List; /** Loading @@ -33,10 +38,53 @@ import java.util.List; public class BatteryUsageStatsProvider { private final Context mContext; private final BatteryStatsImpl mStats; private final PowerProfile mPowerProfile; private final Object mLock = new Object(); private List<PowerCalculator> mPowerCalculators; public BatteryUsageStatsProvider(Context context, BatteryStatsImpl stats) { mContext = context; mStats = stats; mPowerProfile = new PowerProfile(mContext); } private List<PowerCalculator> getPowerCalculators() { synchronized (mLock) { if (mPowerCalculators == null) { mPowerCalculators = new ArrayList<>(); // Power calculators are applied in the order of registration mPowerCalculators.add(new CpuPowerCalculator(mPowerProfile)); mPowerCalculators.add(new MemoryPowerCalculator(mPowerProfile)); mPowerCalculators.add(new WakelockPowerCalculator(mPowerProfile)); if (!isWifiOnlyDevice(mContext)) { mPowerCalculators.add(new MobileRadioPowerCalculator(mPowerProfile)); } mPowerCalculators.add(new WifiPowerCalculator(mPowerProfile)); mPowerCalculators.add(new BluetoothPowerCalculator(mPowerProfile)); mPowerCalculators.add(new SensorPowerCalculator(mPowerProfile, mContext.getSystemService(SensorManager.class))); mPowerCalculators.add(new CameraPowerCalculator(mPowerProfile)); mPowerCalculators.add(new FlashlightPowerCalculator(mPowerProfile)); mPowerCalculators.add(new MediaPowerCalculator(mPowerProfile)); mPowerCalculators.add(new PhonePowerCalculator(mPowerProfile)); mPowerCalculators.add(new ScreenPowerCalculator(mPowerProfile)); mPowerCalculators.add(new AmbientDisplayPowerCalculator(mPowerProfile)); mPowerCalculators.add(new SystemServicePowerCalculator(mPowerProfile)); mPowerCalculators.add(new IdlePowerCalculator(mPowerProfile)); mPowerCalculators.add(new UserPowerCalculator()); } } return mPowerCalculators; } private static boolean isWifiOnlyDevice(Context context) { ConnectivityManager cm = context.getSystemService(ConnectivityManager.class); if (cm == null) { return false; } return !cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE); } /** Loading @@ -49,11 +97,19 @@ public class BatteryUsageStatsProvider { false /* collectBatteryBroadcast */); batteryStatsHelper.create((Bundle) null); final UserManager userManager = mContext.getSystemService(UserManager.class); batteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, userManager.getUserProfiles()); final List<UserHandle> asUsers = userManager.getUserProfiles(); final int n = asUsers.size(); SparseArray<UserHandle> users = new SparseArray<>(n); for (int i = 0; i < n; ++i) { UserHandle userHandle = asUsers.get(i); users.put(userHandle.getIdentifier(), userHandle); } batteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, users); // TODO(b/174186358): read extra power component number from configuration final int customPowerComponentCount = 0; final int customTimeComponentCount = 0; final BatteryUsageStats.Builder batteryUsageStatsBuilder = new BatteryUsageStats.Builder() .setDischargePercentage(batteryStatsHelper.getStats().getDischargeAmount(0)) .setConsumedPower(batteryStatsHelper.getTotalPower()); Loading @@ -62,15 +118,23 @@ public class BatteryUsageStatsProvider { for (int i = 0; i < usageList.size(); i++) { final BatterySipper sipper = usageList.get(i); if (sipper.drainType == BatterySipper.DrainType.APP) { batteryUsageStatsBuilder.addUidBatteryConsumer( new UidBatteryConsumer.Builder(customPowerComponentCount, sipper.getUid()) batteryUsageStatsBuilder.addUidBatteryConsumerBuilder( new UidBatteryConsumer.Builder(customPowerComponentCount, customTimeComponentCount, sipper.uidObj) .setPackageWithHighestDrain(sipper.packageWithHighestDrain) .setConsumedPower(sipper.sumPower()) .setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, sipper.cpuPowerMah) .build()); .setConsumedPower(sipper.sumPower())); } } final long realtimeUs = SystemClock.elapsedRealtime() * 1000; final long uptimeUs = SystemClock.uptimeMillis() * 1000; final List<PowerCalculator> powerCalculators = getPowerCalculators(); for (PowerCalculator powerCalculator : powerCalculators) { powerCalculator.calculate(batteryUsageStatsBuilder, mStats, realtimeUs, uptimeUs, BatteryStats.STATS_SINCE_CHARGED, users); } return batteryUsageStatsBuilder.build(); } }