Merge "Preserve window sizes when rebatching alarms" into klp-dev
diff --git a/services/java/com/android/server/AlarmManagerService.java b/services/java/com/android/server/AlarmManagerService.java
index 3d804ef..b70a34e 100644
--- a/services/java/com/android/server/AlarmManagerService.java
+++ b/services/java/com/android/server/AlarmManagerService.java
@@ -385,10 +385,19 @@
             for (int i = 0; i < N; i++) {
                 Alarm a = batch.get(i);
                 long whenElapsed = convertToElapsed(a.when, a.type);
-                long maxElapsed = (a.whenElapsed == a.maxWhen)
-                        ? whenElapsed
-                                : maxTriggerTime(nowElapsed, whenElapsed, a.repeatInterval);
-                setImplLocked(a.type, a.when, whenElapsed, maxElapsed,
+                final long maxElapsed;
+                if (a.whenElapsed == a.maxWhen) {
+                    // Exact
+                    maxElapsed = whenElapsed;
+                } else {
+                    // Not exact.  Preserve any explicit window, otherwise recalculate
+                    // the window based on the alarm's new futurity.  Note that this
+                    // reflects a policy of preferring timely to deferred delivery.
+                    maxElapsed = (a.windowLength > 0)
+                            ? (whenElapsed + a.windowLength)
+                            : maxTriggerTime(nowElapsed, whenElapsed, a.repeatInterval);
+                }
+                setImplLocked(a.type, a.when, whenElapsed, a.windowLength, maxElapsed,
                         a.repeatInterval, a.operation, batch.standalone, doValidate, a.workSource);
             }
         }
@@ -556,15 +565,16 @@
                         + " tElapsed=" + triggerElapsed + " maxElapsed=" + maxElapsed
                         + " interval=" + interval + " standalone=" + isStandalone);
             }
-            setImplLocked(type, triggerAtTime, triggerElapsed, maxElapsed,
+            setImplLocked(type, triggerAtTime, triggerElapsed, windowLength, maxElapsed,
                     interval, operation, isStandalone, true, workSource);
         }
     }
 
-    private void setImplLocked(int type, long when, long whenElapsed, long maxWhen, long interval,
-            PendingIntent operation, boolean isStandalone, boolean doValidate,
-            WorkSource workSource) {
-        Alarm a = new Alarm(type, when, whenElapsed, maxWhen, interval, operation, workSource);
+    private void setImplLocked(int type, long when, long whenElapsed, long windowLength,
+            long maxWhen, long interval, PendingIntent operation, boolean isStandalone,
+            boolean doValidate, WorkSource workSource) {
+        Alarm a = new Alarm(type, when, whenElapsed, windowLength, maxWhen, interval,
+                operation, workSource);
         removeLocked(operation);
 
         boolean reschedule;
@@ -1046,7 +1056,7 @@
                     // Also schedule its next recurrence
                     final long delta = alarm.count * alarm.repeatInterval;
                     final long nextElapsed = alarm.whenElapsed + delta;
-                    setImplLocked(alarm.type, alarm.when + delta, nextElapsed,
+                    setImplLocked(alarm.type, alarm.when + delta, nextElapsed, alarm.windowLength,
                             maxTriggerTime(nowELAPSED, nextElapsed, alarm.repeatInterval),
                             alarm.repeatInterval, alarm.operation, batch.standalone, true,
                             alarm.workSource);
@@ -1077,17 +1087,19 @@
         public int type;
         public int count;
         public long when;
+        public long windowLength;
         public long whenElapsed;    // 'when' in the elapsed time base
         public long maxWhen;        // also in the elapsed time base
         public long repeatInterval;
         public PendingIntent operation;
         public WorkSource workSource;
         
-        public Alarm(int _type, long _when, long _whenElapsed, long _maxWhen,
+        public Alarm(int _type, long _when, long _whenElapsed, long _windowLength, long _maxWhen,
                 long _interval, PendingIntent _op, WorkSource _ws) {
             type = _type;
             when = _when;
             whenElapsed = _whenElapsed;
+            windowLength = _windowLength;
             maxWhen = _maxWhen;
             repeatInterval = _interval;
             operation = _op;
@@ -1112,6 +1124,7 @@
             pw.print(prefix); pw.print("type="); pw.print(type);
                     pw.print(" whenElapsed="); pw.print(whenElapsed);
                     pw.print(" when="); TimeUtils.formatDuration(when, now, pw);
+                    pw.print(" window="); pw.print(windowLength);
                     pw.print(" repeatInterval="); pw.print(repeatInterval);
                     pw.print(" count="); pw.println(count);
             pw.print(prefix); pw.print("operation="); pw.println(operation);