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

Commit d55e18ec authored by Christopher Tate's avatar Christopher Tate Committed by Android (Google) Code Review
Browse files

Merge "Add AlarmManager.setWindow(...) for supplying an explicit delivery window"

parents 37ee2647 57ceaaa0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3057,6 +3057,7 @@ package android.app {
    method public void setRepeating(int, long, long, android.app.PendingIntent);
    method public void setTime(long);
    method public void setTimeZone(java.lang.String);
    method public void setWindow(int, long, long, android.app.PendingIntent);
    field public static final int ELAPSED_REALTIME = 3; // 0x3
    field public static final int ELAPSED_REALTIME_WAKEUP = 2; // 0x2
    field public static final deprecated long INTERVAL_DAY = 86400000L; // 0x5265c00L
+60 −9
Original line number Diff line number Diff line
@@ -84,9 +84,15 @@ public class AlarmManager
     */
    public static final int ELAPSED_REALTIME = 3;

    /** @hide */
    public static final long WINDOW_EXACT = 0;
    /** @hide */
    public static final long WINDOW_HEURISTIC = -1;

    private final IAlarmManager mService;
    private final boolean mAlwaysExact;


    /**
     * package private on purpose
     */
@@ -97,8 +103,14 @@ public class AlarmManager
        mAlwaysExact = (sdkVersion < Build.VERSION_CODES.KEY_LIME_PIE);
    }

    private long legacyExactLength() {
        return (mAlwaysExact ? WINDOW_EXACT : WINDOW_HEURISTIC);
    }

    /**
     * Schedule an alarm.  <b>Note: for timing operations (ticks, timeouts,
     * TBW: discussion of fuzzy nature of alarms in KLP+.
     *
     * <p>Schedule an alarm.  <b>Note: for timing operations (ticks, timeouts,
     * etc) it is easier and much more efficient to use
     * {@link android.os.Handler}.</b>  If there is already an alarm scheduled
     * for the same IntentSender, it will first be canceled.
@@ -130,7 +142,9 @@ public class AlarmManager
     * IntentSender.getBroadcast()}.
     *
     * @see android.os.Handler
     * @see #setExact
     * @see #setRepeating
     * @see #setWindow
     * @see #cancel
     * @see android.content.Context#sendBroadcast
     * @see android.content.Context#registerReceiver
@@ -141,7 +155,7 @@ public class AlarmManager
     * @see #RTC_WAKEUP
     */
    public void set(int type, long triggerAtMillis, PendingIntent operation) {
        setImpl(type, triggerAtMillis, 0, operation, mAlwaysExact);
        setImpl(type, triggerAtMillis, legacyExactLength(), 0, operation);
    }

    /**
@@ -182,6 +196,8 @@ public class AlarmManager
     *
     * @see android.os.Handler
     * @see #set
     * @see #setExact
     * @see #setWindow
     * @see #cancel
     * @see android.content.Context#sendBroadcast
     * @see android.content.Context#registerReceiver
@@ -193,7 +209,42 @@ public class AlarmManager
     */
    public void setRepeating(int type, long triggerAtMillis,
            long intervalMillis, PendingIntent operation) {
        setImpl(type, triggerAtMillis, intervalMillis, operation, mAlwaysExact);
        setImpl(type, triggerAtMillis, legacyExactLength(), intervalMillis, operation);
    }

    /**
     * Schedule an alarm to be delivered within a given window of time.
     *
     * TBW: clean up these docs
     *
     * @param type One of ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP, RTC or
     *        RTC_WAKEUP.
     * @param windowStartMillis The earliest time, in milliseconds, that the alarm should
     *        be delivered, expressed in the appropriate clock's units (depending on the alarm
     *        type).
     * @param windowLengthMillis The length of the requested delivery window,
     *        in milliseconds.  The alarm will be delivered no later than this many
     *        milliseconds after the windowStartMillis time.  Note that this parameter
     *        is a <i>duration,</i> not the timestamp of the end of the window.
     * @param operation Action to perform when the alarm goes off;
     *        typically comes from {@link PendingIntent#getBroadcast
     *        IntentSender.getBroadcast()}.
     *
     * @see #set
     * @see #setExact
     * @see #setRepeating
     * @see #cancel
     * @see android.content.Context#sendBroadcast
     * @see android.content.Context#registerReceiver
     * @see android.content.Intent#filterEquals
     * @see #ELAPSED_REALTIME
     * @see #ELAPSED_REALTIME_WAKEUP
     * @see #RTC
     * @see #RTC_WAKEUP
     */
    public void setWindow(int type, long windowStartMillis, long windowLengthMillis,
            PendingIntent operation) {
        setImpl(type, windowStartMillis, windowLengthMillis, 0, operation);
    }

    /**
@@ -201,13 +252,13 @@ public class AlarmManager
     * to the precise time specified.
     */
    public void setExact(int type, long triggerAtMillis, PendingIntent operation) {
        setImpl(type, triggerAtMillis, 0, operation, true);
        setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, operation);
    }

    private void setImpl(int type, long triggerAtMillis, long intervalMillis,
            PendingIntent operation, boolean isExact) {
    private void setImpl(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
            PendingIntent operation) {
        try {
            mService.set(type, triggerAtMillis, intervalMillis, operation, isExact);
            mService.set(type, triggerAtMillis, windowMillis, intervalMillis, operation);
        } catch (RemoteException ex) {
        }
    }
@@ -300,7 +351,7 @@ public class AlarmManager
    @Deprecated
    public void setInexactRepeating(int type, long triggerAtMillis,
            long intervalMillis, PendingIntent operation) {
        setRepeating(type, triggerAtMillis, intervalMillis, operation);
        setImpl(type, triggerAtMillis, WINDOW_HEURISTIC, intervalMillis, operation);
    }
    
    /**
+3 −1
Original line number Diff line number Diff line
@@ -24,7 +24,9 @@ import android.app.PendingIntent;
 * {@hide}
 */
interface IAlarmManager {
    void set(int type, long triggerAtTime, long interval, in PendingIntent operation, boolean isExact);
	/** windowLength == 0 means exact; windowLength < 0 means the let the OS decide */
    void set(int type, long triggerAtTime, long windowLength,
            long interval, in PendingIntent operation);
    void setTime(long millis);
    void setTimeZone(String zone);
    void remove(in PendingIntent operation);
+30 −16
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server;

import android.app.Activity;
import android.app.ActivityManagerNative;
import android.app.AlarmManager;
import android.app.IAlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
@@ -314,7 +315,7 @@ class AlarmManagerService extends IAlarmManager.Stub {
    }
    
    // minimum recurrence period or alarm futurity for us to be able to fuzz it
    private static final long MAX_FUZZABLE_INTERVAL = 10000;
    private static final long MIN_FUZZABLE_INTERVAL = 10000;
    private static final BatchTimeOrder sBatchOrder = new BatchTimeOrder();
    private final ArrayList<Batch> mAlarmBatches = new ArrayList<Batch>();

@@ -336,7 +337,7 @@ class AlarmManagerService extends IAlarmManager.Stub {
        long futurity = (interval == 0)
                ? (triggerAtTime - now)
                : interval;
        if (futurity < MAX_FUZZABLE_INTERVAL) {
        if (futurity < MIN_FUZZABLE_INTERVAL) {
            futurity = 0;
        }
        return triggerAtTime + (long)(.75 * futurity);
@@ -499,32 +500,45 @@ class AlarmManagerService extends IAlarmManager.Stub {
    }

    @Override
    public void set(int type, long triggerAtTime, long interval,
            PendingIntent operation, boolean isExact) {
        set(type, triggerAtTime, interval, operation, isExact, false);
    public void set(int type, long triggerAtTime, long windowLength, long interval,
            PendingIntent operation) {
        set(type, triggerAtTime, windowLength, interval, operation, false);
    }

    public void set(int type, long triggerAtTime, long interval,
            PendingIntent operation, boolean isExact, boolean isStandalone) {
    public void set(int type, long triggerAtTime, long windowLength, long interval,
            PendingIntent operation, boolean isStandalone) {
        if (operation == null) {
            Slog.w(TAG, "set/setRepeating ignored because there is no intent");
            return;
        }

        // Sanity check the window length.  This will catch people mistakenly
        // trying to pass an end-of-window timestamp rather than a duration.
        if (windowLength > AlarmManager.INTERVAL_HALF_DAY) {
            Slog.w(TAG, "Window length " + windowLength
                    + "ms suspiciously long; limiting to 1 hour");
            windowLength = AlarmManager.INTERVAL_HOUR;
        }

        if (type < RTC_WAKEUP || type > ELAPSED_REALTIME) {
            throw new IllegalArgumentException("Invalid alarm type " + type);
        }

        long nowElapsed = SystemClock.elapsedRealtime();
        long triggerElapsed = convertToElapsed(triggerAtTime, type);
        long maxElapsed = (isExact)
                ? triggerElapsed
                : maxTriggerTime(nowElapsed, triggerElapsed, interval);
        final long nowElapsed = SystemClock.elapsedRealtime();
        final long triggerElapsed = convertToElapsed(triggerAtTime, type);
        final long maxElapsed;
        if (windowLength == AlarmManager.WINDOW_EXACT) {
            maxElapsed = triggerElapsed;
        } else if (windowLength < 0) {
            maxElapsed = maxTriggerTime(nowElapsed, triggerElapsed, interval);
        } else {
            maxElapsed = triggerElapsed + windowLength;
        }

        synchronized (mLock) {
            if (DEBUG_BATCH) {
                Slog.v(TAG, "set(" + operation + ") : type=" + type
                        + " triggerAtTime=" + triggerAtTime
                        + " triggerAtTime=" + triggerAtTime + " win=" + windowLength
                        + " tElapsed=" + triggerElapsed + " maxElapsed=" + maxElapsed
                        + " interval=" + interval + " standalone=" + isStandalone);
            }
@@ -1218,8 +1232,8 @@ class AlarmManagerService extends IAlarmManager.Stub {
            // the top of the next minute.
            final long tickEventDelay = nextTime - currentTime;

            set(ELAPSED_REALTIME, SystemClock.elapsedRealtime() + tickEventDelay,
                    0, mTimeTickSender, true, true);
            set(ELAPSED_REALTIME, SystemClock.elapsedRealtime() + tickEventDelay, 0,
                    0, mTimeTickSender, true);
        }
	
        public void scheduleDateChangedEvent() {
@@ -1231,7 +1245,7 @@ class AlarmManagerService extends IAlarmManager.Stub {
            calendar.set(Calendar.MILLISECOND, 0);
            calendar.add(Calendar.DAY_OF_MONTH, 1);
      
            set(RTC, calendar.getTimeInMillis(), 0, mDateChangeSender, true, true);
            set(RTC, calendar.getTimeInMillis(), 0, 0, mDateChangeSender, true);
        }
    }