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

Commit b660bfd3 authored by Kweku Adams's avatar Kweku Adams Committed by Cherrypicker Worker
Browse files

Fix alarm throttling.

Alarm throttling wasn't happening if the queue became empty before a new
alarm was scheduled. This fixes that so the min time between alarms is
always enforced.

Bug: 288975061
Test: atest FrameworksMockingServicesTests:AlarmQueueTest
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:ef46dcbc567938823b600eca5d3349d661a5aeaf)
Merged-In: Id01bcf4e7d53ae7d89c99cb7f97b86163c43ea88
Change-Id: Id01bcf4e7d53ae7d89c99cb7f97b86163c43ea88
parent 1624ad46
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -151,6 +151,10 @@ public abstract class AlarmQueue<K> implements AlarmManager.OnAlarmListener {
    @GuardedBy("mLock")
    @ElapsedRealtimeLong
    private long mTriggerTimeElapsed = NOT_SCHEDULED;
    /** The last time an alarm went off (ie. the last time {@link #onAlarm()} was called}). */
    @GuardedBy("mLock")
    @ElapsedRealtimeLong
    private long mLastFireTimeElapsed;

    /**
     * @param alarmTag               The tag to use when scheduling the alarm with AlarmManager.
@@ -284,7 +288,7 @@ public abstract class AlarmQueue<K> implements AlarmManager.OnAlarmListener {
    /** Sets an alarm with {@link AlarmManager} for the earliest alarm in the queue after now. */
    @GuardedBy("mLock")
    private void setNextAlarmLocked() {
        setNextAlarmLocked(mInjector.getElapsedRealtime());
        setNextAlarmLocked(mLastFireTimeElapsed + mMinTimeBetweenAlarmsMs);
    }

    /**
@@ -334,6 +338,7 @@ public abstract class AlarmQueue<K> implements AlarmManager.OnAlarmListener {
        final ArraySet<K> expired = new ArraySet<>();
        synchronized (mLock) {
            final long nowElapsed = mInjector.getElapsedRealtime();
            mLastFireTimeElapsed = nowElapsed;
            while (mAlarmPriorityQueue.size() > 0) {
                final Pair<K, Long> alarm = mAlarmPriorityQueue.peek();
                if (alarm.second <= nowElapsed) {
+23 −0
Original line number Diff line number Diff line
@@ -258,6 +258,29 @@ public class AlarmQueueTest {
                anyInt(), eq(nowElapsed + 5 * HOUR_IN_MILLIS), eq(ALARM_TAG), any(), any());
    }

    @Test
    public void testMinTimeBetweenAlarms_freshAlarm() {
        final AlarmQueue<String> alarmQueue = createAlarmQueue(true, 5 * MINUTE_IN_MILLIS);
        final long fixedTimeElapsed = mInjector.getElapsedRealtime();

        InOrder inOrder = inOrder(mAlarmManager);

        final String pkg1 = "com.android.test.1";
        final String pkg2 = "com.android.test.2";
        alarmQueue.addAlarm(pkg1, fixedTimeElapsed + MINUTE_IN_MILLIS);
        inOrder.verify(mAlarmManager, timeout(1000).times(1)).setExact(
                anyInt(), eq(fixedTimeElapsed + MINUTE_IN_MILLIS), eq(ALARM_TAG), any(), any());

        advanceElapsedClock(MINUTE_IN_MILLIS);

        alarmQueue.onAlarm();
        // Minimum of 5 minutes between alarms, so the next alarm should be 5 minutes after the
        // first.
        alarmQueue.addAlarm(pkg2, fixedTimeElapsed + 2 * MINUTE_IN_MILLIS);
        inOrder.verify(mAlarmManager, timeout(1000).times(1)).setExact(
                anyInt(), eq(fixedTimeElapsed + 6 * MINUTE_IN_MILLIS), eq(ALARM_TAG), any(), any());
    }

    @Test
    public void testOnAlarm() {
        final AlarmQueue<String> alarmQueue = createAlarmQueue(true, 0);