Add Multicast wakelock stats in battery-stats dump
This commit adds the statistics for multicast wakelocks (count/time)
in dump of battery-stats.
This enables debugging of power issues due to extensive wakeup of host
processor due to arrival of multicast packets, and help identify the
blamed application
Bug: 33649966
Test: Manual Test
Change-Id: I882f945dd36fa2881c59776b4954017bf3c76cd7
Signed-off-by: Ahmed ElArabawy <arabawy@google.com>
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index af91e81..811091e 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -224,6 +224,7 @@
* - Always On Display (screen doze mode) time and power
* New in version 28:
* - Light/Deep Doze power
+ * - WiFi Multicast Wakelock statistics (count & duration)
*/
static final int CHECKIN_VERSION = 28;
@@ -313,6 +314,8 @@
private static final String CAMERA_DATA = "cam";
private static final String VIDEO_DATA = "vid";
private static final String AUDIO_DATA = "aud";
+ private static final String WIFI_MULTICAST_TOTAL_DATA = "wmct";
+ private static final String WIFI_MULTICAST_DATA = "wmc";
public static final String RESULT_RECEIVER_CONTROLLER_KEY = "controller_activity";
@@ -516,6 +519,13 @@
public abstract ArrayMap<String, ? extends Wakelock> getWakelockStats();
/**
+ * Returns the WiFi Multicast Wakelock statistics.
+ *
+ * @return a Timer Object for the per uid Multicast statistics.
+ */
+ public abstract Timer getMulticastWakelockStats();
+
+ /**
* Returns a mapping containing sync statistics.
*
* @return a Map from Strings to Timer objects.
@@ -3363,13 +3373,16 @@
screenDozeTime / 1000);
- // Calculate wakelock times across all uids.
+ // Calculate both wakelock and wifi multicast wakelock times across all uids.
long fullWakeLockTimeTotal = 0;
long partialWakeLockTimeTotal = 0;
+ long multicastWakeLockTimeTotalMicros = 0;
+ int multicastWakeLockCountTotal = 0;
for (int iu = 0; iu < NU; iu++) {
final Uid u = uidStats.valueAt(iu);
+ // First calculating the wakelock stats
final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
= u.getWakelockStats();
for (int iw=wakelocks.size()-1; iw>=0; iw--) {
@@ -3387,6 +3400,13 @@
rawRealtime, which);
}
}
+
+ // Now calculating the wifi multicast wakelock stats
+ final Timer mcTimer = u.getMulticastWakelockStats();
+ if (mcTimer != null) {
+ multicastWakeLockTimeTotalMicros += mcTimer.getTotalTimeLocked(rawRealtime, which);
+ multicastWakeLockCountTotal += mcTimer.getCountLocked(which);
+ }
}
// Dump network stats
@@ -3502,6 +3522,11 @@
}
dumpLine(pw, 0 /* uid */, category, WIFI_SIGNAL_STRENGTH_COUNT_DATA, args);
+ // Dump Multicast total stats
+ dumpLine(pw, 0 /* uid */, category, WIFI_MULTICAST_TOTAL_DATA,
+ multicastWakeLockTimeTotalMicros / 1000,
+ multicastWakeLockCountTotal);
+
if (which == STATS_SINCE_UNPLUGGED) {
dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
getDischargeCurrentLevel());
@@ -3828,6 +3853,18 @@
}
}
+ // WiFi Multicast Wakelock Statistics
+ final Timer mcTimer = u.getMulticastWakelockStats();
+ if (mcTimer != null) {
+ final long totalMcWakelockTimeMs =
+ mcTimer.getTotalTimeLocked(rawRealtime, which) / 1000 ;
+ final int countMcWakelock = mcTimer.getCountLocked(which);
+ if(totalMcWakelockTimeMs > 0) {
+ dumpLine(pw, uid, category, WIFI_MULTICAST_DATA,
+ totalMcWakelockTimeMs, countMcWakelock);
+ }
+ }
+
final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
for (int isy=syncs.size()-1; isy>=0; isy--) {
final Timer timer = syncs.valueAt(isy);
@@ -4327,15 +4364,18 @@
pw.print(" Connectivity changes: "); pw.println(connChanges);
}
- // Calculate wakelock times across all uids.
+ // Calculate both wakelock and wifi multicast wakelock times across all uids.
long fullWakeLockTimeTotalMicros = 0;
long partialWakeLockTimeTotalMicros = 0;
+ long multicastWakeLockTimeTotalMicros = 0;
+ int multicastWakeLockCountTotal = 0;
final ArrayList<TimerEntry> timers = new ArrayList<>();
for (int iu = 0; iu < NU; iu++) {
final Uid u = uidStats.valueAt(iu);
+ // First calculate wakelock statistics
final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
= u.getWakelockStats();
for (int iw=wakelocks.size()-1; iw>=0; iw--) {
@@ -4363,6 +4403,13 @@
}
}
}
+
+ // Next calculate wifi multicast wakelock statistics
+ final Timer mcTimer = u.getMulticastWakelockStats();
+ if (mcTimer != null) {
+ multicastWakeLockTimeTotalMicros += mcTimer.getTotalTimeLocked(rawRealtime, which);
+ multicastWakeLockCountTotal += mcTimer.getCountLocked(which);
+ }
}
final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
@@ -4392,6 +4439,20 @@
pw.println(sb.toString());
}
+ if (multicastWakeLockTimeTotalMicros != 0) {
+ sb.setLength(0);
+ sb.append(prefix);
+ sb.append(" Total WiFi Multicast wakelock Count: ");
+ sb.append(multicastWakeLockCountTotal);
+ pw.println(sb.toString());
+
+ sb.setLength(0);
+ sb.append(prefix);
+ sb.append(" Total WiFi Multicast wakelock time: ");
+ formatTimeMsNoSpace(sb, (multicastWakeLockTimeTotalMicros + 500) / 1000);
+ pw.println(sb.toString());
+ }
+
pw.println("");
pw.print(prefix);
sb.setLength(0);
@@ -5309,6 +5370,24 @@
}
}
+ // Calculate multicast wakelock stats
+ final Timer mcTimer = u.getMulticastWakelockStats();
+ if (mcTimer != null) {
+ final long multicastWakeLockTimeMicros = mcTimer.getTotalTimeLocked(rawRealtime, which);
+ final int multicastWakeLockCount = mcTimer.getCountLocked(which);
+
+ if (multicastWakeLockTimeMicros > 0) {
+ sb.setLength(0);
+ sb.append(prefix);
+ sb.append(" WiFi Multicast Wakelock");
+ sb.append(" count = ");
+ sb.append(multicastWakeLockCount);
+ sb.append(" time = ");
+ formatTimeMsNoSpace(sb, (multicastWakeLockTimeMicros + 500) / 1000);
+ pw.println(sb.toString());
+ }
+ }
+
final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
for (int isy=syncs.size()-1; isy>=0; isy--) {
final Timer timer = syncs.valueAt(isy);
@@ -7085,6 +7164,10 @@
proto.end(wToken);
}
+ // Wifi Multicast Wakelock (WIFI_MULTICAST_WAKELOCK_DATA)
+ dumpTimer(proto, UidProto.WIFI_MULTICAST_WAKELOCK, u.getMulticastWakelockStats(),
+ rawRealtimeUs, which);
+
// Wakeup alarms (WAKEUP_ALARM_DATA)
for (int ipkg = packageStats.size() - 1; ipkg >= 0; --ipkg) {
final Uid.Pkg ps = packageStats.valueAt(ipkg);
@@ -7341,6 +7424,30 @@
getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT));
proto.end(mToken);
+ // Wifi multicast wakelock total stats (WIFI_MULTICAST_WAKELOCK_TOTAL_DATA)
+ // Calculate multicast wakelock stats across all uids.
+ long multicastWakeLockTimeTotalUs = 0;
+ int multicastWakeLockCountTotal = 0;
+
+ for (int iu = 0; iu < uidStats.size(); iu++) {
+ final Uid u = uidStats.valueAt(iu);
+
+ final Timer mcTimer = u.getMulticastWakelockStats();
+
+ if (mcTimer != null) {
+ multicastWakeLockTimeTotalUs +=
+ mcTimer.getTotalTimeLocked(rawRealtimeUs, which);
+ multicastWakeLockCountTotal += mcTimer.getCountLocked(which);
+ }
+ }
+
+ final long wmctToken = proto.start(SystemProto.WIFI_MULTICAST_WAKELOCK_TOTAL);
+ proto.write(SystemProto.WifiMulticastWakelockTotal.DURATION_MS,
+ multicastWakeLockTimeTotalUs / 1000);
+ proto.write(SystemProto.WifiMulticastWakelockTotal.COUNT,
+ multicastWakeLockCountTotal);
+ proto.end(wmctToken);
+
// Power use item (POWER_USE_ITEM_DATA)
final List<BatterySipper> sippers = helper.getUsageList();
if (sippers != null) {