Loading core/java/android/os/AggregateBatteryConsumer.java +7 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package android.os; import android.annotation.NonNull; import java.io.PrintWriter; /** * Contains power consumption data across the entire device. * Loading @@ -37,6 +39,11 @@ public final class AggregateBatteryConsumer extends BatteryConsumer implements P mConsumedPowerMah = source.readDouble(); } @Override public void dump(PrintWriter pw, boolean skipEmptyComponents) { mPowerComponents.dump(pw, skipEmptyComponents); } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { super.writeToParcel(dest, flags); Loading core/java/android/os/BatteryConsumer.java +69 −3 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.os; import android.annotation.IntDef; import android.annotation.NonNull; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading @@ -27,7 +28,7 @@ import java.lang.annotation.RetentionPolicy; * * @hide */ public class BatteryConsumer { public abstract class BatteryConsumer { /** * Power usage component, describing the particular part of the system Loading Loading @@ -85,12 +86,37 @@ public class BatteryConsumer { public static final int FIRST_CUSTOM_POWER_COMPONENT_ID = 1000; public static final int LAST_CUSTOM_POWER_COMPONENT_ID = 9999; private static final String[] sPowerComponentNames = new String[POWER_COMPONENT_COUNT]; static { // Assign individually to avoid future mismatch sPowerComponentNames[POWER_COMPONENT_SCREEN] = "screen"; sPowerComponentNames[POWER_COMPONENT_CPU] = "cpu"; sPowerComponentNames[POWER_COMPONENT_BLUETOOTH] = "bluetooth"; sPowerComponentNames[POWER_COMPONENT_CAMERA] = "camera"; sPowerComponentNames[POWER_COMPONENT_AUDIO] = "audio"; sPowerComponentNames[POWER_COMPONENT_VIDEO] = "video"; sPowerComponentNames[POWER_COMPONENT_FLASHLIGHT] = "flashlight"; sPowerComponentNames[POWER_COMPONENT_SYSTEM_SERVICES] = "system_services"; sPowerComponentNames[POWER_COMPONENT_MOBILE_RADIO] = "mobile_radio"; sPowerComponentNames[POWER_COMPONENT_SENSORS] = "sensors"; sPowerComponentNames[POWER_COMPONENT_GNSS] = "gnss"; sPowerComponentNames[POWER_COMPONENT_WIFI] = "wifi"; sPowerComponentNames[POWER_COMPONENT_WAKELOCK] = "wakelock"; sPowerComponentNames[POWER_COMPONENT_MEMORY] = "memory"; sPowerComponentNames[POWER_COMPONENT_PHONE] = "phone"; sPowerComponentNames[POWER_COMPONENT_AMBIENT_DISPLAY] = "ambient_display"; sPowerComponentNames[POWER_COMPONENT_IDLE] = "idle"; sPowerComponentNames[POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS] = "reattributed"; } /** * Identifiers of models used for power estimation. * * @hide */ @IntDef(prefix = {"POWER_MODEL_"}, value = { POWER_MODEL_UNDEFINED, POWER_MODEL_POWER_PROFILE, POWER_MODEL_MEASURED_ENERGY, }) Loading @@ -98,16 +124,21 @@ public class BatteryConsumer { public @interface PowerModel { } /** * Unspecified power model. */ public static final int POWER_MODEL_UNDEFINED = 0; /** * Power model that is based on average consumption rates that hardware components * consume in various states. */ public static final int POWER_MODEL_POWER_PROFILE = 0; public static final int POWER_MODEL_POWER_PROFILE = 1; /** * Power model that is based on energy consumption measured by on-device power monitors. */ public static final int POWER_MODEL_MEASURED_ENERGY = 1; public static final int POWER_MODEL_MEASURED_ENERGY = 2; protected final PowerComponents mPowerComponents; Loading Loading @@ -197,6 +228,41 @@ public class BatteryConsumer { mPowerComponents.writeToParcel(dest, flags); } /** * Returns the name of the specified component. Intended for logging and debugging. */ public static String powerComponentIdToString(@BatteryConsumer.PowerComponent int componentId) { return sPowerComponentNames[componentId]; } /** * Returns the name of the specified power model. Intended for logging and debugging. */ public static String powerModelToString(@BatteryConsumer.PowerModel int powerModel) { switch (powerModel) { case BatteryConsumer.POWER_MODEL_MEASURED_ENERGY: return "measured energy"; case BatteryConsumer.POWER_MODEL_POWER_PROFILE: return "power profile"; default: return ""; } } /** * Prints the stats in a human-readable format. */ public void dump(PrintWriter pw) { dump(pw, true); } /** * Prints the stats in a human-readable format. * * @param skipEmptyComponents if true, omit any power components with a zero amount. */ public abstract void dump(PrintWriter pw, boolean skipEmptyComponents); protected abstract static class BaseBuilder<T extends BaseBuilder<?>> { final PowerComponents.Builder mPowerComponentsBuilder; Loading core/java/android/os/BatteryStats.java +10 −144 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import android.view.Display; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; import com.android.internal.os.BatteryUsageStatsProvider; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -5299,154 +5300,19 @@ public abstract class BatteryStats implements Parcelable { pw.println(getDischargeAmountScreenDozeSinceCharge()); pw.println(); final BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, this); final BatteryUsageStats stats = provider.getBatteryUsageStats( new BatteryUsageStatsQuery.Builder() .setMaxStatsAgeMs(0) .includePowerModels() .build()); stats.dump(pw, prefix); final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly); helper.create(this); helper.refreshStats(which, UserHandle.USER_ALL); List<BatterySipper> sippers = helper.getUsageList(); if (sippers != null && sippers.size() > 0) { pw.print(prefix); pw.println(" Estimated power use (mAh):"); pw.print(prefix); pw.print(" Capacity: "); printmAh(pw, helper.getPowerProfile().getBatteryCapacity()); pw.print(", Computed drain: "); printmAh(pw, helper.getComputedPower()); pw.print(", actual drain: "); printmAh(pw, helper.getMinDrainedPower()); if (helper.getMinDrainedPower() != helper.getMaxDrainedPower()) { pw.print("-"); printmAh(pw, helper.getMaxDrainedPower()); } pw.println(); for (int i=0; i<sippers.size(); i++) { final BatterySipper bs = sippers.get(i); pw.print(prefix); switch (bs.drainType) { case AMBIENT_DISPLAY: pw.print(" Ambient display: "); break; case IDLE: pw.print(" Idle: "); break; case CELL: pw.print(" Cell standby: "); break; case PHONE: pw.print(" Phone calls: "); break; case WIFI: pw.print(" Wifi: "); break; case BLUETOOTH: pw.print(" Bluetooth: "); break; case SCREEN: pw.print(" Screen: "); break; case FLASHLIGHT: pw.print(" Flashlight: "); break; case APP: pw.print(" Uid "); UserHandle.formatUid(pw, bs.uidObj.getUid()); pw.print(": "); break; case USER: pw.print(" User "); pw.print(bs.userId); pw.print(": "); break; case UNACCOUNTED: pw.print(" Unaccounted: "); break; case OVERCOUNTED: pw.print(" Over-counted: "); break; case CAMERA: pw.print(" Camera: "); break; default: pw.print(" ???: "); break; } printmAh(pw, bs.totalPowerMah); if (bs.usagePowerMah != bs.totalPowerMah) { // If the usage (generic power) isn't the whole amount, we list out // what components are involved in the calculation. pw.print(" ("); if (bs.usagePowerMah != 0) { pw.print(" usage="); printmAh(pw, bs.usagePowerMah); } if (bs.cpuPowerMah != 0) { pw.print(" cpu="); printmAh(pw, bs.cpuPowerMah); } if (bs.wakeLockPowerMah != 0) { pw.print(" wake="); printmAh(pw, bs.wakeLockPowerMah); } if (bs.mobileRadioPowerMah != 0) { pw.print(" radio="); printmAh(pw, bs.mobileRadioPowerMah); } if (bs.wifiPowerMah != 0) { pw.print(" wifi="); printmAh(pw, bs.wifiPowerMah); } if (bs.bluetoothPowerMah != 0) { pw.print(" bt="); printmAh(pw, bs.bluetoothPowerMah); } if (bs.gpsPowerMah != 0) { pw.print(" gps="); printmAh(pw, bs.gpsPowerMah); } if (bs.sensorPowerMah != 0) { pw.print(" sensor="); printmAh(pw, bs.sensorPowerMah); } if (bs.cameraPowerMah != 0) { pw.print(" camera="); printmAh(pw, bs.cameraPowerMah); } if (bs.flashlightPowerMah != 0) { pw.print(" flash="); printmAh(pw, bs.flashlightPowerMah); } if (bs.customMeasuredPowerMah != null) { for (int idx = 0; idx < bs.customMeasuredPowerMah.length; idx++) { final double customPowerMah = bs.customMeasuredPowerMah[idx]; if (customPowerMah != 0) { pw.print(" custom[" + idx + "]="); printmAh(pw, customPowerMah); } } } pw.print(" )"); } // If there is additional smearing information, include it. if (bs.totalSmearedPowerMah != bs.totalPowerMah) { pw.print(" Including smearing: "); printmAh(pw, bs.totalSmearedPowerMah); pw.print(" ("); if (bs.screenPowerMah != 0) { pw.print(" screen="); printmAh(pw, bs.screenPowerMah); } if (bs.proportionalSmearMah != 0) { pw.print(" proportional="); printmAh(pw, bs.proportionalSmearMah); } pw.print(" )"); } if (bs.shouldHide) { pw.print(" Excluded from smearing"); } pw.println(); } pw.println(); } sippers = helper.getMobilemsppList(); final List<BatterySipper> sippers = helper.getMobilemsppList(); if (sippers != null && sippers.size() > 0) { pw.print(prefix); pw.println(" Per-app mobile ms per packet:"); long totalTime = 0; Loading core/java/android/os/BatteryUsageStats.java +121 −0 Original line number Diff line number Diff line Loading @@ -23,10 +23,13 @@ import android.util.SparseArray; import com.android.internal.os.BatteryStatsHistory; import com.android.internal.os.BatteryStatsHistoryIterator; import com.android.internal.os.PowerCalculator; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Comparator; import java.util.List; /** Loading Loading @@ -73,6 +76,7 @@ public final class BatteryUsageStats implements Parcelable { private final int mDischargePercentage; private final long mStatsStartTimestampMs; private final double mBatteryCapacityMah; private final double mDischargedPowerLowerBound; private final double mDischargedPowerUpperBound; private final long mBatteryTimeRemainingMs; Loading @@ -86,6 +90,7 @@ public final class BatteryUsageStats implements Parcelable { private BatteryUsageStats(@NonNull Builder builder) { mStatsStartTimestampMs = builder.mStatsStartTimestampMs; mBatteryCapacityMah = builder.mBatteryCapacityMah; mDischargePercentage = builder.mDischargePercentage; mDischargedPowerLowerBound = builder.mDischargedPowerLowerBoundMah; mDischargedPowerUpperBound = builder.mDischargedPowerUpperBoundMah; Loading Loading @@ -144,6 +149,13 @@ public final class BatteryUsageStats implements Parcelable { .getConsumedPower(); } /** * Returns battery capacity in milli-amp-hours. */ public double getBatteryCapacity() { return mBatteryCapacityMah; } /** * Portion of battery charge drained since BatteryStats reset (e.g. due to being fully * charged), as percentage of the full charge in the range [0:100] Loading Loading @@ -217,6 +229,7 @@ public final class BatteryUsageStats implements Parcelable { private BatteryUsageStats(@NonNull Parcel source) { mStatsStartTimestampMs = source.readLong(); mBatteryCapacityMah = source.readDouble(); mDischargePercentage = source.readInt(); mDischargedPowerLowerBound = source.readDouble(); mDischargedPowerUpperBound = source.readDouble(); Loading Loading @@ -274,6 +287,7 @@ public final class BatteryUsageStats implements Parcelable { @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeLong(mStatsStartTimestampMs); dest.writeDouble(mBatteryCapacityMah); dest.writeInt(mDischargePercentage); dest.writeDouble(mDischargedPowerLowerBound); dest.writeDouble(mDischargedPowerUpperBound); Loading Loading @@ -321,6 +335,104 @@ public final class BatteryUsageStats implements Parcelable { } }; /** * Prints the stats in a human-readable format. */ public void dump(PrintWriter pw, String prefix) { pw.print(prefix); pw.println(" Estimated power use (mAh):"); pw.print(prefix); pw.print(" Capacity: "); PowerCalculator.printPowerMah(pw, getBatteryCapacity()); pw.print(", Computed drain: "); PowerCalculator.printPowerMah(pw, getConsumedPower()); final Range<Double> dischargedPowerRange = getDischargedPowerRange(); pw.print(", actual drain: "); PowerCalculator.printPowerMah(pw, dischargedPowerRange.getLower()); if (!dischargedPowerRange.getLower().equals(dischargedPowerRange.getUpper())) { pw.print("-"); PowerCalculator.printPowerMah(pw, dischargedPowerRange.getUpper()); } pw.println(); pw.println(" Global"); final BatteryConsumer deviceConsumer = getAggregateBatteryConsumer( AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE); final BatteryConsumer appsConsumer = getAggregateBatteryConsumer( AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS); for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT; componentId++) { final double devicePowerMah = deviceConsumer.getConsumedPower(componentId); final double appsPowerMah = appsConsumer.getConsumedPower(componentId); if (devicePowerMah == 0 && appsPowerMah == 0) { continue; } final String componentName = BatteryConsumer.powerComponentIdToString(componentId); printPowerComponent(pw, prefix, componentName, devicePowerMah, appsPowerMah, deviceConsumer.getPowerModel(componentId), deviceConsumer.getUsageDurationMillis(componentId)); } for (int componentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID; componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + mCustomPowerComponentNames.length; componentId++) { final double devicePowerMah = deviceConsumer.getConsumedPowerForCustomComponent(componentId); final double appsPowerMah = appsConsumer.getConsumedPowerForCustomComponent(componentId); if (devicePowerMah == 0 && appsPowerMah == 0) { continue; } printPowerComponent(pw, prefix, deviceConsumer.getCustomPowerComponentName(componentId), devicePowerMah, appsPowerMah, BatteryConsumer.POWER_MODEL_UNDEFINED, deviceConsumer.getUsageDurationForCustomComponentMillis(componentId)); } dumpSortedBatteryConsumers(pw, prefix, getUidBatteryConsumers()); dumpSortedBatteryConsumers(pw, prefix, getUserBatteryConsumers()); } private void printPowerComponent(PrintWriter pw, String prefix, String componentName, double devicePowerMah, double appsPowerMah, int powerModel, long durationMs) { StringBuilder sb = new StringBuilder(); sb.append(prefix).append(" ").append(componentName).append(": ") .append(PowerCalculator.formatCharge(devicePowerMah)); if (powerModel != BatteryConsumer.POWER_MODEL_UNDEFINED && powerModel != BatteryConsumer.POWER_MODEL_POWER_PROFILE) { sb.append(" ["); sb.append(BatteryConsumer.powerModelToString(powerModel)); sb.append("]"); } sb.append(" apps: ").append(PowerCalculator.formatCharge(appsPowerMah)); if (durationMs != 0) { sb.append(" duration: "); BatteryStats.formatTimeMs(sb, durationMs); } pw.println(sb.toString()); } private void dumpSortedBatteryConsumers(PrintWriter pw, String prefix, List<? extends BatteryConsumer> batteryConsumers) { batteryConsumers.sort( Comparator.<BatteryConsumer>comparingDouble(BatteryConsumer::getConsumedPower) .reversed()); for (BatteryConsumer consumer : batteryConsumers) { if (consumer.getConsumedPower() == 0) { continue; } pw.print(prefix); pw.print(" "); consumer.dump(pw); pw.println(); } } /** * Builder for BatteryUsageStats. */ Loading @@ -329,6 +441,7 @@ public final class BatteryUsageStats implements Parcelable { private final String[] mCustomPowerComponentNames; private final boolean mIncludePowerModels; private long mStatsStartTimestampMs; private double mBatteryCapacityMah; private int mDischargePercentage; private double mDischargedPowerLowerBoundMah; private double mDischargedPowerUpperBoundMah; Loading Loading @@ -364,6 +477,14 @@ public final class BatteryUsageStats implements Parcelable { return new BatteryUsageStats(this); } /** * Sets the battery capacity in milli-amp-hours. */ public Builder setBatteryCapacity(double batteryCapacityMah) { mBatteryCapacityMah = batteryCapacityMah; return this; } /** * Sets the timestamp of the latest battery stats reset, in milliseconds. */ Loading core/java/android/os/PowerComponents.java +35 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,10 @@ package android.os; import android.annotation.NonNull; import com.android.internal.os.PowerCalculator; import java.io.PrintWriter; /** * Contains details of battery attribution data broken down to individual power drain types * such as CPU, RAM, GPU etc. Loading Loading @@ -202,6 +206,37 @@ class PowerComponents { return max; } public void dump(PrintWriter pw, boolean skipEmptyComponents) { String separator = ""; for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT; componentId++) { final double componentPower = getConsumedPower(componentId); if (skipEmptyComponents && componentPower == 0) { continue; } pw.print(separator); separator = " "; pw.print(BatteryConsumer.powerComponentIdToString(componentId)); pw.print("="); PowerCalculator.printPowerMah(pw, componentPower); } final int customComponentCount = getCustomPowerComponentCount(); for (int customComponentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID; customComponentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + customComponentCount; customComponentId++) { final double customComponentPower = getConsumedPowerForCustomComponent(customComponentId); if (skipEmptyComponents && customComponentPower == 0) { continue; } pw.print(separator); separator = " "; pw.print(getCustomPowerComponentName(customComponentId)); pw.print("="); PowerCalculator.printPowerMah(pw, customComponentPower); } } /** * Builder for PowerComponents. */ Loading Loading
core/java/android/os/AggregateBatteryConsumer.java +7 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package android.os; import android.annotation.NonNull; import java.io.PrintWriter; /** * Contains power consumption data across the entire device. * Loading @@ -37,6 +39,11 @@ public final class AggregateBatteryConsumer extends BatteryConsumer implements P mConsumedPowerMah = source.readDouble(); } @Override public void dump(PrintWriter pw, boolean skipEmptyComponents) { mPowerComponents.dump(pw, skipEmptyComponents); } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { super.writeToParcel(dest, flags); Loading
core/java/android/os/BatteryConsumer.java +69 −3 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.os; import android.annotation.IntDef; import android.annotation.NonNull; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading @@ -27,7 +28,7 @@ import java.lang.annotation.RetentionPolicy; * * @hide */ public class BatteryConsumer { public abstract class BatteryConsumer { /** * Power usage component, describing the particular part of the system Loading Loading @@ -85,12 +86,37 @@ public class BatteryConsumer { public static final int FIRST_CUSTOM_POWER_COMPONENT_ID = 1000; public static final int LAST_CUSTOM_POWER_COMPONENT_ID = 9999; private static final String[] sPowerComponentNames = new String[POWER_COMPONENT_COUNT]; static { // Assign individually to avoid future mismatch sPowerComponentNames[POWER_COMPONENT_SCREEN] = "screen"; sPowerComponentNames[POWER_COMPONENT_CPU] = "cpu"; sPowerComponentNames[POWER_COMPONENT_BLUETOOTH] = "bluetooth"; sPowerComponentNames[POWER_COMPONENT_CAMERA] = "camera"; sPowerComponentNames[POWER_COMPONENT_AUDIO] = "audio"; sPowerComponentNames[POWER_COMPONENT_VIDEO] = "video"; sPowerComponentNames[POWER_COMPONENT_FLASHLIGHT] = "flashlight"; sPowerComponentNames[POWER_COMPONENT_SYSTEM_SERVICES] = "system_services"; sPowerComponentNames[POWER_COMPONENT_MOBILE_RADIO] = "mobile_radio"; sPowerComponentNames[POWER_COMPONENT_SENSORS] = "sensors"; sPowerComponentNames[POWER_COMPONENT_GNSS] = "gnss"; sPowerComponentNames[POWER_COMPONENT_WIFI] = "wifi"; sPowerComponentNames[POWER_COMPONENT_WAKELOCK] = "wakelock"; sPowerComponentNames[POWER_COMPONENT_MEMORY] = "memory"; sPowerComponentNames[POWER_COMPONENT_PHONE] = "phone"; sPowerComponentNames[POWER_COMPONENT_AMBIENT_DISPLAY] = "ambient_display"; sPowerComponentNames[POWER_COMPONENT_IDLE] = "idle"; sPowerComponentNames[POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS] = "reattributed"; } /** * Identifiers of models used for power estimation. * * @hide */ @IntDef(prefix = {"POWER_MODEL_"}, value = { POWER_MODEL_UNDEFINED, POWER_MODEL_POWER_PROFILE, POWER_MODEL_MEASURED_ENERGY, }) Loading @@ -98,16 +124,21 @@ public class BatteryConsumer { public @interface PowerModel { } /** * Unspecified power model. */ public static final int POWER_MODEL_UNDEFINED = 0; /** * Power model that is based on average consumption rates that hardware components * consume in various states. */ public static final int POWER_MODEL_POWER_PROFILE = 0; public static final int POWER_MODEL_POWER_PROFILE = 1; /** * Power model that is based on energy consumption measured by on-device power monitors. */ public static final int POWER_MODEL_MEASURED_ENERGY = 1; public static final int POWER_MODEL_MEASURED_ENERGY = 2; protected final PowerComponents mPowerComponents; Loading Loading @@ -197,6 +228,41 @@ public class BatteryConsumer { mPowerComponents.writeToParcel(dest, flags); } /** * Returns the name of the specified component. Intended for logging and debugging. */ public static String powerComponentIdToString(@BatteryConsumer.PowerComponent int componentId) { return sPowerComponentNames[componentId]; } /** * Returns the name of the specified power model. Intended for logging and debugging. */ public static String powerModelToString(@BatteryConsumer.PowerModel int powerModel) { switch (powerModel) { case BatteryConsumer.POWER_MODEL_MEASURED_ENERGY: return "measured energy"; case BatteryConsumer.POWER_MODEL_POWER_PROFILE: return "power profile"; default: return ""; } } /** * Prints the stats in a human-readable format. */ public void dump(PrintWriter pw) { dump(pw, true); } /** * Prints the stats in a human-readable format. * * @param skipEmptyComponents if true, omit any power components with a zero amount. */ public abstract void dump(PrintWriter pw, boolean skipEmptyComponents); protected abstract static class BaseBuilder<T extends BaseBuilder<?>> { final PowerComponents.Builder mPowerComponentsBuilder; Loading
core/java/android/os/BatteryStats.java +10 −144 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import android.view.Display; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; import com.android.internal.os.BatteryUsageStatsProvider; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -5299,154 +5300,19 @@ public abstract class BatteryStats implements Parcelable { pw.println(getDischargeAmountScreenDozeSinceCharge()); pw.println(); final BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, this); final BatteryUsageStats stats = provider.getBatteryUsageStats( new BatteryUsageStatsQuery.Builder() .setMaxStatsAgeMs(0) .includePowerModels() .build()); stats.dump(pw, prefix); final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly); helper.create(this); helper.refreshStats(which, UserHandle.USER_ALL); List<BatterySipper> sippers = helper.getUsageList(); if (sippers != null && sippers.size() > 0) { pw.print(prefix); pw.println(" Estimated power use (mAh):"); pw.print(prefix); pw.print(" Capacity: "); printmAh(pw, helper.getPowerProfile().getBatteryCapacity()); pw.print(", Computed drain: "); printmAh(pw, helper.getComputedPower()); pw.print(", actual drain: "); printmAh(pw, helper.getMinDrainedPower()); if (helper.getMinDrainedPower() != helper.getMaxDrainedPower()) { pw.print("-"); printmAh(pw, helper.getMaxDrainedPower()); } pw.println(); for (int i=0; i<sippers.size(); i++) { final BatterySipper bs = sippers.get(i); pw.print(prefix); switch (bs.drainType) { case AMBIENT_DISPLAY: pw.print(" Ambient display: "); break; case IDLE: pw.print(" Idle: "); break; case CELL: pw.print(" Cell standby: "); break; case PHONE: pw.print(" Phone calls: "); break; case WIFI: pw.print(" Wifi: "); break; case BLUETOOTH: pw.print(" Bluetooth: "); break; case SCREEN: pw.print(" Screen: "); break; case FLASHLIGHT: pw.print(" Flashlight: "); break; case APP: pw.print(" Uid "); UserHandle.formatUid(pw, bs.uidObj.getUid()); pw.print(": "); break; case USER: pw.print(" User "); pw.print(bs.userId); pw.print(": "); break; case UNACCOUNTED: pw.print(" Unaccounted: "); break; case OVERCOUNTED: pw.print(" Over-counted: "); break; case CAMERA: pw.print(" Camera: "); break; default: pw.print(" ???: "); break; } printmAh(pw, bs.totalPowerMah); if (bs.usagePowerMah != bs.totalPowerMah) { // If the usage (generic power) isn't the whole amount, we list out // what components are involved in the calculation. pw.print(" ("); if (bs.usagePowerMah != 0) { pw.print(" usage="); printmAh(pw, bs.usagePowerMah); } if (bs.cpuPowerMah != 0) { pw.print(" cpu="); printmAh(pw, bs.cpuPowerMah); } if (bs.wakeLockPowerMah != 0) { pw.print(" wake="); printmAh(pw, bs.wakeLockPowerMah); } if (bs.mobileRadioPowerMah != 0) { pw.print(" radio="); printmAh(pw, bs.mobileRadioPowerMah); } if (bs.wifiPowerMah != 0) { pw.print(" wifi="); printmAh(pw, bs.wifiPowerMah); } if (bs.bluetoothPowerMah != 0) { pw.print(" bt="); printmAh(pw, bs.bluetoothPowerMah); } if (bs.gpsPowerMah != 0) { pw.print(" gps="); printmAh(pw, bs.gpsPowerMah); } if (bs.sensorPowerMah != 0) { pw.print(" sensor="); printmAh(pw, bs.sensorPowerMah); } if (bs.cameraPowerMah != 0) { pw.print(" camera="); printmAh(pw, bs.cameraPowerMah); } if (bs.flashlightPowerMah != 0) { pw.print(" flash="); printmAh(pw, bs.flashlightPowerMah); } if (bs.customMeasuredPowerMah != null) { for (int idx = 0; idx < bs.customMeasuredPowerMah.length; idx++) { final double customPowerMah = bs.customMeasuredPowerMah[idx]; if (customPowerMah != 0) { pw.print(" custom[" + idx + "]="); printmAh(pw, customPowerMah); } } } pw.print(" )"); } // If there is additional smearing information, include it. if (bs.totalSmearedPowerMah != bs.totalPowerMah) { pw.print(" Including smearing: "); printmAh(pw, bs.totalSmearedPowerMah); pw.print(" ("); if (bs.screenPowerMah != 0) { pw.print(" screen="); printmAh(pw, bs.screenPowerMah); } if (bs.proportionalSmearMah != 0) { pw.print(" proportional="); printmAh(pw, bs.proportionalSmearMah); } pw.print(" )"); } if (bs.shouldHide) { pw.print(" Excluded from smearing"); } pw.println(); } pw.println(); } sippers = helper.getMobilemsppList(); final List<BatterySipper> sippers = helper.getMobilemsppList(); if (sippers != null && sippers.size() > 0) { pw.print(prefix); pw.println(" Per-app mobile ms per packet:"); long totalTime = 0; Loading
core/java/android/os/BatteryUsageStats.java +121 −0 Original line number Diff line number Diff line Loading @@ -23,10 +23,13 @@ import android.util.SparseArray; import com.android.internal.os.BatteryStatsHistory; import com.android.internal.os.BatteryStatsHistoryIterator; import com.android.internal.os.PowerCalculator; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Comparator; import java.util.List; /** Loading Loading @@ -73,6 +76,7 @@ public final class BatteryUsageStats implements Parcelable { private final int mDischargePercentage; private final long mStatsStartTimestampMs; private final double mBatteryCapacityMah; private final double mDischargedPowerLowerBound; private final double mDischargedPowerUpperBound; private final long mBatteryTimeRemainingMs; Loading @@ -86,6 +90,7 @@ public final class BatteryUsageStats implements Parcelable { private BatteryUsageStats(@NonNull Builder builder) { mStatsStartTimestampMs = builder.mStatsStartTimestampMs; mBatteryCapacityMah = builder.mBatteryCapacityMah; mDischargePercentage = builder.mDischargePercentage; mDischargedPowerLowerBound = builder.mDischargedPowerLowerBoundMah; mDischargedPowerUpperBound = builder.mDischargedPowerUpperBoundMah; Loading Loading @@ -144,6 +149,13 @@ public final class BatteryUsageStats implements Parcelable { .getConsumedPower(); } /** * Returns battery capacity in milli-amp-hours. */ public double getBatteryCapacity() { return mBatteryCapacityMah; } /** * Portion of battery charge drained since BatteryStats reset (e.g. due to being fully * charged), as percentage of the full charge in the range [0:100] Loading Loading @@ -217,6 +229,7 @@ public final class BatteryUsageStats implements Parcelable { private BatteryUsageStats(@NonNull Parcel source) { mStatsStartTimestampMs = source.readLong(); mBatteryCapacityMah = source.readDouble(); mDischargePercentage = source.readInt(); mDischargedPowerLowerBound = source.readDouble(); mDischargedPowerUpperBound = source.readDouble(); Loading Loading @@ -274,6 +287,7 @@ public final class BatteryUsageStats implements Parcelable { @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeLong(mStatsStartTimestampMs); dest.writeDouble(mBatteryCapacityMah); dest.writeInt(mDischargePercentage); dest.writeDouble(mDischargedPowerLowerBound); dest.writeDouble(mDischargedPowerUpperBound); Loading Loading @@ -321,6 +335,104 @@ public final class BatteryUsageStats implements Parcelable { } }; /** * Prints the stats in a human-readable format. */ public void dump(PrintWriter pw, String prefix) { pw.print(prefix); pw.println(" Estimated power use (mAh):"); pw.print(prefix); pw.print(" Capacity: "); PowerCalculator.printPowerMah(pw, getBatteryCapacity()); pw.print(", Computed drain: "); PowerCalculator.printPowerMah(pw, getConsumedPower()); final Range<Double> dischargedPowerRange = getDischargedPowerRange(); pw.print(", actual drain: "); PowerCalculator.printPowerMah(pw, dischargedPowerRange.getLower()); if (!dischargedPowerRange.getLower().equals(dischargedPowerRange.getUpper())) { pw.print("-"); PowerCalculator.printPowerMah(pw, dischargedPowerRange.getUpper()); } pw.println(); pw.println(" Global"); final BatteryConsumer deviceConsumer = getAggregateBatteryConsumer( AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE); final BatteryConsumer appsConsumer = getAggregateBatteryConsumer( AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS); for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT; componentId++) { final double devicePowerMah = deviceConsumer.getConsumedPower(componentId); final double appsPowerMah = appsConsumer.getConsumedPower(componentId); if (devicePowerMah == 0 && appsPowerMah == 0) { continue; } final String componentName = BatteryConsumer.powerComponentIdToString(componentId); printPowerComponent(pw, prefix, componentName, devicePowerMah, appsPowerMah, deviceConsumer.getPowerModel(componentId), deviceConsumer.getUsageDurationMillis(componentId)); } for (int componentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID; componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + mCustomPowerComponentNames.length; componentId++) { final double devicePowerMah = deviceConsumer.getConsumedPowerForCustomComponent(componentId); final double appsPowerMah = appsConsumer.getConsumedPowerForCustomComponent(componentId); if (devicePowerMah == 0 && appsPowerMah == 0) { continue; } printPowerComponent(pw, prefix, deviceConsumer.getCustomPowerComponentName(componentId), devicePowerMah, appsPowerMah, BatteryConsumer.POWER_MODEL_UNDEFINED, deviceConsumer.getUsageDurationForCustomComponentMillis(componentId)); } dumpSortedBatteryConsumers(pw, prefix, getUidBatteryConsumers()); dumpSortedBatteryConsumers(pw, prefix, getUserBatteryConsumers()); } private void printPowerComponent(PrintWriter pw, String prefix, String componentName, double devicePowerMah, double appsPowerMah, int powerModel, long durationMs) { StringBuilder sb = new StringBuilder(); sb.append(prefix).append(" ").append(componentName).append(": ") .append(PowerCalculator.formatCharge(devicePowerMah)); if (powerModel != BatteryConsumer.POWER_MODEL_UNDEFINED && powerModel != BatteryConsumer.POWER_MODEL_POWER_PROFILE) { sb.append(" ["); sb.append(BatteryConsumer.powerModelToString(powerModel)); sb.append("]"); } sb.append(" apps: ").append(PowerCalculator.formatCharge(appsPowerMah)); if (durationMs != 0) { sb.append(" duration: "); BatteryStats.formatTimeMs(sb, durationMs); } pw.println(sb.toString()); } private void dumpSortedBatteryConsumers(PrintWriter pw, String prefix, List<? extends BatteryConsumer> batteryConsumers) { batteryConsumers.sort( Comparator.<BatteryConsumer>comparingDouble(BatteryConsumer::getConsumedPower) .reversed()); for (BatteryConsumer consumer : batteryConsumers) { if (consumer.getConsumedPower() == 0) { continue; } pw.print(prefix); pw.print(" "); consumer.dump(pw); pw.println(); } } /** * Builder for BatteryUsageStats. */ Loading @@ -329,6 +441,7 @@ public final class BatteryUsageStats implements Parcelable { private final String[] mCustomPowerComponentNames; private final boolean mIncludePowerModels; private long mStatsStartTimestampMs; private double mBatteryCapacityMah; private int mDischargePercentage; private double mDischargedPowerLowerBoundMah; private double mDischargedPowerUpperBoundMah; Loading Loading @@ -364,6 +477,14 @@ public final class BatteryUsageStats implements Parcelable { return new BatteryUsageStats(this); } /** * Sets the battery capacity in milli-amp-hours. */ public Builder setBatteryCapacity(double batteryCapacityMah) { mBatteryCapacityMah = batteryCapacityMah; return this; } /** * Sets the timestamp of the latest battery stats reset, in milliseconds. */ Loading
core/java/android/os/PowerComponents.java +35 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,10 @@ package android.os; import android.annotation.NonNull; import com.android.internal.os.PowerCalculator; import java.io.PrintWriter; /** * Contains details of battery attribution data broken down to individual power drain types * such as CPU, RAM, GPU etc. Loading Loading @@ -202,6 +206,37 @@ class PowerComponents { return max; } public void dump(PrintWriter pw, boolean skipEmptyComponents) { String separator = ""; for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT; componentId++) { final double componentPower = getConsumedPower(componentId); if (skipEmptyComponents && componentPower == 0) { continue; } pw.print(separator); separator = " "; pw.print(BatteryConsumer.powerComponentIdToString(componentId)); pw.print("="); PowerCalculator.printPowerMah(pw, componentPower); } final int customComponentCount = getCustomPowerComponentCount(); for (int customComponentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID; customComponentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + customComponentCount; customComponentId++) { final double customComponentPower = getConsumedPowerForCustomComponent(customComponentId); if (skipEmptyComponents && customComponentPower == 0) { continue; } pw.print(separator); separator = " "; pw.print(getCustomPowerComponentName(customComponentId)); pw.print("="); PowerCalculator.printPowerMah(pw, customComponentPower); } } /** * Builder for PowerComponents. */ Loading