summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java10
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java58
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();