Loading core/java/android/provider/Settings.java +1 −0 Original line number Diff line number Diff line Loading @@ -10784,6 +10784,7 @@ public final class Settings { * read_binary_cpu_time (boolean) * proc_state_cpu_times_read_delay_ms (long) * external_stats_collection_rate_limit_ms (long) * battery_level_collection_delay_ms (long) * </pre> * * <p> Loading core/java/com/android/internal/os/BatteryStatsImpl.java +13 −1 Original line number Diff line number Diff line Loading @@ -585,6 +585,7 @@ public class BatteryStatsImpl extends BatteryStats { boolean onBatteryScreenOff); Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis); void cancelCpuSyncDueToWakelockChange(); Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis); } public Handler mHandler; Loading Loading @@ -12614,7 +12615,8 @@ public class BatteryStatsImpl extends BatteryStats { // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record // which will pull external stats. scheduleSyncExternalStatsLocked("battery-level", ExternalStatsSync.UPDATE_ALL); mExternalSync.scheduleSyncDueToBatteryLevelChange( mConstants.BATTERY_LEVEL_COLLECTION_DELAY_MS); } if (mHistoryCur.batteryStatus != status) { mHistoryCur.batteryStatus = (byte)status; Loading Loading @@ -13270,6 +13272,8 @@ public class BatteryStatsImpl extends BatteryStats { = "uid_remove_delay_ms"; public static final String KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = "external_stats_collection_rate_limit_ms"; public static final String KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS = "battery_level_collection_delay_ms"; private static final boolean DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE = true; private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true; Loading @@ -13277,6 +13281,7 @@ public class BatteryStatsImpl extends BatteryStats { private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 10_000; private static final long DEFAULT_UID_REMOVE_DELAY_MS = 5L * 60L * 1000L; private static final long DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = 600_000; private static final long DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS = 300_000; public boolean TRACK_CPU_TIMES_BY_PROC_STATE = DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE; public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME; Loading @@ -13285,6 +13290,8 @@ public class BatteryStatsImpl extends BatteryStats { public long UID_REMOVE_DELAY_MS = DEFAULT_UID_REMOVE_DELAY_MS; public long EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; public long BATTERY_LEVEL_COLLECTION_DELAY_MS = DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS; private ContentResolver mResolver; private final KeyValueListParser mParser = new KeyValueListParser(','); Loading Loading @@ -13333,6 +13340,9 @@ public class BatteryStatsImpl extends BatteryStats { EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = mParser.getLong( KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS, DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); BATTERY_LEVEL_COLLECTION_DELAY_MS = mParser.getLong( KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS, DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS); } } Loading Loading @@ -13384,6 +13394,8 @@ public class BatteryStatsImpl extends BatteryStats { pw.println(KERNEL_UID_READERS_THROTTLE_TIME); pw.print(KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); pw.print("="); pw.println(EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); pw.print(KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS); pw.print("="); pw.println(BATTERY_LEVEL_COLLECTION_DELAY_MS); } } core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java +5 −0 Original line number Diff line number Diff line Loading @@ -190,6 +190,11 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl { @Override public void cancelCpuSyncDueToWakelockChange() { } @Override public Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis) { return null; } } } services/core/java/com/android/server/am/BatteryExternalStatsWorker.java +67 −18 Original line number Diff line number Diff line Loading @@ -103,6 +103,9 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { @GuardedBy("this") private Future<?> mWakelockChangesUpdate; @GuardedBy("this") private Future<?> mBatteryLevelSync; private final Object mWorkerLock = new Object(); @GuardedBy("mWorkerLock") Loading Loading @@ -197,35 +200,75 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { @Override public Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis) { if (mExecutorService.isShutdown()) { return CompletableFuture.failedFuture(new IllegalStateException("worker shutdown")); } if (mWakelockChangesUpdate != null) { // If there's already a scheduled task, leave it as is if we're trying to re-schedule // it again with a delay, otherwise cancel and re-schedule it. if (delayMillis == 0) { mWakelockChangesUpdate.cancel(false); } else { return mWakelockChangesUpdate; } } mWakelockChangesUpdate = mExecutorService.schedule(() -> { synchronized (BatteryExternalStatsWorker.this) { mWakelockChangesUpdate = scheduleDelayedSyncLocked(mWakelockChangesUpdate, () -> { scheduleSync("wakelock-change", UPDATE_CPU); scheduleRunnable(() -> mStats.postBatteryNeedsCpuUpdateMsg()); mWakelockChangesUpdate = null; }, delayMillis, TimeUnit.MILLISECONDS); }, delayMillis); return mWakelockChangesUpdate; } } @Override public void cancelCpuSyncDueToWakelockChange() { synchronized (BatteryExternalStatsWorker.this) { if (mWakelockChangesUpdate != null) { mWakelockChangesUpdate.cancel(false); mWakelockChangesUpdate = null; } } } @Override public Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis) { synchronized (BatteryExternalStatsWorker.this) { mBatteryLevelSync = scheduleDelayedSyncLocked(mBatteryLevelSync, () -> scheduleSync("battery-level", UPDATE_ALL), delayMillis); return mBatteryLevelSync; } } @GuardedBy("this") private void cancelSyncDueToBatteryLevelChangeLocked() { if (mBatteryLevelSync != null) { mBatteryLevelSync.cancel(false); mBatteryLevelSync = null; } } /** * Schedule a sync {@param syncRunnable} with a delay. If there's already a scheduled sync, a * new sync won't be scheduled unless it is being scheduled to run immediately (delayMillis=0). * * @param lastScheduledSync the task which was earlier scheduled to run * @param syncRunnable the task that needs to be scheduled to run * @param delayMillis time after which {@param syncRunnable} needs to be scheduled * @return scheduled {@link Future} which can be used to check if task is completed or to * cancel it if needed */ @GuardedBy("this") private Future<?> scheduleDelayedSyncLocked(Future<?> lastScheduledSync, Runnable syncRunnable, long delayMillis) { if (mExecutorService.isShutdown()) { return CompletableFuture.failedFuture(new IllegalStateException("worker shutdown")); } if (lastScheduledSync != null) { // If there's already a scheduled task, leave it as is if we're trying to // re-schedule it again with a delay, otherwise cancel and re-schedule it. if (delayMillis == 0) { lastScheduledSync.cancel(false); } else { return lastScheduledSync; } } return mExecutorService.schedule(syncRunnable, delayMillis, TimeUnit.MILLISECONDS); } public synchronized Future<?> scheduleWrite() { if (mExecutorService.isShutdown()) { return CompletableFuture.failedFuture(new IllegalStateException("worker shutdown")); Loading Loading @@ -294,6 +337,12 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { mUidsToRemove.clear(); mCurrentFuture = null; mUseLatestStates = true; if ((updateFlags & UPDATE_ALL) != 0) { cancelSyncDueToBatteryLevelChangeLocked(); } if ((updateFlags & UPDATE_CPU) != 0) { cancelCpuSyncDueToWakelockChange(); } } try { Loading Loading
core/java/android/provider/Settings.java +1 −0 Original line number Diff line number Diff line Loading @@ -10784,6 +10784,7 @@ public final class Settings { * read_binary_cpu_time (boolean) * proc_state_cpu_times_read_delay_ms (long) * external_stats_collection_rate_limit_ms (long) * battery_level_collection_delay_ms (long) * </pre> * * <p> Loading
core/java/com/android/internal/os/BatteryStatsImpl.java +13 −1 Original line number Diff line number Diff line Loading @@ -585,6 +585,7 @@ public class BatteryStatsImpl extends BatteryStats { boolean onBatteryScreenOff); Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis); void cancelCpuSyncDueToWakelockChange(); Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis); } public Handler mHandler; Loading Loading @@ -12614,7 +12615,8 @@ public class BatteryStatsImpl extends BatteryStats { // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record // which will pull external stats. scheduleSyncExternalStatsLocked("battery-level", ExternalStatsSync.UPDATE_ALL); mExternalSync.scheduleSyncDueToBatteryLevelChange( mConstants.BATTERY_LEVEL_COLLECTION_DELAY_MS); } if (mHistoryCur.batteryStatus != status) { mHistoryCur.batteryStatus = (byte)status; Loading Loading @@ -13270,6 +13272,8 @@ public class BatteryStatsImpl extends BatteryStats { = "uid_remove_delay_ms"; public static final String KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = "external_stats_collection_rate_limit_ms"; public static final String KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS = "battery_level_collection_delay_ms"; private static final boolean DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE = true; private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true; Loading @@ -13277,6 +13281,7 @@ public class BatteryStatsImpl extends BatteryStats { private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 10_000; private static final long DEFAULT_UID_REMOVE_DELAY_MS = 5L * 60L * 1000L; private static final long DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = 600_000; private static final long DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS = 300_000; public boolean TRACK_CPU_TIMES_BY_PROC_STATE = DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE; public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME; Loading @@ -13285,6 +13290,8 @@ public class BatteryStatsImpl extends BatteryStats { public long UID_REMOVE_DELAY_MS = DEFAULT_UID_REMOVE_DELAY_MS; public long EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; public long BATTERY_LEVEL_COLLECTION_DELAY_MS = DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS; private ContentResolver mResolver; private final KeyValueListParser mParser = new KeyValueListParser(','); Loading Loading @@ -13333,6 +13340,9 @@ public class BatteryStatsImpl extends BatteryStats { EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = mParser.getLong( KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS, DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); BATTERY_LEVEL_COLLECTION_DELAY_MS = mParser.getLong( KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS, DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS); } } Loading Loading @@ -13384,6 +13394,8 @@ public class BatteryStatsImpl extends BatteryStats { pw.println(KERNEL_UID_READERS_THROTTLE_TIME); pw.print(KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); pw.print("="); pw.println(EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); pw.print(KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS); pw.print("="); pw.println(BATTERY_LEVEL_COLLECTION_DELAY_MS); } }
core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java +5 −0 Original line number Diff line number Diff line Loading @@ -190,6 +190,11 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl { @Override public void cancelCpuSyncDueToWakelockChange() { } @Override public Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis) { return null; } } }
services/core/java/com/android/server/am/BatteryExternalStatsWorker.java +67 −18 Original line number Diff line number Diff line Loading @@ -103,6 +103,9 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { @GuardedBy("this") private Future<?> mWakelockChangesUpdate; @GuardedBy("this") private Future<?> mBatteryLevelSync; private final Object mWorkerLock = new Object(); @GuardedBy("mWorkerLock") Loading Loading @@ -197,35 +200,75 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { @Override public Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis) { if (mExecutorService.isShutdown()) { return CompletableFuture.failedFuture(new IllegalStateException("worker shutdown")); } if (mWakelockChangesUpdate != null) { // If there's already a scheduled task, leave it as is if we're trying to re-schedule // it again with a delay, otherwise cancel and re-schedule it. if (delayMillis == 0) { mWakelockChangesUpdate.cancel(false); } else { return mWakelockChangesUpdate; } } mWakelockChangesUpdate = mExecutorService.schedule(() -> { synchronized (BatteryExternalStatsWorker.this) { mWakelockChangesUpdate = scheduleDelayedSyncLocked(mWakelockChangesUpdate, () -> { scheduleSync("wakelock-change", UPDATE_CPU); scheduleRunnable(() -> mStats.postBatteryNeedsCpuUpdateMsg()); mWakelockChangesUpdate = null; }, delayMillis, TimeUnit.MILLISECONDS); }, delayMillis); return mWakelockChangesUpdate; } } @Override public void cancelCpuSyncDueToWakelockChange() { synchronized (BatteryExternalStatsWorker.this) { if (mWakelockChangesUpdate != null) { mWakelockChangesUpdate.cancel(false); mWakelockChangesUpdate = null; } } } @Override public Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis) { synchronized (BatteryExternalStatsWorker.this) { mBatteryLevelSync = scheduleDelayedSyncLocked(mBatteryLevelSync, () -> scheduleSync("battery-level", UPDATE_ALL), delayMillis); return mBatteryLevelSync; } } @GuardedBy("this") private void cancelSyncDueToBatteryLevelChangeLocked() { if (mBatteryLevelSync != null) { mBatteryLevelSync.cancel(false); mBatteryLevelSync = null; } } /** * Schedule a sync {@param syncRunnable} with a delay. If there's already a scheduled sync, a * new sync won't be scheduled unless it is being scheduled to run immediately (delayMillis=0). * * @param lastScheduledSync the task which was earlier scheduled to run * @param syncRunnable the task that needs to be scheduled to run * @param delayMillis time after which {@param syncRunnable} needs to be scheduled * @return scheduled {@link Future} which can be used to check if task is completed or to * cancel it if needed */ @GuardedBy("this") private Future<?> scheduleDelayedSyncLocked(Future<?> lastScheduledSync, Runnable syncRunnable, long delayMillis) { if (mExecutorService.isShutdown()) { return CompletableFuture.failedFuture(new IllegalStateException("worker shutdown")); } if (lastScheduledSync != null) { // If there's already a scheduled task, leave it as is if we're trying to // re-schedule it again with a delay, otherwise cancel and re-schedule it. if (delayMillis == 0) { lastScheduledSync.cancel(false); } else { return lastScheduledSync; } } return mExecutorService.schedule(syncRunnable, delayMillis, TimeUnit.MILLISECONDS); } public synchronized Future<?> scheduleWrite() { if (mExecutorService.isShutdown()) { return CompletableFuture.failedFuture(new IllegalStateException("worker shutdown")); Loading Loading @@ -294,6 +337,12 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { mUidsToRemove.clear(); mCurrentFuture = null; mUseLatestStates = true; if ((updateFlags & UPDATE_ALL) != 0) { cancelSyncDueToBatteryLevelChangeLocked(); } if ((updateFlags & UPDATE_CPU) != 0) { cancelCpuSyncDueToWakelockChange(); } } try { Loading