summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Suprabh Shukla <suprabh@google.com> 2023-04-14 17:23:22 -0700
committer Suprabh Shukla <suprabh@google.com> 2023-04-19 19:02:23 -0700
commit4ed309b32275a13e44db23b3c250da91d429072b (patch)
treedaab6f6d42f3f49bc5d42fe5fce3884e65569e2a
parentd43a6541a3fe13ad22d35a9bcc6830adf278fd7e (diff)
Enable attribution for sensor and cellular wakeups
Sensor wakeup events are already being reported to batterystats. For cellular, the code in network stack will be enabled independently. Test: atest FrameworksServicesTests:CpuWakeupStatsTest Test: statsd_testdrive -e 588 Bug: 276498460 Bug: 275436924 Change-Id: I1fc925193b4f0e3713d29de552138287c9a9768e
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java3
-rw-r--r--services/core/java/android/os/BatteryStatsInternal.java24
-rw-r--r--services/core/java/com/android/server/am/BatteryStatsService.java43
-rw-r--r--services/core/java/com/android/server/power/stats/wakeups/CpuWakeupStats.java17
-rw-r--r--services/tests/servicestests/res/xml/irq_device_map_3.xml6
-rw-r--r--services/tests/servicestests/src/com/android/server/power/stats/wakeups/CpuWakeupStatsTest.java81
6 files changed, 150 insertions, 24 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 3772960e8ac4..df1b66612ea2 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -4873,8 +4873,7 @@ public class AlarmManagerService extends SystemService {
}
}
if (wakeupUids.size() > 0 && mBatteryStatsInternal != null) {
- mBatteryStatsInternal.noteCpuWakingActivity(
- BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_ALARM, nowELAPSED,
+ mBatteryStatsInternal.noteWakingAlarmBatch(nowELAPSED,
wakeupUids.toArray());
}
deliverAlarmsLocked(triggerList, nowELAPSED);
diff --git a/services/core/java/android/os/BatteryStatsInternal.java b/services/core/java/android/os/BatteryStatsInternal.java
index 12ee13183221..0713999d4354 100644
--- a/services/core/java/android/os/BatteryStatsInternal.java
+++ b/services/core/java/android/os/BatteryStatsInternal.java
@@ -17,7 +17,6 @@
package android.os;
import android.annotation.IntDef;
-import android.annotation.NonNull;
import android.net.Network;
import com.android.internal.os.BinderCallsStats;
@@ -40,6 +39,8 @@ public abstract class BatteryStatsInternal {
public static final int CPU_WAKEUP_SUBSYSTEM_ALARM = 1;
public static final int CPU_WAKEUP_SUBSYSTEM_WIFI = 2;
public static final int CPU_WAKEUP_SUBSYSTEM_SOUND_TRIGGER = 3;
+ public static final int CPU_WAKEUP_SUBSYSTEM_SENSOR = 4;
+ public static final int CPU_WAKEUP_SUBSYSTEM_CELLULAR_DATA = 5;
/** @hide */
@IntDef(prefix = {"CPU_WAKEUP_SUBSYSTEM_"}, value = {
@@ -47,9 +48,11 @@ public abstract class BatteryStatsInternal {
CPU_WAKEUP_SUBSYSTEM_ALARM,
CPU_WAKEUP_SUBSYSTEM_WIFI,
CPU_WAKEUP_SUBSYSTEM_SOUND_TRIGGER,
+ CPU_WAKEUP_SUBSYSTEM_SENSOR,
+ CPU_WAKEUP_SUBSYSTEM_CELLULAR_DATA,
})
@Retention(RetentionPolicy.SOURCE)
- @interface CpuWakeupSubsystem {
+ public @interface CpuWakeupSubsystem {
}
/**
@@ -107,19 +110,16 @@ public abstract class BatteryStatsInternal {
public abstract void noteBinderThreadNativeIds(int[] binderThreadNativeTids);
/**
- * Reports any activity that could potentially have caused the CPU to wake up.
- * Accepts a timestamp to allow free ordering between the event and its reporting.
- * @param subsystem The subsystem this activity should be attributed to.
- * @param elapsedMillis The time when this activity happened in the elapsed timebase.
- * @param uids The uid (or uids) that should be blamed for this activity.
- */
- public abstract void noteCpuWakingActivity(@CpuWakeupSubsystem int subsystem,
- long elapsedMillis, @NonNull int... uids);
-
- /**
* Reports a sound trigger recognition event that may have woken up the CPU.
* @param elapsedMillis The time when the event happened in the elapsed timebase.
* @param uid The uid that requested this trigger.
*/
public abstract void noteWakingSoundTrigger(long elapsedMillis, int uid);
+
+ /**
+ * Reports an alarm batch that would have woken up the CPU.
+ * @param elapsedMillis The time at which this alarm batch was scheduled to go off.
+ * @param uids the uids of all apps that have any alarm in this batch.
+ */
+ public abstract void noteWakingAlarmBatch(long elapsedMillis, int... uids);
}
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index c0b3a90d923b..d140403f77c3 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -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_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.os.BatteryStats.POWER_DATA_UNAVAILABLE;
@@ -51,6 +52,7 @@ import android.os.BatteryConsumer;
import android.os.BatteryManagerInternal;
import android.os.BatteryStats;
import android.os.BatteryStatsInternal;
+import android.os.BatteryStatsInternal.CpuWakeupSubsystem;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
import android.os.Binder;
@@ -474,6 +476,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub
private int transportToSubsystem(NetworkCapabilities nc) {
if (nc.hasTransport(TRANSPORT_WIFI)) {
return CPU_WAKEUP_SUBSYSTEM_WIFI;
+ } else if (nc.hasTransport(TRANSPORT_CELLULAR)) {
+ return CPU_WAKEUP_SUBSYSTEM_CELLULAR_DATA;
}
return CPU_WAKEUP_SUBSYSTEM_UNKNOWN;
}
@@ -514,14 +518,32 @@ public final class BatteryStatsService extends IBatteryStats.Stub
}
@Override
- public void noteCpuWakingActivity(int subsystem, long elapsedMillis, int... uids) {
- Objects.requireNonNull(uids);
- mHandler.post(() -> mCpuWakeupStats.noteWakingActivity(subsystem, elapsedMillis, uids));
- }
- @Override
public void noteWakingSoundTrigger(long elapsedMillis, int uid) {
noteCpuWakingActivity(CPU_WAKEUP_SUBSYSTEM_SOUND_TRIGGER, elapsedMillis, uid);
}
+
+ @Override
+ public void noteWakingAlarmBatch(long elapsedMillis, int... uids) {
+ noteCpuWakingActivity(CPU_WAKEUP_SUBSYSTEM_ALARM, elapsedMillis, uids);
+ }
+ }
+
+ /**
+ * Reports any activity that could potentially have caused the CPU to wake up.
+ * Accepts a timestamp to allow free ordering between the event and its reporting.
+ *
+ * <p>
+ * This method can be called multiple times for the same wakeup and then all attribution
+ * reported will be unioned as long as all reports are made within a small amount of cpu uptime
+ * after the wakeup is reported to batterystats.
+ *
+ * @param subsystem The subsystem this activity should be attributed to.
+ * @param elapsedMillis The time when this activity happened in the elapsed timebase.
+ * @param uids The uid (or uids) that should be blamed for this activity.
+ */
+ void noteCpuWakingActivity(@CpuWakeupSubsystem int subsystem, long elapsedMillis, int... uids) {
+ Objects.requireNonNull(uids);
+ mHandler.post(() -> mCpuWakeupStats.noteWakingActivity(subsystem, elapsedMillis, uids));
}
@Override
@@ -1267,6 +1289,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
if (callingUid != Process.SYSTEM_UID) {
throw new SecurityException("Calling uid " + callingUid + " is not system uid");
}
+ final long elapsedMillis = TimeUnit.NANOSECONDS.toMillis(elapsedNanos);
final SensorManager sm = mContext.getSystemService(SensorManager.class);
final Sensor sensor = sm.getSensorByHandle(sensorHandle);
@@ -1275,10 +1298,12 @@ public final class BatteryStatsService extends IBatteryStats.Stub
+ " received in noteWakeupSensorEvent");
return;
}
- Slog.i(TAG, "Sensor " + sensor + " wakeup event at " + elapsedNanos + " sent to uid "
- + uid);
- // TODO (b/275436924): Remove log and pipe to CpuWakeupStats for wakeup attribution
- // This method should return as quickly as possible. Use mHandler#post to do longer work.
+ if (uid < 0) {
+ Slog.wtf(TAG, "Invalid uid " + uid + " for sensor event with sensor: " + sensor);
+ return;
+ }
+ // TODO (b/278319756): Also pipe in Sensor type for more usefulness.
+ noteCpuWakingActivity(BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_SENSOR, elapsedMillis, uid);
}
@Override
diff --git a/services/core/java/com/android/server/power/stats/wakeups/CpuWakeupStats.java b/services/core/java/com/android/server/power/stats/wakeups/CpuWakeupStats.java
index 1d63489f3c4f..eb6d28e76ff8 100644
--- a/services/core/java/com/android/server/power/stats/wakeups/CpuWakeupStats.java
+++ b/services/core/java/com/android/server/power/stats/wakeups/CpuWakeupStats.java
@@ -17,6 +17,8 @@
package com.android.server.power.stats.wakeups;
import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_ALARM;
+import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_CELLULAR_DATA;
+import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_SENSOR;
import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_SOUND_TRIGGER;
import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_UNKNOWN;
import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_WIFI;
@@ -54,10 +56,11 @@ import java.util.regex.Pattern;
*/
public class CpuWakeupStats {
private static final String TAG = "CpuWakeupStats";
-
private static final String SUBSYSTEM_ALARM_STRING = "Alarm";
private static final String SUBSYSTEM_WIFI_STRING = "Wifi";
private static final String SUBSYSTEM_SOUND_TRIGGER_STRING = "Sound_trigger";
+ private static final String SUBSYSTEM_SENSOR_STRING = "Sensor";
+ private static final String SUBSYSTEM_CELLULAR_DATA_STRING = "Cellular_data";
private static final String TRACE_TRACK_WAKEUP_ATTRIBUTION = "wakeup_attribution";
@VisibleForTesting
static final long WAKEUP_REASON_HALF_WINDOW_MS = 500;
@@ -111,6 +114,10 @@ public class CpuWakeupStats {
return FrameworkStatsLog.KERNEL_WAKEUP_ATTRIBUTED__REASON__WIFI;
case CPU_WAKEUP_SUBSYSTEM_SOUND_TRIGGER:
return FrameworkStatsLog.KERNEL_WAKEUP_ATTRIBUTED__REASON__SOUND_TRIGGER;
+ case CPU_WAKEUP_SUBSYSTEM_SENSOR:
+ return FrameworkStatsLog.KERNEL_WAKEUP_ATTRIBUTED__REASON__SENSOR;
+ case CPU_WAKEUP_SUBSYSTEM_CELLULAR_DATA:
+ return FrameworkStatsLog.KERNEL_WAKEUP_ATTRIBUTED__REASON__CELLULAR_DATA;
}
return FrameworkStatsLog.KERNEL_WAKEUP_ATTRIBUTED__REASON__UNKNOWN;
}
@@ -542,6 +549,10 @@ public class CpuWakeupStats {
return CPU_WAKEUP_SUBSYSTEM_WIFI;
case SUBSYSTEM_SOUND_TRIGGER_STRING:
return CPU_WAKEUP_SUBSYSTEM_SOUND_TRIGGER;
+ case SUBSYSTEM_SENSOR_STRING:
+ return CPU_WAKEUP_SUBSYSTEM_SENSOR;
+ case SUBSYSTEM_CELLULAR_DATA_STRING:
+ return CPU_WAKEUP_SUBSYSTEM_CELLULAR_DATA;
}
return CPU_WAKEUP_SUBSYSTEM_UNKNOWN;
}
@@ -554,6 +565,10 @@ public class CpuWakeupStats {
return SUBSYSTEM_WIFI_STRING;
case CPU_WAKEUP_SUBSYSTEM_SOUND_TRIGGER:
return SUBSYSTEM_SOUND_TRIGGER_STRING;
+ case CPU_WAKEUP_SUBSYSTEM_SENSOR:
+ return SUBSYSTEM_SENSOR_STRING;
+ case CPU_WAKEUP_SUBSYSTEM_CELLULAR_DATA:
+ return SUBSYSTEM_CELLULAR_DATA_STRING;
case CPU_WAKEUP_SUBSYSTEM_UNKNOWN:
return "Unknown";
}
diff --git a/services/tests/servicestests/res/xml/irq_device_map_3.xml b/services/tests/servicestests/res/xml/irq_device_map_3.xml
index 7e2529aa0090..fd55428c48df 100644
--- a/services/tests/servicestests/res/xml/irq_device_map_3.xml
+++ b/services/tests/servicestests/res/xml/irq_device_map_3.xml
@@ -26,4 +26,10 @@
<device name="test.sound_trigger.device">
<subsystem>Sound_trigger</subsystem>
</device>
+ <device name="test.cellular_data.device">
+ <subsystem>Cellular_data</subsystem>
+ </device>
+ <device name="test.sensor.device">
+ <subsystem>Sensor</subsystem>
+ </device>
</irq-device-map> \ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/wakeups/CpuWakeupStatsTest.java b/services/tests/servicestests/src/com/android/server/power/stats/wakeups/CpuWakeupStatsTest.java
index dca67d6da7ad..76b6a820e4a7 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/wakeups/CpuWakeupStatsTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/stats/wakeups/CpuWakeupStatsTest.java
@@ -17,6 +17,8 @@
package com.android.server.power.stats.wakeups;
import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_ALARM;
+import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_CELLULAR_DATA;
+import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_SENSOR;
import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_SOUND_TRIGGER;
import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_UNKNOWN;
import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_WIFI;
@@ -50,6 +52,8 @@ public class CpuWakeupStatsTest {
private static final String KERNEL_REASON_ALARM_IRQ = "120 test.alarm.device";
private static final String KERNEL_REASON_WIFI_IRQ = "130 test.wifi.device";
private static final String KERNEL_REASON_SOUND_TRIGGER_IRQ = "129 test.sound_trigger.device";
+ private static final String KERNEL_REASON_SENSOR_IRQ = "15 test.sensor.device";
+ private static final String KERNEL_REASON_CELLULAR_DATA_IRQ = "18 test.cellular_data.device";
private static final String KERNEL_REASON_UNKNOWN_IRQ = "140 test.unknown.device";
private static final String KERNEL_REASON_UNKNOWN = "free-form-reason test.alarm.device";
private static final String KERNEL_REASON_ALARM_ABNORMAL = "-1 test.alarm.device";
@@ -110,6 +114,83 @@ public class CpuWakeupStatsTest {
}
@Test
+ public void irqAttributionAllCombinations() {
+ final int[] subsystems = new int[] {
+ CPU_WAKEUP_SUBSYSTEM_ALARM,
+ CPU_WAKEUP_SUBSYSTEM_WIFI,
+ CPU_WAKEUP_SUBSYSTEM_SOUND_TRIGGER,
+ CPU_WAKEUP_SUBSYSTEM_SENSOR,
+ CPU_WAKEUP_SUBSYSTEM_CELLULAR_DATA,
+ };
+
+ final String[] kernelReasons = new String[] {
+ KERNEL_REASON_ALARM_IRQ,
+ KERNEL_REASON_WIFI_IRQ,
+ KERNEL_REASON_SOUND_TRIGGER_IRQ,
+ KERNEL_REASON_SENSOR_IRQ,
+ KERNEL_REASON_CELLULAR_DATA_IRQ,
+ };
+
+ final int[] uids = new int[] {
+ TEST_UID_2, TEST_UID_3, TEST_UID_4, TEST_UID_1, TEST_UID_5
+ };
+
+ final int[] procStates = new int[] {
+ TEST_PROC_STATE_2,
+ TEST_PROC_STATE_3,
+ TEST_PROC_STATE_4,
+ TEST_PROC_STATE_1,
+ TEST_PROC_STATE_5
+ };
+
+ final int total = subsystems.length;
+ assertThat(kernelReasons.length).isEqualTo(total);
+ assertThat(uids.length).isEqualTo(total);
+ assertThat(procStates.length).isEqualTo(total);
+
+ for (int mask = 1; mask < (1 << total); mask++) {
+ final CpuWakeupStats obj = new CpuWakeupStats(sContext, R.xml.irq_device_map_3,
+ mHandler);
+ populateDefaultProcStates(obj);
+
+ final long wakeupTime = mRandom.nextLong(123456);
+
+ String combinedKernelReason = null;
+ for (int i = 0; i < total; i++) {
+ if ((mask & (1 << i)) != 0) {
+ combinedKernelReason = (combinedKernelReason == null)
+ ? kernelReasons[i]
+ : String.join(":", combinedKernelReason, kernelReasons[i]);
+ }
+
+ obj.noteWakingActivity(subsystems[i], wakeupTime + 2, uids[i]);
+ }
+ obj.noteWakeupTimeAndReason(wakeupTime, 1, combinedKernelReason);
+
+ assertThat(obj.mWakeupAttribution.size()).isEqualTo(1);
+
+ final SparseArray<SparseIntArray> attribution = obj.mWakeupAttribution.get(wakeupTime);
+ assertThat(attribution.size()).isEqualTo(Integer.bitCount(mask));
+
+ for (int i = 0; i < total; i++) {
+ if ((mask & (1 << i)) == 0) {
+ assertThat(attribution.contains(subsystems[i])).isFalse();
+ continue;
+ }
+ assertThat(attribution.contains(subsystems[i])).isTrue();
+ assertThat(attribution.get(subsystems[i]).get(uids[i])).isEqualTo(procStates[i]);
+
+ for (int j = 0; j < total; j++) {
+ if (i == j) {
+ continue;
+ }
+ assertThat(attribution.get(subsystems[i]).indexOfKey(uids[j])).isLessThan(0);
+ }
+ }
+ }
+ }
+
+ @Test
public void alarmIrqAttributionSolo() {
final CpuWakeupStats obj = new CpuWakeupStats(sContext, R.xml.irq_device_map_3, mHandler);
final long wakeupTime = 12423121;