Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a750da19 authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Android (Google) Code Review
Browse files

Merge "Schedule external stats sync on battery level change with a delay" into pi-dev

parents 1186fb76 0719c6af
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -10776,6 +10776,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>
+13 −1
Original line number Diff line number Diff line
@@ -585,6 +585,7 @@ public class BatteryStatsImpl extends BatteryStats {
                boolean onBatteryScreenOff);
        Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis);
        void cancelCpuSyncDueToWakelockChange();
        Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis);
    }
    public Handler mHandler;
@@ -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;
@@ -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;
@@ -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;
@@ -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(',');
@@ -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);
            }
        }
@@ -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);
        }
    }
+5 −0
Original line number Diff line number Diff line
@@ -190,6 +190,11 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl {
        @Override
        public void cancelCpuSyncDueToWakelockChange() {
        }

        @Override
        public Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis) {
            return null;
        }
    }
}
+67 −18
Original line number Diff line number Diff line
@@ -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")
@@ -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"));
@@ -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 {