diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index 8b524ddab458c..08c47dcaa9b79 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -75,6 +75,12 @@ class AlarmManagerService extends SystemService { // warning message. The time duration is in milliseconds. private static final long LATE_ALARM_THRESHOLD = 10 * 1000; + // Minimum futurity of a new alarm + private static final long MIN_FUTURITY = 5 * 1000; // 5 seconds, in millis + + // Minimum alarm recurrence interval + private static final long MIN_INTERVAL = 60 * 1000; // one minute, in millis + private static final int RTC_WAKEUP_MASK = 1 << RTC_WAKEUP; private static final int RTC_MASK = 1 << RTC; private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << ELAPSED_REALTIME_WAKEUP; @@ -696,6 +702,15 @@ class AlarmManagerService extends SystemService { windowLength = AlarmManager.INTERVAL_HOUR; } + // Sanity check the recurrence interval. This will catch people who supply + // seconds when the API expects milliseconds. + if (interval > 0 && interval < MIN_INTERVAL) { + Slog.w(TAG, "Suspiciously short interval " + interval + + " millis; expanding to " + (int)(MIN_INTERVAL/1000) + + " seconds"); + interval = MIN_INTERVAL; + } + if (type < RTC_WAKEUP || type > ELAPSED_REALTIME) { throw new IllegalArgumentException("Invalid alarm type " + type); } @@ -709,7 +724,11 @@ class AlarmManagerService extends SystemService { } final long nowElapsed = SystemClock.elapsedRealtime(); - final long triggerElapsed = convertToElapsed(triggerAtTime, type); + final long nominalTrigger = convertToElapsed(triggerAtTime, type); + // Try to prevent spamming by making sure we aren't firing alarms in the immediate future + final long minTrigger = nowElapsed + MIN_FUTURITY; + final long triggerElapsed = (nominalTrigger > minTrigger) ? nominalTrigger : minTrigger; + final long maxElapsed; if (windowLength == AlarmManager.WINDOW_EXACT) { maxElapsed = triggerElapsed;