diff options
-rw-r--r-- | apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java | 10 | ||||
-rw-r--r-- | services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java | 58 |
2 files changed, 65 insertions, 3 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java index 18ee6f2c7992..ba66ff72bfdd 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java @@ -4441,6 +4441,11 @@ public class AlarmManagerService extends SystemService { public void run() { ArrayList<Alarm> triggerList = new ArrayList<Alarm>(); + synchronized (mLock) { + mLastTimeChangeClockTime = mInjector.getCurrentTimeMillis(); + mLastTimeChangeRealtime = mInjector.getElapsedRealtimeMillis(); + } + while (true) { int result = mInjector.waitForAlarm(); final long nowRTC = mInjector.getCurrentTimeMillis(); @@ -4464,10 +4469,9 @@ public class AlarmManagerService extends SystemService { expectedClockTime = lastTimeChangeClockTime + (nowELAPSED - mLastTimeChangeRealtime); } - if (lastTimeChangeClockTime == 0 || nowRTC < (expectedClockTime - 1000) + if (nowRTC < (expectedClockTime - 1000) || nowRTC > (expectedClockTime + 1000)) { - // The change is by at least +/- 1000 ms (or this is the first change), - // let's do it! + // The change is by at least +/- 1000 ms, let's do it! if (DEBUG_BATCH) { Slog.v(TAG, "Time changed notification from kernel; rebatching"); } diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java index b980ca05b609..30de0e8c7981 100644 --- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java @@ -512,6 +512,9 @@ public final class AlarmManagerServiceTest { when(mPermissionManagerInternal.getAppOpPermissionPackages( SCHEDULE_EXACT_ALARM)).thenReturn(EmptyArray.STRING); + // Initialize timestamps with arbitrary values of time + mNowElapsedTest = 12; + mNowRtcTest = 345; mInjector = new Injector(mMockContext); mService = new AlarmManagerService(mMockContext, mInjector); spyOn(mService); @@ -774,6 +777,61 @@ public final class AlarmManagerServiceTest { } @Test + public void timeChangeBroadcastForward() throws Exception { + final long timeDelta = 12345; + // AlarmManagerService sends the broadcast if real time clock proceeds 1000ms more than boot + // time clock. + mNowRtcTest += timeDelta + 1001; + mNowElapsedTest += timeDelta; + mTestTimer.expire(TIME_CHANGED_MASK); + + verify(mMockContext) + .sendBroadcastAsUser( + argThat((intent) -> intent.getAction() == Intent.ACTION_TIME_CHANGED), + eq(UserHandle.ALL), + isNull(), + any()); + } + + @Test + public void timeChangeBroadcastBackward() throws Exception { + final long timeDelta = 12345; + // AlarmManagerService sends the broadcast if real time clock proceeds 1000ms less than boot + // time clock. + mNowRtcTest += timeDelta - 1001; + mNowElapsedTest += timeDelta; + mTestTimer.expire(TIME_CHANGED_MASK); + + verify(mMockContext) + .sendBroadcastAsUser( + argThat((intent) -> intent.getAction() == Intent.ACTION_TIME_CHANGED), + eq(UserHandle.ALL), + isNull(), + any()); + } + + @Test + public void timeChangeFilterMinorAdjustment() throws Exception { + final long timeDelta = 12345; + // AlarmManagerService does not send the broadcast if real time clock proceeds within 1000ms + // than boot time clock. + mNowRtcTest += timeDelta + 1000; + mNowElapsedTest += timeDelta; + mTestTimer.expire(TIME_CHANGED_MASK); + + mNowRtcTest += timeDelta - 1000; + mNowElapsedTest += timeDelta; + mTestTimer.expire(TIME_CHANGED_MASK); + + verify(mMockContext, never()) + .sendBroadcastAsUser( + argThat((intent) -> intent.getAction() == Intent.ACTION_TIME_CHANGED), + any(), + any(), + any()); + } + + @Test public void testSingleAlarmExpiration() throws Exception { final long triggerTime = mNowElapsedTest + 5000; final PendingIntent alarmPi = getNewMockPendingIntent(); |