diff options
| -rw-r--r-- | apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java | 13 | ||||
| -rw-r--r-- | services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java | 57 |
2 files changed, 59 insertions, 11 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 fe0c7f718bb0..fb5129f18417 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java @@ -2006,16 +2006,12 @@ public class AlarmManagerService extends SystemService { windowLength = INTERVAL_DAY; } else if ((flags & FLAG_PRIORITIZE) == 0 && windowLength < minAllowedWindow) { // Prioritized alarms are exempt from minimum window limits. - if (CompatChanges.isChangeEnabled( + if (!isExemptFromMinWindowRestrictions(callingUid) && CompatChanges.isChangeEnabled( AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS, callingPackage, UserHandle.getUserHandleForUid(callingUid))) { Slog.w(TAG, "Window length " + windowLength + "ms too short; expanding to " + minAllowedWindow + "ms."); windowLength = minAllowedWindow; - } else { - // TODO (b/185199076): Remove temporary log to catch breaking apps. - Slog.wtf(TAG, "Short window " + windowLength + "ms specified by " - + callingPackage); } } maxElapsed = triggerElapsed + windowLength; @@ -2409,6 +2405,13 @@ public class AlarmManagerService extends SystemService { } /** + * Returns true if the given uid can set window to be as small as it wants. + */ + boolean isExemptFromMinWindowRestrictions(int uid) { + return isExemptFromExactAlarmPermission(uid); + } + + /** * Returns true if the given uid does not require SCHEDULE_EXACT_ALARM to set exact, * allow-while-idle alarms. */ 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 21de7916e23d..280204dfd481 100644 --- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java @@ -2309,12 +2309,14 @@ public class AlarmManagerServiceTest { public void minWindowChangeDisabled() { mockChangeEnabled(AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS, false); final long minWindow = 73; + final long futurity = 10_000; setDeviceConfigLong(KEY_MIN_WINDOW, minWindow); // 0 is WINDOW_EXACT and < 0 is WINDOW_HEURISTIC. for (int window = 1; window <= minWindow; window++) { final PendingIntent pi = getNewMockPendingIntent(); - setTestAlarm(ELAPSED_REALTIME, 0, window, pi, 0, 0, TEST_CALLING_UID, null); + setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + futurity, window, pi, 0, 0, + TEST_CALLING_UID, null); assertEquals(1, mService.mAlarmStore.size()); final Alarm a = mService.mAlarmStore.remove(unused -> true).get(0); @@ -2323,18 +2325,61 @@ public class AlarmManagerServiceTest { } @Test + public void minWindowExempted() { + mockChangeEnabled(AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS, true); + final long minWindow = 73; + final long futurity = 10_000; + + setDeviceConfigLong(KEY_MIN_WINDOW, minWindow); + + final int coreUid = 2312; + doReturn(true).when(() -> UserHandle.isCore(coreUid)); + + final int allowlisted = 54239; + when(mDeviceIdleInternal.isAppOnWhitelist(UserHandle.getAppId(allowlisted))).thenReturn( + true); + + for (final int callingUid : new int[]{SYSTEM_UI_UID, coreUid, coreUid}) { + // 0 is WINDOW_EXACT and < 0 is WINDOW_HEURISTIC. + for (int window = 1; window <= minWindow; window++) { + final PendingIntent pi = getNewMockPendingIntent(); + setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + futurity, window, pi, 0, 0, + callingUid, null); + + assertEquals(1, mService.mAlarmStore.size()); + final Alarm a = mService.mAlarmStore.remove(unused -> true).get(0); + assertEquals(window, a.windowLength); + } + } + + // 0 is WINDOW_EXACT and < 0 is WINDOW_HEURISTIC. + for (int window = 1; window <= minWindow; window++) { + final PendingIntent pi = getNewMockPendingIntent(); + setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + futurity, window, pi, 0, 0, + TEST_CALLING_UID, null); + + assertEquals(1, mService.mAlarmStore.size()); + final Alarm a = mService.mAlarmStore.remove(unused -> true).get(0); + assertEquals(minWindow, a.windowLength); + } + } + + @Test public void minWindowPriorityAlarm() { mockChangeEnabled(AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS, true); final long minWindow = 73; + final long futurity = 10_000; setDeviceConfigLong(KEY_MIN_WINDOW, minWindow); // 0 is WINDOW_EXACT and < 0 is WINDOW_HEURISTIC. for (int window = 1; window <= minWindow; window++) { - setPrioritizedAlarm(ELAPSED_REALTIME, 0, window, new IAlarmListener.Stub() { - @Override - public void doAlarm(IAlarmCompleteListener callback) throws RemoteException { - } - }); + setPrioritizedAlarm(ELAPSED_REALTIME, mNowElapsedTest + futurity, window, + new IAlarmListener.Stub() { + @Override + public void doAlarm(IAlarmCompleteListener callback) + throws RemoteException { + } + }); assertEquals(1, mService.mAlarmStore.size()); final Alarm a = mService.mAlarmStore.remove(unused -> true).get(0); assertEquals(window, a.windowLength); |