Loading core/java/android/os/BatteryStats.java +235 −162 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ import android.app.job.JobParameters; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.location.GnssSignalQuality; import android.os.BatteryStatsManager.WifiState; import android.os.BatteryStatsManager.WifiSupplState; Loading @@ -43,6 +45,7 @@ import android.util.MutableBoolean; import android.util.Pair; import android.util.Printer; import android.util.SparseArray; import android.util.SparseDoubleArray; import android.util.SparseIntArray; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; Loading @@ -65,6 +68,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.Formatter; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; Loading Loading @@ -4126,7 +4130,28 @@ public abstract class BatteryStats implements Parcelable { * Temporary for settings. */ public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid) { dumpCheckinLocked(context, pw, which, reqUid, BatteryStatsHelper.checkWifiOnly(context)); dumpCheckinLocked(context, pw, which, reqUid, checkWifiOnly(context)); } private static final String[] CHECKIN_POWER_COMPONENT_LABELS = new String[BatteryConsumer.POWER_COMPONENT_COUNT]; static { // Assign individually to avoid future mismatch of indices CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_SCREEN] = "scrn"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_CPU] = "cpu"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_BLUETOOTH] = "blue"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_CAMERA] = "camera"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_AUDIO] = "audio"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_VIDEO] = "video"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_FLASHLIGHT] = "flashlight"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO] = "cell"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_SENSORS] = "sensors"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_GNSS] = "gnss"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_WIFI] = "wifi"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_MEMORY] = "memory"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_PHONE] = "phone"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY] = "ambi"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_IDLE] = "idle"; } /** Loading Loading @@ -4397,74 +4422,37 @@ public abstract class BatteryStats implements Parcelable { } } final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly); helper.create(this); helper.refreshStats(which, UserHandle.USER_ALL); final List<BatterySipper> sippers = helper.getUsageList(); if (sippers != null && sippers.size() > 0) { final BatteryUsageStats stats = getBatteryUsageStats(context); dumpLine(pw, 0 /* uid */, category, POWER_USE_SUMMARY_DATA, PowerCalculator.formatCharge(helper.getPowerProfile().getBatteryCapacity()), PowerCalculator.formatCharge(helper.getComputedPower()), PowerCalculator.formatCharge(helper.getMinDrainedPower()), PowerCalculator.formatCharge(helper.getMaxDrainedPower())); int uid = 0; for (int i=0; i<sippers.size(); i++) { final BatterySipper bs = sippers.get(i); String label; switch (bs.drainType) { case AMBIENT_DISPLAY: label = "ambi"; break; case IDLE: label="idle"; break; case CELL: label="cell"; break; case PHONE: label="phone"; break; case WIFI: label="wifi"; break; case BLUETOOTH: label="blue"; break; case SCREEN: label="scrn"; break; case FLASHLIGHT: label="flashlight"; break; case APP: uid = bs.uidObj.getUid(); label = "uid"; break; case USER: uid = UserHandle.getUid(bs.userId, 0); label = "user"; break; case UNACCOUNTED: label = "unacc"; break; case OVERCOUNTED: label = "over"; break; case CAMERA: label = "camera"; break; case MEMORY: label = "memory"; break; default: PowerCalculator.formatCharge(stats.getBatteryCapacity()), PowerCalculator.formatCharge(stats.getConsumedPower()), PowerCalculator.formatCharge(stats.getDischargedPowerRange().getLower()), PowerCalculator.formatCharge(stats.getDischargedPowerRange().getUpper())); final BatteryConsumer deviceConsumer = stats.getAggregateBatteryConsumer( BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE); for (@BatteryConsumer.PowerComponent int powerComponent = 0; powerComponent < BatteryConsumer.POWER_COMPONENT_COUNT; powerComponent++) { String label = CHECKIN_POWER_COMPONENT_LABELS[powerComponent]; if (label == null) { label = "???"; } dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label, PowerCalculator.formatCharge(bs.totalPowerMah), bs.shouldHide ? 1 : 0, PowerCalculator.formatCharge(bs.screenPowerMah), PowerCalculator.formatCharge(bs.proportionalSmearMah)); dumpLine(pw, 0 /* uid */, category, POWER_USE_ITEM_DATA, label, PowerCalculator.formatCharge(deviceConsumer.getConsumedPower(powerComponent)), shouldHidePowerComponent(powerComponent) ? 1 : 0, "0", "0"); } final ProportionalAttributionCalculator proportionalAttributionCalculator = new ProportionalAttributionCalculator(context, stats); final List<UidBatteryConsumer> uidBatteryConsumers = stats.getUidBatteryConsumers(); for (int i = 0; i < uidBatteryConsumers.size(); i++) { UidBatteryConsumer consumer = uidBatteryConsumers.get(i); dumpLine(pw, consumer.getUid(), category, POWER_USE_ITEM_DATA, "uid", PowerCalculator.formatCharge(consumer.getConsumedPower()), proportionalAttributionCalculator.isSystemBatteryConsumer(consumer) ? 1 : 0, PowerCalculator.formatCharge( consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN)), PowerCalculator.formatCharge( proportionalAttributionCalculator.getProportionalPowerMah(consumer))); } final long[] cpuFreqs = getCpuFreqs(); Loading Loading @@ -4909,7 +4897,7 @@ public abstract class BatteryStats implements Parcelable { */ public final void dumpLocked(Context context, PrintWriter pw, String prefix, int which, int reqUid) { dumpLocked(context, pw, prefix, which, reqUid, BatteryStatsHelper.checkWifiOnly(context)); dumpLocked(context, pw, prefix, which, reqUid, checkWifiOnly(context)); } @SuppressWarnings("unused") Loading Loading @@ -7625,21 +7613,20 @@ public abstract class BatteryStats implements Parcelable { proto.write(BatteryStatsProto.END_PLATFORM_VERSION, getEndPlatformVersion()); if ((flags & DUMP_DAILY_ONLY) == 0) { final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, (flags & DUMP_DEVICE_WIFI_ONLY) != 0); helper.create(this); helper.refreshStats(STATS_SINCE_CHARGED, UserHandle.USER_ALL); dumpProtoAppsLocked(proto, helper, apps); dumpProtoSystemLocked(proto, helper); final BatteryUsageStats stats = getBatteryUsageStats(context); ProportionalAttributionCalculator proportionalAttributionCalculator = new ProportionalAttributionCalculator(context, stats); dumpProtoAppsLocked(proto, stats, apps, proportionalAttributionCalculator); dumpProtoSystemLocked(proto, stats); } proto.end(bToken); proto.flush(); } private void dumpProtoAppsLocked(ProtoOutputStream proto, BatteryStatsHelper helper, List<ApplicationInfo> apps) { private void dumpProtoAppsLocked(ProtoOutputStream proto, BatteryUsageStats stats, List<ApplicationInfo> apps, ProportionalAttributionCalculator proportionalAttributionCalculator) { final int which = STATS_SINCE_CHARGED; final long rawUptimeUs = SystemClock.uptimeMillis() * 1000; final long rawRealtimeMs = SystemClock.elapsedRealtime(); Loading @@ -7660,17 +7647,11 @@ public abstract class BatteryStats implements Parcelable { } } SparseArray<BatterySipper> uidToSipper = new SparseArray<>(); final List<BatterySipper> sippers = helper.getUsageList(); if (sippers != null) { for (int i = 0; i < sippers.size(); ++i) { final BatterySipper bs = sippers.get(i); if (bs.drainType != BatterySipper.DrainType.APP) { // Others are handled by dumpProtoSystemLocked() continue; } uidToSipper.put(bs.uidObj.getUid(), bs); } SparseArray<UidBatteryConsumer> uidToConsumer = new SparseArray<>(); final List<UidBatteryConsumer> consumers = stats.getUidBatteryConsumers(); for (int i = consumers.size() - 1; i >= 0; --i) { final UidBatteryConsumer bs = consumers.get(i); uidToConsumer.put(bs.getUid(), bs); } SparseArray<? extends Uid> uidStats = getUidStats(); Loading Loading @@ -7936,14 +7917,16 @@ public abstract class BatteryStats implements Parcelable { proto.end(nToken); // Power use item (POWER_USE_ITEM_DATA) BatterySipper bs = uidToSipper.get(uid); if (bs != null) { UidBatteryConsumer consumer = uidToConsumer.get(uid); if (consumer != null) { final long bsToken = proto.start(UidProto.POWER_USE_ITEM); proto.write(UidProto.PowerUseItem.COMPUTED_POWER_MAH, bs.totalPowerMah); proto.write(UidProto.PowerUseItem.SHOULD_HIDE, bs.shouldHide); proto.write(UidProto.PowerUseItem.SCREEN_POWER_MAH, bs.screenPowerMah); proto.write(UidProto.PowerUseItem.COMPUTED_POWER_MAH, consumer.getConsumedPower()); proto.write(UidProto.PowerUseItem.SHOULD_HIDE, proportionalAttributionCalculator.isSystemBatteryConsumer(consumer)); proto.write(UidProto.PowerUseItem.SCREEN_POWER_MAH, consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN)); proto.write(UidProto.PowerUseItem.PROPORTIONAL_SMEAR_MAH, bs.proportionalSmearMah); proportionalAttributionCalculator.getProportionalPowerMah(consumer)); proto.end(bsToken); } Loading Loading @@ -8189,7 +8172,7 @@ public abstract class BatteryStats implements Parcelable { } } private void dumpProtoSystemLocked(ProtoOutputStream proto, BatteryStatsHelper helper) { private void dumpProtoSystemLocked(ProtoOutputStream proto, BatteryUsageStats stats) { final long sToken = proto.start(BatteryStatsProto.SYSTEM); final long rawUptimeUs = SystemClock.uptimeMillis() * 1000; final long rawRealtimeMs = SystemClock.elapsedRealtime(); Loading Loading @@ -8433,77 +8416,65 @@ public abstract class BatteryStats implements Parcelable { multicastWakeLockCountTotal); proto.end(wmctToken); // Power use item (POWER_USE_ITEM_DATA) final List<BatterySipper> sippers = helper.getUsageList(); if (sippers != null) { for (int i = 0; i < sippers.size(); ++i) { final BatterySipper bs = sippers.get(i); final BatteryConsumer deviceConsumer = stats.getAggregateBatteryConsumer( BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE); for (int powerComponent = 0; powerComponent < BatteryConsumer.POWER_COMPONENT_COUNT; powerComponent++) { int n = SystemProto.PowerUseItem.UNKNOWN_SIPPER; int uid = 0; switch (bs.drainType) { case AMBIENT_DISPLAY: switch (powerComponent) { case BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY: n = SystemProto.PowerUseItem.AMBIENT_DISPLAY; break; case IDLE: case BatteryConsumer.POWER_COMPONENT_IDLE: n = SystemProto.PowerUseItem.IDLE; break; case CELL: case BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO: n = SystemProto.PowerUseItem.CELL; break; case PHONE: case BatteryConsumer.POWER_COMPONENT_PHONE: n = SystemProto.PowerUseItem.PHONE; break; case WIFI: case BatteryConsumer.POWER_COMPONENT_WIFI: n = SystemProto.PowerUseItem.WIFI; break; case BLUETOOTH: case BatteryConsumer.POWER_COMPONENT_BLUETOOTH: n = SystemProto.PowerUseItem.BLUETOOTH; break; case SCREEN: case BatteryConsumer.POWER_COMPONENT_SCREEN: n = SystemProto.PowerUseItem.SCREEN; break; case FLASHLIGHT: case BatteryConsumer.POWER_COMPONENT_FLASHLIGHT: n = SystemProto.PowerUseItem.FLASHLIGHT; break; case APP: // dumpProtoAppsLocked will handle this. continue; case USER: n = SystemProto.PowerUseItem.USER; uid = UserHandle.getUid(bs.userId, 0); break; case UNACCOUNTED: n = SystemProto.PowerUseItem.UNACCOUNTED; break; case OVERCOUNTED: n = SystemProto.PowerUseItem.OVERCOUNTED; break; case CAMERA: case BatteryConsumer.POWER_COMPONENT_CAMERA: n = SystemProto.PowerUseItem.CAMERA; break; case MEMORY: case BatteryConsumer.POWER_COMPONENT_MEMORY: n = SystemProto.PowerUseItem.MEMORY; break; } final long puiToken = proto.start(SystemProto.POWER_USE_ITEM); proto.write(SystemProto.PowerUseItem.NAME, n); proto.write(SystemProto.PowerUseItem.UID, uid); proto.write(SystemProto.PowerUseItem.COMPUTED_POWER_MAH, bs.totalPowerMah); proto.write(SystemProto.PowerUseItem.SHOULD_HIDE, bs.shouldHide); proto.write(SystemProto.PowerUseItem.SCREEN_POWER_MAH, bs.screenPowerMah); proto.write(SystemProto.PowerUseItem.PROPORTIONAL_SMEAR_MAH, bs.proportionalSmearMah); proto.write(SystemProto.PowerUseItem.UID, 0); proto.write(SystemProto.PowerUseItem.COMPUTED_POWER_MAH, deviceConsumer.getConsumedPower(powerComponent)); proto.write(SystemProto.PowerUseItem.SHOULD_HIDE, shouldHidePowerComponent(powerComponent)); proto.write(SystemProto.PowerUseItem.SCREEN_POWER_MAH, 0); proto.write(SystemProto.PowerUseItem.PROPORTIONAL_SMEAR_MAH, 0); proto.end(puiToken); } } // Power use summary (POWER_USE_SUMMARY_DATA) final long pusToken = proto.start(SystemProto.POWER_USE_SUMMARY); proto.write(SystemProto.PowerUseSummary.BATTERY_CAPACITY_MAH, helper.getPowerProfile().getBatteryCapacity()); proto.write(SystemProto.PowerUseSummary.COMPUTED_POWER_MAH, helper.getComputedPower()); proto.write(SystemProto.PowerUseSummary.MIN_DRAINED_POWER_MAH, helper.getMinDrainedPower()); proto.write(SystemProto.PowerUseSummary.MAX_DRAINED_POWER_MAH, helper.getMaxDrainedPower()); stats.getBatteryCapacity()); proto.write(SystemProto.PowerUseSummary.COMPUTED_POWER_MAH, stats.getConsumedPower()); proto.write(SystemProto.PowerUseSummary.MIN_DRAINED_POWER_MAH, stats.getDischargedPowerRange().getLower()); proto.write(SystemProto.PowerUseSummary.MAX_DRAINED_POWER_MAH, stats.getDischargedPowerRange().getUpper()); proto.end(pusToken); // RPM stats (RESOURCE_POWER_MANAGER_DATA) Loading Loading @@ -8579,4 +8550,106 @@ public abstract class BatteryStats implements Parcelable { proto.end(sToken); } private static boolean checkWifiOnly(Context context) { final TelephonyManager tm = context.getSystemService(TelephonyManager.class); if (tm == null) { return false; } return !tm.isDataCapable(); } private BatteryUsageStats getBatteryUsageStats(Context context) { final BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, this); final BatteryUsageStatsQuery query = new BatteryUsageStatsQuery.Builder().setMaxStatsAgeMs(0).build(); return provider.getBatteryUsageStats(query); } private boolean shouldHidePowerComponent(int powerComponent) { return powerComponent == BatteryConsumer.POWER_COMPONENT_IDLE || powerComponent == BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO || powerComponent == BatteryConsumer.POWER_COMPONENT_SCREEN || powerComponent == BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY; } private static class ProportionalAttributionCalculator { private static final double SYSTEM_BATTERY_CONSUMER = -1; private final PackageManager mPackageManager; private final HashSet<String> mSystemAndServicePackages; private final SparseDoubleArray mProportionalPowerMah; ProportionalAttributionCalculator(Context context, BatteryUsageStats stats) { mPackageManager = context.getPackageManager(); final Resources resources = context.getResources(); final String[] systemPackageArray = resources.getStringArray( com.android.internal.R.array.config_batteryPackageTypeSystem); final String[] servicePackageArray = resources.getStringArray( com.android.internal.R.array.config_batteryPackageTypeService); mSystemAndServicePackages = new HashSet<>(systemPackageArray.length + servicePackageArray.length); for (String packageName : systemPackageArray) { mSystemAndServicePackages.add(packageName); } for (String packageName : servicePackageArray) { mSystemAndServicePackages.add(packageName); } final List<UidBatteryConsumer> uidBatteryConsumers = stats.getUidBatteryConsumers(); mProportionalPowerMah = new SparseDoubleArray(uidBatteryConsumers.size()); double systemPowerMah = 0; for (int i = uidBatteryConsumers.size() - 1; i >= 0; i--) { UidBatteryConsumer consumer = uidBatteryConsumers.get(i); final int uid = consumer.getUid(); if (isSystemUid(uid)) { mProportionalPowerMah.put(uid, SYSTEM_BATTERY_CONSUMER); systemPowerMah += consumer.getConsumedPower(); } } final double totalRemainingPower = stats.getConsumedPower() - systemPowerMah; if (Math.abs(totalRemainingPower) > 1e-3) { for (int i = uidBatteryConsumers.size() - 1; i >= 0; i--) { UidBatteryConsumer consumer = uidBatteryConsumers.get(i); final int uid = consumer.getUid(); if (mProportionalPowerMah.get(uid) != SYSTEM_BATTERY_CONSUMER) { final double power = consumer.getConsumedPower(); mProportionalPowerMah.put(uid, power + systemPowerMah * power / totalRemainingPower); } } } } boolean isSystemBatteryConsumer(UidBatteryConsumer consumer) { return mProportionalPowerMah.get(consumer.getUid()) < 0; } double getProportionalPowerMah(UidBatteryConsumer consumer) { final double powerMah = mProportionalPowerMah.get(consumer.getUid()); return powerMah >= 0 ? powerMah : 0; } /** * Check whether the UID is one of the system UIDs or a service UID */ private boolean isSystemUid(int uid) { if (uid >= Process.ROOT_UID && uid < Process.FIRST_APPLICATION_UID) { return true; } final String[] packages = mPackageManager.getPackagesForUid(uid); if (packages == null) { return false; } for (String packageName : packages) { if (mSystemAndServicePackages.contains(packageName)) { return true; } } return false; } } } Loading
core/java/android/os/BatteryStats.java +235 −162 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ import android.app.job.JobParameters; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.location.GnssSignalQuality; import android.os.BatteryStatsManager.WifiState; import android.os.BatteryStatsManager.WifiSupplState; Loading @@ -43,6 +45,7 @@ import android.util.MutableBoolean; import android.util.Pair; import android.util.Printer; import android.util.SparseArray; import android.util.SparseDoubleArray; import android.util.SparseIntArray; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; Loading @@ -65,6 +68,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.Formatter; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; Loading Loading @@ -4126,7 +4130,28 @@ public abstract class BatteryStats implements Parcelable { * Temporary for settings. */ public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid) { dumpCheckinLocked(context, pw, which, reqUid, BatteryStatsHelper.checkWifiOnly(context)); dumpCheckinLocked(context, pw, which, reqUid, checkWifiOnly(context)); } private static final String[] CHECKIN_POWER_COMPONENT_LABELS = new String[BatteryConsumer.POWER_COMPONENT_COUNT]; static { // Assign individually to avoid future mismatch of indices CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_SCREEN] = "scrn"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_CPU] = "cpu"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_BLUETOOTH] = "blue"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_CAMERA] = "camera"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_AUDIO] = "audio"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_VIDEO] = "video"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_FLASHLIGHT] = "flashlight"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO] = "cell"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_SENSORS] = "sensors"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_GNSS] = "gnss"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_WIFI] = "wifi"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_MEMORY] = "memory"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_PHONE] = "phone"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY] = "ambi"; CHECKIN_POWER_COMPONENT_LABELS[BatteryConsumer.POWER_COMPONENT_IDLE] = "idle"; } /** Loading Loading @@ -4397,74 +4422,37 @@ public abstract class BatteryStats implements Parcelable { } } final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly); helper.create(this); helper.refreshStats(which, UserHandle.USER_ALL); final List<BatterySipper> sippers = helper.getUsageList(); if (sippers != null && sippers.size() > 0) { final BatteryUsageStats stats = getBatteryUsageStats(context); dumpLine(pw, 0 /* uid */, category, POWER_USE_SUMMARY_DATA, PowerCalculator.formatCharge(helper.getPowerProfile().getBatteryCapacity()), PowerCalculator.formatCharge(helper.getComputedPower()), PowerCalculator.formatCharge(helper.getMinDrainedPower()), PowerCalculator.formatCharge(helper.getMaxDrainedPower())); int uid = 0; for (int i=0; i<sippers.size(); i++) { final BatterySipper bs = sippers.get(i); String label; switch (bs.drainType) { case AMBIENT_DISPLAY: label = "ambi"; break; case IDLE: label="idle"; break; case CELL: label="cell"; break; case PHONE: label="phone"; break; case WIFI: label="wifi"; break; case BLUETOOTH: label="blue"; break; case SCREEN: label="scrn"; break; case FLASHLIGHT: label="flashlight"; break; case APP: uid = bs.uidObj.getUid(); label = "uid"; break; case USER: uid = UserHandle.getUid(bs.userId, 0); label = "user"; break; case UNACCOUNTED: label = "unacc"; break; case OVERCOUNTED: label = "over"; break; case CAMERA: label = "camera"; break; case MEMORY: label = "memory"; break; default: PowerCalculator.formatCharge(stats.getBatteryCapacity()), PowerCalculator.formatCharge(stats.getConsumedPower()), PowerCalculator.formatCharge(stats.getDischargedPowerRange().getLower()), PowerCalculator.formatCharge(stats.getDischargedPowerRange().getUpper())); final BatteryConsumer deviceConsumer = stats.getAggregateBatteryConsumer( BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE); for (@BatteryConsumer.PowerComponent int powerComponent = 0; powerComponent < BatteryConsumer.POWER_COMPONENT_COUNT; powerComponent++) { String label = CHECKIN_POWER_COMPONENT_LABELS[powerComponent]; if (label == null) { label = "???"; } dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label, PowerCalculator.formatCharge(bs.totalPowerMah), bs.shouldHide ? 1 : 0, PowerCalculator.formatCharge(bs.screenPowerMah), PowerCalculator.formatCharge(bs.proportionalSmearMah)); dumpLine(pw, 0 /* uid */, category, POWER_USE_ITEM_DATA, label, PowerCalculator.formatCharge(deviceConsumer.getConsumedPower(powerComponent)), shouldHidePowerComponent(powerComponent) ? 1 : 0, "0", "0"); } final ProportionalAttributionCalculator proportionalAttributionCalculator = new ProportionalAttributionCalculator(context, stats); final List<UidBatteryConsumer> uidBatteryConsumers = stats.getUidBatteryConsumers(); for (int i = 0; i < uidBatteryConsumers.size(); i++) { UidBatteryConsumer consumer = uidBatteryConsumers.get(i); dumpLine(pw, consumer.getUid(), category, POWER_USE_ITEM_DATA, "uid", PowerCalculator.formatCharge(consumer.getConsumedPower()), proportionalAttributionCalculator.isSystemBatteryConsumer(consumer) ? 1 : 0, PowerCalculator.formatCharge( consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN)), PowerCalculator.formatCharge( proportionalAttributionCalculator.getProportionalPowerMah(consumer))); } final long[] cpuFreqs = getCpuFreqs(); Loading Loading @@ -4909,7 +4897,7 @@ public abstract class BatteryStats implements Parcelable { */ public final void dumpLocked(Context context, PrintWriter pw, String prefix, int which, int reqUid) { dumpLocked(context, pw, prefix, which, reqUid, BatteryStatsHelper.checkWifiOnly(context)); dumpLocked(context, pw, prefix, which, reqUid, checkWifiOnly(context)); } @SuppressWarnings("unused") Loading Loading @@ -7625,21 +7613,20 @@ public abstract class BatteryStats implements Parcelable { proto.write(BatteryStatsProto.END_PLATFORM_VERSION, getEndPlatformVersion()); if ((flags & DUMP_DAILY_ONLY) == 0) { final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, (flags & DUMP_DEVICE_WIFI_ONLY) != 0); helper.create(this); helper.refreshStats(STATS_SINCE_CHARGED, UserHandle.USER_ALL); dumpProtoAppsLocked(proto, helper, apps); dumpProtoSystemLocked(proto, helper); final BatteryUsageStats stats = getBatteryUsageStats(context); ProportionalAttributionCalculator proportionalAttributionCalculator = new ProportionalAttributionCalculator(context, stats); dumpProtoAppsLocked(proto, stats, apps, proportionalAttributionCalculator); dumpProtoSystemLocked(proto, stats); } proto.end(bToken); proto.flush(); } private void dumpProtoAppsLocked(ProtoOutputStream proto, BatteryStatsHelper helper, List<ApplicationInfo> apps) { private void dumpProtoAppsLocked(ProtoOutputStream proto, BatteryUsageStats stats, List<ApplicationInfo> apps, ProportionalAttributionCalculator proportionalAttributionCalculator) { final int which = STATS_SINCE_CHARGED; final long rawUptimeUs = SystemClock.uptimeMillis() * 1000; final long rawRealtimeMs = SystemClock.elapsedRealtime(); Loading @@ -7660,17 +7647,11 @@ public abstract class BatteryStats implements Parcelable { } } SparseArray<BatterySipper> uidToSipper = new SparseArray<>(); final List<BatterySipper> sippers = helper.getUsageList(); if (sippers != null) { for (int i = 0; i < sippers.size(); ++i) { final BatterySipper bs = sippers.get(i); if (bs.drainType != BatterySipper.DrainType.APP) { // Others are handled by dumpProtoSystemLocked() continue; } uidToSipper.put(bs.uidObj.getUid(), bs); } SparseArray<UidBatteryConsumer> uidToConsumer = new SparseArray<>(); final List<UidBatteryConsumer> consumers = stats.getUidBatteryConsumers(); for (int i = consumers.size() - 1; i >= 0; --i) { final UidBatteryConsumer bs = consumers.get(i); uidToConsumer.put(bs.getUid(), bs); } SparseArray<? extends Uid> uidStats = getUidStats(); Loading Loading @@ -7936,14 +7917,16 @@ public abstract class BatteryStats implements Parcelable { proto.end(nToken); // Power use item (POWER_USE_ITEM_DATA) BatterySipper bs = uidToSipper.get(uid); if (bs != null) { UidBatteryConsumer consumer = uidToConsumer.get(uid); if (consumer != null) { final long bsToken = proto.start(UidProto.POWER_USE_ITEM); proto.write(UidProto.PowerUseItem.COMPUTED_POWER_MAH, bs.totalPowerMah); proto.write(UidProto.PowerUseItem.SHOULD_HIDE, bs.shouldHide); proto.write(UidProto.PowerUseItem.SCREEN_POWER_MAH, bs.screenPowerMah); proto.write(UidProto.PowerUseItem.COMPUTED_POWER_MAH, consumer.getConsumedPower()); proto.write(UidProto.PowerUseItem.SHOULD_HIDE, proportionalAttributionCalculator.isSystemBatteryConsumer(consumer)); proto.write(UidProto.PowerUseItem.SCREEN_POWER_MAH, consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN)); proto.write(UidProto.PowerUseItem.PROPORTIONAL_SMEAR_MAH, bs.proportionalSmearMah); proportionalAttributionCalculator.getProportionalPowerMah(consumer)); proto.end(bsToken); } Loading Loading @@ -8189,7 +8172,7 @@ public abstract class BatteryStats implements Parcelable { } } private void dumpProtoSystemLocked(ProtoOutputStream proto, BatteryStatsHelper helper) { private void dumpProtoSystemLocked(ProtoOutputStream proto, BatteryUsageStats stats) { final long sToken = proto.start(BatteryStatsProto.SYSTEM); final long rawUptimeUs = SystemClock.uptimeMillis() * 1000; final long rawRealtimeMs = SystemClock.elapsedRealtime(); Loading Loading @@ -8433,77 +8416,65 @@ public abstract class BatteryStats implements Parcelable { multicastWakeLockCountTotal); proto.end(wmctToken); // Power use item (POWER_USE_ITEM_DATA) final List<BatterySipper> sippers = helper.getUsageList(); if (sippers != null) { for (int i = 0; i < sippers.size(); ++i) { final BatterySipper bs = sippers.get(i); final BatteryConsumer deviceConsumer = stats.getAggregateBatteryConsumer( BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE); for (int powerComponent = 0; powerComponent < BatteryConsumer.POWER_COMPONENT_COUNT; powerComponent++) { int n = SystemProto.PowerUseItem.UNKNOWN_SIPPER; int uid = 0; switch (bs.drainType) { case AMBIENT_DISPLAY: switch (powerComponent) { case BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY: n = SystemProto.PowerUseItem.AMBIENT_DISPLAY; break; case IDLE: case BatteryConsumer.POWER_COMPONENT_IDLE: n = SystemProto.PowerUseItem.IDLE; break; case CELL: case BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO: n = SystemProto.PowerUseItem.CELL; break; case PHONE: case BatteryConsumer.POWER_COMPONENT_PHONE: n = SystemProto.PowerUseItem.PHONE; break; case WIFI: case BatteryConsumer.POWER_COMPONENT_WIFI: n = SystemProto.PowerUseItem.WIFI; break; case BLUETOOTH: case BatteryConsumer.POWER_COMPONENT_BLUETOOTH: n = SystemProto.PowerUseItem.BLUETOOTH; break; case SCREEN: case BatteryConsumer.POWER_COMPONENT_SCREEN: n = SystemProto.PowerUseItem.SCREEN; break; case FLASHLIGHT: case BatteryConsumer.POWER_COMPONENT_FLASHLIGHT: n = SystemProto.PowerUseItem.FLASHLIGHT; break; case APP: // dumpProtoAppsLocked will handle this. continue; case USER: n = SystemProto.PowerUseItem.USER; uid = UserHandle.getUid(bs.userId, 0); break; case UNACCOUNTED: n = SystemProto.PowerUseItem.UNACCOUNTED; break; case OVERCOUNTED: n = SystemProto.PowerUseItem.OVERCOUNTED; break; case CAMERA: case BatteryConsumer.POWER_COMPONENT_CAMERA: n = SystemProto.PowerUseItem.CAMERA; break; case MEMORY: case BatteryConsumer.POWER_COMPONENT_MEMORY: n = SystemProto.PowerUseItem.MEMORY; break; } final long puiToken = proto.start(SystemProto.POWER_USE_ITEM); proto.write(SystemProto.PowerUseItem.NAME, n); proto.write(SystemProto.PowerUseItem.UID, uid); proto.write(SystemProto.PowerUseItem.COMPUTED_POWER_MAH, bs.totalPowerMah); proto.write(SystemProto.PowerUseItem.SHOULD_HIDE, bs.shouldHide); proto.write(SystemProto.PowerUseItem.SCREEN_POWER_MAH, bs.screenPowerMah); proto.write(SystemProto.PowerUseItem.PROPORTIONAL_SMEAR_MAH, bs.proportionalSmearMah); proto.write(SystemProto.PowerUseItem.UID, 0); proto.write(SystemProto.PowerUseItem.COMPUTED_POWER_MAH, deviceConsumer.getConsumedPower(powerComponent)); proto.write(SystemProto.PowerUseItem.SHOULD_HIDE, shouldHidePowerComponent(powerComponent)); proto.write(SystemProto.PowerUseItem.SCREEN_POWER_MAH, 0); proto.write(SystemProto.PowerUseItem.PROPORTIONAL_SMEAR_MAH, 0); proto.end(puiToken); } } // Power use summary (POWER_USE_SUMMARY_DATA) final long pusToken = proto.start(SystemProto.POWER_USE_SUMMARY); proto.write(SystemProto.PowerUseSummary.BATTERY_CAPACITY_MAH, helper.getPowerProfile().getBatteryCapacity()); proto.write(SystemProto.PowerUseSummary.COMPUTED_POWER_MAH, helper.getComputedPower()); proto.write(SystemProto.PowerUseSummary.MIN_DRAINED_POWER_MAH, helper.getMinDrainedPower()); proto.write(SystemProto.PowerUseSummary.MAX_DRAINED_POWER_MAH, helper.getMaxDrainedPower()); stats.getBatteryCapacity()); proto.write(SystemProto.PowerUseSummary.COMPUTED_POWER_MAH, stats.getConsumedPower()); proto.write(SystemProto.PowerUseSummary.MIN_DRAINED_POWER_MAH, stats.getDischargedPowerRange().getLower()); proto.write(SystemProto.PowerUseSummary.MAX_DRAINED_POWER_MAH, stats.getDischargedPowerRange().getUpper()); proto.end(pusToken); // RPM stats (RESOURCE_POWER_MANAGER_DATA) Loading Loading @@ -8579,4 +8550,106 @@ public abstract class BatteryStats implements Parcelable { proto.end(sToken); } private static boolean checkWifiOnly(Context context) { final TelephonyManager tm = context.getSystemService(TelephonyManager.class); if (tm == null) { return false; } return !tm.isDataCapable(); } private BatteryUsageStats getBatteryUsageStats(Context context) { final BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, this); final BatteryUsageStatsQuery query = new BatteryUsageStatsQuery.Builder().setMaxStatsAgeMs(0).build(); return provider.getBatteryUsageStats(query); } private boolean shouldHidePowerComponent(int powerComponent) { return powerComponent == BatteryConsumer.POWER_COMPONENT_IDLE || powerComponent == BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO || powerComponent == BatteryConsumer.POWER_COMPONENT_SCREEN || powerComponent == BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY; } private static class ProportionalAttributionCalculator { private static final double SYSTEM_BATTERY_CONSUMER = -1; private final PackageManager mPackageManager; private final HashSet<String> mSystemAndServicePackages; private final SparseDoubleArray mProportionalPowerMah; ProportionalAttributionCalculator(Context context, BatteryUsageStats stats) { mPackageManager = context.getPackageManager(); final Resources resources = context.getResources(); final String[] systemPackageArray = resources.getStringArray( com.android.internal.R.array.config_batteryPackageTypeSystem); final String[] servicePackageArray = resources.getStringArray( com.android.internal.R.array.config_batteryPackageTypeService); mSystemAndServicePackages = new HashSet<>(systemPackageArray.length + servicePackageArray.length); for (String packageName : systemPackageArray) { mSystemAndServicePackages.add(packageName); } for (String packageName : servicePackageArray) { mSystemAndServicePackages.add(packageName); } final List<UidBatteryConsumer> uidBatteryConsumers = stats.getUidBatteryConsumers(); mProportionalPowerMah = new SparseDoubleArray(uidBatteryConsumers.size()); double systemPowerMah = 0; for (int i = uidBatteryConsumers.size() - 1; i >= 0; i--) { UidBatteryConsumer consumer = uidBatteryConsumers.get(i); final int uid = consumer.getUid(); if (isSystemUid(uid)) { mProportionalPowerMah.put(uid, SYSTEM_BATTERY_CONSUMER); systemPowerMah += consumer.getConsumedPower(); } } final double totalRemainingPower = stats.getConsumedPower() - systemPowerMah; if (Math.abs(totalRemainingPower) > 1e-3) { for (int i = uidBatteryConsumers.size() - 1; i >= 0; i--) { UidBatteryConsumer consumer = uidBatteryConsumers.get(i); final int uid = consumer.getUid(); if (mProportionalPowerMah.get(uid) != SYSTEM_BATTERY_CONSUMER) { final double power = consumer.getConsumedPower(); mProportionalPowerMah.put(uid, power + systemPowerMah * power / totalRemainingPower); } } } } boolean isSystemBatteryConsumer(UidBatteryConsumer consumer) { return mProportionalPowerMah.get(consumer.getUid()) < 0; } double getProportionalPowerMah(UidBatteryConsumer consumer) { final double powerMah = mProportionalPowerMah.get(consumer.getUid()); return powerMah >= 0 ? powerMah : 0; } /** * Check whether the UID is one of the system UIDs or a service UID */ private boolean isSystemUid(int uid) { if (uid >= Process.ROOT_UID && uid < Process.FIRST_APPLICATION_UID) { return true; } final String[] packages = mPackageManager.getPackagesForUid(uid); if (packages == null) { return false; } for (String packageName : packages) { if (mSystemAndServicePackages.contains(packageName)) { return true; } } return false; } } }