Attributing and logging wifi wakeups

If Wifi is included in the transports of the network the packet came
on, we classify the wakeup as a Wifi wakeup.

Currently, only the packets arriving on the wifi interface are marked,
so we only do this for Wifi. We can add more subsystems once more
interfaces start marking these packets in the lower stack.

Test: Manually inspect the output of `dumpsys batterystats --wakeups`
and `statsd_testdrive 588`

Bug: 265742148
Change-Id: Id444757330bf776befd78116194e05e78a00f3ad
This commit is contained in:
Suprabh Shukla
2023-01-18 18:25:16 -08:00
parent 00f7aaf503
commit c060bf7892
4 changed files with 38 additions and 6 deletions

View File

@@ -17,14 +17,15 @@
*/
-->
<irq-device-map>
<!-- This file maps devices (chips) that can send IRQs to the CPU (and bring it out of sleep) to
logical subsystems in userspace code. Since each Android device has its own uniquely
designed chipset, this mapping is expected to be empty by default and should be overridden
by device specific configs.
<!-- This file maps devices (chips) that can send interrupts to the main processor (and bring it
out of sleep) to logical subsystems in userspace code. Since each Android device has its own
uniquely designed chipset, this mapping is expected to be empty by default and should be
overridden by device-specific configs.
This mapping helps the system to meaningfully attribute CPU wakeups to logical work that
happened on the device. The devices are referred to by their names as defined in the kernel.
Currently defined subsystems are:
Currently, defined subsystems are:
- Alarm: Use this to denote wakeup alarms requested by apps via the AlarmManager API.
- Wifi: Use this to denote network traffic that uses the wifi transport.
The overlay should use tags <device> and <subsystem> to describe this mapping in the
following way:

View File

@@ -38,11 +38,13 @@ public abstract class BatteryStatsInternal {
public static final int CPU_WAKEUP_SUBSYSTEM_UNKNOWN = -1;
public static final int CPU_WAKEUP_SUBSYSTEM_ALARM = 1;
public static final int CPU_WAKEUP_SUBSYSTEM_WIFI = 2;
/** @hide */
@IntDef(prefix = {"CPU_WAKEUP_SUBSYSTEM_"}, value = {
CPU_WAKEUP_SUBSYSTEM_UNKNOWN,
CPU_WAKEUP_SUBSYSTEM_ALARM,
CPU_WAKEUP_SUBSYSTEM_WIFI,
})
@Retention(RetentionPolicy.SOURCE)
@interface CpuWakeupSubsystem {

View File

@@ -23,6 +23,7 @@ import static android.Manifest.permission.NETWORK_STACK;
import static android.Manifest.permission.POWER_SAVER;
import static android.Manifest.permission.UPDATE_DEVICE_STATS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.os.BatteryStats.POWER_DATA_UNAVAILABLE;
@@ -479,9 +480,29 @@ public final class BatteryStatsService extends IBatteryStats.Stub
BatteryStatsService.this.noteJobsDeferred(uid, numDeferred, sinceLast);
}
private int transportToSubsystem(NetworkCapabilities nc) {
if (nc.hasTransport(TRANSPORT_WIFI)) {
return CPU_WAKEUP_SUBSYSTEM_WIFI;
}
return CPU_WAKEUP_SUBSYSTEM_UNKNOWN;
}
@Override
public void noteCpuWakingNetworkPacket(Network network, long elapsedMillis, int uid) {
Slog.d(TAG, "Wakeup due to incoming packet on network " + network + " to uid " + uid);
if (uid < 0) {
Slog.e(TAG, "Invalid uid for waking network packet: " + uid);
return;
}
final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
final NetworkCapabilities nc = cm.getNetworkCapabilities(network);
final int subsystem = transportToSubsystem(nc);
if (subsystem == CPU_WAKEUP_SUBSYSTEM_UNKNOWN) {
Slog.wtf(TAG, "Could not map transport for network: " + network
+ " while attributing wakeup by packet sent to uid: " + uid);
return;
}
noteCpuWakingActivity(subsystem, elapsedMillis, uid);
}
@Override

View File

@@ -18,6 +18,7 @@ package com.android.server.power.stats;
import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_ALARM;
import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_UNKNOWN;
import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_WIFI;
import android.content.Context;
import android.os.Handler;
@@ -49,6 +50,7 @@ public class CpuWakeupStats {
private static final String TAG = "CpuWakeupStats";
private static final String SUBSYSTEM_ALARM_STRING = "Alarm";
private static final String SUBSYSTEM_ALARM_WIFI = "Wifi";
@VisibleForTesting
static final long WAKEUP_RETENTION_MS = 3 * 24 * 60 * 60_000; // 3 days.
@VisibleForTesting
@@ -74,6 +76,8 @@ public class CpuWakeupStats {
switch (subsystem) {
case CPU_WAKEUP_SUBSYSTEM_ALARM:
return FrameworkStatsLog.KERNEL_WAKEUP_ATTRIBUTED__REASON__ALARM;
case CPU_WAKEUP_SUBSYSTEM_WIFI:
return FrameworkStatsLog.KERNEL_WAKEUP_ATTRIBUTED__REASON__WIFI;
}
return FrameworkStatsLog.KERNEL_WAKEUP_ATTRIBUTED__REASON__UNKNOWN;
}
@@ -425,6 +429,8 @@ public class CpuWakeupStats {
switch (rawSubsystem) {
case SUBSYSTEM_ALARM_STRING:
return CPU_WAKEUP_SUBSYSTEM_ALARM;
case SUBSYSTEM_ALARM_WIFI:
return CPU_WAKEUP_SUBSYSTEM_WIFI;
}
return CPU_WAKEUP_SUBSYSTEM_UNKNOWN;
}
@@ -433,6 +439,8 @@ public class CpuWakeupStats {
switch (subsystem) {
case CPU_WAKEUP_SUBSYSTEM_ALARM:
return SUBSYSTEM_ALARM_STRING;
case CPU_WAKEUP_SUBSYSTEM_WIFI:
return SUBSYSTEM_ALARM_WIFI;
case CPU_WAKEUP_SUBSYSTEM_UNKNOWN:
return "Unknown";
}