Loading services/core/java/com/android/server/am/BatteryStatsService.java +1 −0 Original line number Diff line number Diff line Loading @@ -402,6 +402,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub public void systemServicesReady() { mStats.systemServicesReady(mContext); mCpuWakeupStats.systemServicesReady(); mWorker.systemServicesReady(); final INetworkManagementService nms = INetworkManagementService.Stub.asInterface( ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE)); Loading services/core/java/com/android/server/power/stats/CpuWakeupStats.java +73 −8 Original line number Diff line number Diff line Loading @@ -22,7 +22,9 @@ import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_WIFI; import android.content.Context; import android.os.Handler; import android.os.HandlerExecutor; import android.os.UserHandle; import android.provider.DeviceConfig; import android.util.IndentingPrintWriter; import android.util.IntArray; import android.util.LongSparseArray; Loading @@ -40,6 +42,8 @@ import com.android.internal.util.IntPair; import java.util.Arrays; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; Loading @@ -52,13 +56,13 @@ public class 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 static final long WAKEUP_REASON_HALF_WINDOW_MS = 500; private static final long WAKEUP_WRITE_DELAY_MS = 2 * 60 * 1000; // 2 minutes. private static final long WAKEUP_WRITE_DELAY_MS = TimeUnit.MINUTES.toMillis(2); private final Handler mHandler; private final IrqDeviceMap mIrqDeviceMap; @VisibleForTesting final Config mConfig = new Config(); private final WakingActivityHistory mRecentWakingActivity = new WakingActivityHistory(); @VisibleForTesting Loading @@ -72,6 +76,14 @@ public class CpuWakeupStats { mHandler = handler; } /** * Called on the boot phase SYSTEM_SERVICES_READY. * This ensures that DeviceConfig is ready for calls to read properties. */ public synchronized void systemServicesReady() { mConfig.register(new HandlerExecutor(mHandler)); } private static int subsystemToStatsReason(int subsystem) { switch (subsystem) { case CPU_WAKEUP_SUBSYSTEM_ALARM: Loading Loading @@ -136,14 +148,15 @@ public class CpuWakeupStats { // we can delete all history that will not be useful in attributing future wakeups. mRecentWakingActivity.clearAllBefore(elapsedRealtime - WAKEUP_REASON_HALF_WINDOW_MS); // Limit history of wakeups and their attribution to the last WAKEUP_RETENTION_MS. Note that // Limit history of wakeups and their attribution to the last retentionDuration. Note that // the last wakeup and its attribution (if computed) is always stored, even if that wakeup // had occurred before WAKEUP_RETENTION_MS. int lastIdx = mWakeupEvents.closestIndexOnOrBefore(elapsedRealtime - WAKEUP_RETENTION_MS); // had occurred before retentionDuration. final long retentionDuration = mConfig.WAKEUP_STATS_RETENTION_MS; int lastIdx = mWakeupEvents.closestIndexOnOrBefore(elapsedRealtime - retentionDuration); for (int i = lastIdx; i >= 0; i--) { mWakeupEvents.removeAt(i); } lastIdx = mWakeupAttribution.closestIndexOnOrBefore(elapsedRealtime - WAKEUP_RETENTION_MS); lastIdx = mWakeupAttribution.closestIndexOnOrBefore(elapsedRealtime - retentionDuration); for (int i = lastIdx; i >= 0; i--) { mWakeupAttribution.removeAt(i); } Loading Loading @@ -226,6 +239,9 @@ public class CpuWakeupStats { pw.println("CPU wakeup stats:"); pw.increaseIndent(); mConfig.dump(pw); pw.println(); mIrqDeviceMap.dump(pw); pw.println(); Loading Loading @@ -296,7 +312,8 @@ public class CpuWakeupStats { } private static final class WakingActivityHistory { private static final long WAKING_ACTIVITY_RETENTION_MS = 3 * 60 * 60_000; // 3 hours. private static final long WAKING_ACTIVITY_RETENTION_MS = TimeUnit.MINUTES.toMillis(10); private SparseArray<TimeSparseArray<SparseBooleanArray>> mWakingActivity = new SparseArray<>(); Loading Loading @@ -521,4 +538,52 @@ public class CpuWakeupStats { } } } static final class Config implements DeviceConfig.OnPropertiesChangedListener { static final String KEY_WAKEUP_STATS_RETENTION_MS = "wakeup_stats_retention_ms"; private static final String[] PROPERTY_NAMES = { KEY_WAKEUP_STATS_RETENTION_MS, }; static final long DEFAULT_WAKEUP_STATS_RETENTION_MS = TimeUnit.DAYS.toMillis(3); /** * Wakeup stats are retained only for this duration. */ public volatile long WAKEUP_STATS_RETENTION_MS = DEFAULT_WAKEUP_STATS_RETENTION_MS; void register(Executor executor) { DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_BATTERY_STATS, executor, this); onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_BATTERY_STATS, PROPERTY_NAMES)); } @Override public void onPropertiesChanged(DeviceConfig.Properties properties) { for (String name : properties.getKeyset()) { if (name == null) { continue; } switch (name) { case KEY_WAKEUP_STATS_RETENTION_MS: WAKEUP_STATS_RETENTION_MS = properties.getLong( KEY_WAKEUP_STATS_RETENTION_MS, DEFAULT_WAKEUP_STATS_RETENTION_MS); break; } } } void dump(IndentingPrintWriter pw) { pw.println("Config:"); pw.increaseIndent(); pw.print(KEY_WAKEUP_STATS_RETENTION_MS, WAKEUP_STATS_RETENTION_MS); pw.println(); pw.decreaseIndent(); } } } services/tests/servicestests/src/com/android/server/power/stats/CpuWakeupStatsTest.java +5 −6 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_UNKNOWN; import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_WIFI; import static com.android.server.power.stats.CpuWakeupStats.WAKEUP_REASON_HALF_WINDOW_MS; import static com.android.server.power.stats.CpuWakeupStats.WAKEUP_RETENTION_MS; import static com.google.common.truth.Truth.assertThat; Loading Loading @@ -66,6 +65,7 @@ public class CpuWakeupStatsTest { public void removesOldWakeups() { // The xml resource doesn't matter for this test. final CpuWakeupStats obj = new CpuWakeupStats(sContext, R.xml.irq_device_map_1, mHandler); final long retention = obj.mConfig.WAKEUP_STATS_RETENTION_MS; final Set<Long> timestamps = new HashSet<>(); final long firstWakeup = 453192; Loading @@ -73,22 +73,21 @@ public class CpuWakeupStatsTest { obj.noteWakeupTimeAndReason(firstWakeup, 32, KERNEL_REASON_UNKNOWN_IRQ); timestamps.add(firstWakeup); for (int i = 1; i < 1000; i++) { final long delta = mRandom.nextLong(WAKEUP_RETENTION_MS); final long delta = mRandom.nextLong(retention); if (timestamps.add(firstWakeup + delta)) { obj.noteWakeupTimeAndReason(firstWakeup + delta, i, KERNEL_REASON_UNKNOWN_IRQ); } } assertThat(obj.mWakeupEvents.size()).isEqualTo(timestamps.size()); obj.noteWakeupTimeAndReason(firstWakeup + WAKEUP_RETENTION_MS + 1242, 231, obj.noteWakeupTimeAndReason(firstWakeup + retention + 1242, 231, KERNEL_REASON_UNKNOWN_IRQ); assertThat(obj.mWakeupEvents.size()).isEqualTo(timestamps.size()); for (int i = 0; i < 100; i++) { final long now = mRandom.nextLong(WAKEUP_RETENTION_MS + 1, 100 * WAKEUP_RETENTION_MS); final long now = mRandom.nextLong(retention + 1, 100 * retention); obj.noteWakeupTimeAndReason(now, i, KERNEL_REASON_UNKNOWN_IRQ); assertThat(obj.mWakeupEvents.closestIndexOnOrBefore(now - WAKEUP_RETENTION_MS)) .isLessThan(0); assertThat(obj.mWakeupEvents.closestIndexOnOrBefore(now - retention)).isLessThan(0); } } Loading Loading
services/core/java/com/android/server/am/BatteryStatsService.java +1 −0 Original line number Diff line number Diff line Loading @@ -402,6 +402,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub public void systemServicesReady() { mStats.systemServicesReady(mContext); mCpuWakeupStats.systemServicesReady(); mWorker.systemServicesReady(); final INetworkManagementService nms = INetworkManagementService.Stub.asInterface( ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE)); Loading
services/core/java/com/android/server/power/stats/CpuWakeupStats.java +73 −8 Original line number Diff line number Diff line Loading @@ -22,7 +22,9 @@ import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_WIFI; import android.content.Context; import android.os.Handler; import android.os.HandlerExecutor; import android.os.UserHandle; import android.provider.DeviceConfig; import android.util.IndentingPrintWriter; import android.util.IntArray; import android.util.LongSparseArray; Loading @@ -40,6 +42,8 @@ import com.android.internal.util.IntPair; import java.util.Arrays; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; Loading @@ -52,13 +56,13 @@ public class 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 static final long WAKEUP_REASON_HALF_WINDOW_MS = 500; private static final long WAKEUP_WRITE_DELAY_MS = 2 * 60 * 1000; // 2 minutes. private static final long WAKEUP_WRITE_DELAY_MS = TimeUnit.MINUTES.toMillis(2); private final Handler mHandler; private final IrqDeviceMap mIrqDeviceMap; @VisibleForTesting final Config mConfig = new Config(); private final WakingActivityHistory mRecentWakingActivity = new WakingActivityHistory(); @VisibleForTesting Loading @@ -72,6 +76,14 @@ public class CpuWakeupStats { mHandler = handler; } /** * Called on the boot phase SYSTEM_SERVICES_READY. * This ensures that DeviceConfig is ready for calls to read properties. */ public synchronized void systemServicesReady() { mConfig.register(new HandlerExecutor(mHandler)); } private static int subsystemToStatsReason(int subsystem) { switch (subsystem) { case CPU_WAKEUP_SUBSYSTEM_ALARM: Loading Loading @@ -136,14 +148,15 @@ public class CpuWakeupStats { // we can delete all history that will not be useful in attributing future wakeups. mRecentWakingActivity.clearAllBefore(elapsedRealtime - WAKEUP_REASON_HALF_WINDOW_MS); // Limit history of wakeups and their attribution to the last WAKEUP_RETENTION_MS. Note that // Limit history of wakeups and their attribution to the last retentionDuration. Note that // the last wakeup and its attribution (if computed) is always stored, even if that wakeup // had occurred before WAKEUP_RETENTION_MS. int lastIdx = mWakeupEvents.closestIndexOnOrBefore(elapsedRealtime - WAKEUP_RETENTION_MS); // had occurred before retentionDuration. final long retentionDuration = mConfig.WAKEUP_STATS_RETENTION_MS; int lastIdx = mWakeupEvents.closestIndexOnOrBefore(elapsedRealtime - retentionDuration); for (int i = lastIdx; i >= 0; i--) { mWakeupEvents.removeAt(i); } lastIdx = mWakeupAttribution.closestIndexOnOrBefore(elapsedRealtime - WAKEUP_RETENTION_MS); lastIdx = mWakeupAttribution.closestIndexOnOrBefore(elapsedRealtime - retentionDuration); for (int i = lastIdx; i >= 0; i--) { mWakeupAttribution.removeAt(i); } Loading Loading @@ -226,6 +239,9 @@ public class CpuWakeupStats { pw.println("CPU wakeup stats:"); pw.increaseIndent(); mConfig.dump(pw); pw.println(); mIrqDeviceMap.dump(pw); pw.println(); Loading Loading @@ -296,7 +312,8 @@ public class CpuWakeupStats { } private static final class WakingActivityHistory { private static final long WAKING_ACTIVITY_RETENTION_MS = 3 * 60 * 60_000; // 3 hours. private static final long WAKING_ACTIVITY_RETENTION_MS = TimeUnit.MINUTES.toMillis(10); private SparseArray<TimeSparseArray<SparseBooleanArray>> mWakingActivity = new SparseArray<>(); Loading Loading @@ -521,4 +538,52 @@ public class CpuWakeupStats { } } } static final class Config implements DeviceConfig.OnPropertiesChangedListener { static final String KEY_WAKEUP_STATS_RETENTION_MS = "wakeup_stats_retention_ms"; private static final String[] PROPERTY_NAMES = { KEY_WAKEUP_STATS_RETENTION_MS, }; static final long DEFAULT_WAKEUP_STATS_RETENTION_MS = TimeUnit.DAYS.toMillis(3); /** * Wakeup stats are retained only for this duration. */ public volatile long WAKEUP_STATS_RETENTION_MS = DEFAULT_WAKEUP_STATS_RETENTION_MS; void register(Executor executor) { DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_BATTERY_STATS, executor, this); onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_BATTERY_STATS, PROPERTY_NAMES)); } @Override public void onPropertiesChanged(DeviceConfig.Properties properties) { for (String name : properties.getKeyset()) { if (name == null) { continue; } switch (name) { case KEY_WAKEUP_STATS_RETENTION_MS: WAKEUP_STATS_RETENTION_MS = properties.getLong( KEY_WAKEUP_STATS_RETENTION_MS, DEFAULT_WAKEUP_STATS_RETENTION_MS); break; } } } void dump(IndentingPrintWriter pw) { pw.println("Config:"); pw.increaseIndent(); pw.print(KEY_WAKEUP_STATS_RETENTION_MS, WAKEUP_STATS_RETENTION_MS); pw.println(); pw.decreaseIndent(); } } }
services/tests/servicestests/src/com/android/server/power/stats/CpuWakeupStatsTest.java +5 −6 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_UNKNOWN; import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_WIFI; import static com.android.server.power.stats.CpuWakeupStats.WAKEUP_REASON_HALF_WINDOW_MS; import static com.android.server.power.stats.CpuWakeupStats.WAKEUP_RETENTION_MS; import static com.google.common.truth.Truth.assertThat; Loading Loading @@ -66,6 +65,7 @@ public class CpuWakeupStatsTest { public void removesOldWakeups() { // The xml resource doesn't matter for this test. final CpuWakeupStats obj = new CpuWakeupStats(sContext, R.xml.irq_device_map_1, mHandler); final long retention = obj.mConfig.WAKEUP_STATS_RETENTION_MS; final Set<Long> timestamps = new HashSet<>(); final long firstWakeup = 453192; Loading @@ -73,22 +73,21 @@ public class CpuWakeupStatsTest { obj.noteWakeupTimeAndReason(firstWakeup, 32, KERNEL_REASON_UNKNOWN_IRQ); timestamps.add(firstWakeup); for (int i = 1; i < 1000; i++) { final long delta = mRandom.nextLong(WAKEUP_RETENTION_MS); final long delta = mRandom.nextLong(retention); if (timestamps.add(firstWakeup + delta)) { obj.noteWakeupTimeAndReason(firstWakeup + delta, i, KERNEL_REASON_UNKNOWN_IRQ); } } assertThat(obj.mWakeupEvents.size()).isEqualTo(timestamps.size()); obj.noteWakeupTimeAndReason(firstWakeup + WAKEUP_RETENTION_MS + 1242, 231, obj.noteWakeupTimeAndReason(firstWakeup + retention + 1242, 231, KERNEL_REASON_UNKNOWN_IRQ); assertThat(obj.mWakeupEvents.size()).isEqualTo(timestamps.size()); for (int i = 0; i < 100; i++) { final long now = mRandom.nextLong(WAKEUP_RETENTION_MS + 1, 100 * WAKEUP_RETENTION_MS); final long now = mRandom.nextLong(retention + 1, 100 * retention); obj.noteWakeupTimeAndReason(now, i, KERNEL_REASON_UNKNOWN_IRQ); assertThat(obj.mWakeupEvents.closestIndexOnOrBefore(now - WAKEUP_RETENTION_MS)) .isLessThan(0); assertThat(obj.mWakeupEvents.closestIndexOnOrBefore(now - retention)).isLessThan(0); } } Loading