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

Commit 3e04b472 authored by Christopher Tate's avatar Christopher Tate
Browse files

Preserve window sizes when rebatching alarms

The existing code wasn't retaining the requested window bounds, if any,
and so could wind up rebatching alarms into much longer potential
delivery windows than originally demanded by the caller.  This could
wind up delivering alarms outside their designated windows entirely.

Bug 11324357

Change-Id: I4d418cd08702e397b3c7692b412d4bf51d5d9e4b
parent 089959a0
Loading
Loading
Loading
Loading
+24 −11
Original line number Diff line number Diff line
@@ -385,10 +385,19 @@ class AlarmManagerService extends IAlarmManager.Stub {
            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
                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, maxElapsed,
                }
                setImplLocked(a.type, a.when, whenElapsed, a.windowLength, maxElapsed,
                        a.repeatInterval, a.operation, batch.standalone, doValidate, a.workSource);
            }
        }
@@ -556,15 +565,16 @@ class AlarmManagerService extends IAlarmManager.Stub {
                        + " 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 @@ class AlarmManagerService extends IAlarmManager.Stub {
                    // 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 @@ class AlarmManagerService extends IAlarmManager.Stub {
        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 @@ class AlarmManagerService extends IAlarmManager.Stub {
            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);