Loading apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +8 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -2408,6 +2404,13 @@ public class AlarmManagerService extends SystemService { return hasPermission; } /** * 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. Loading services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +51 −6 Original line number Diff line number Diff line Loading @@ -2309,12 +2309,42 @@ 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); assertEquals(window, a.windowLength); } } @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); Loading @@ -2322,17 +2352,32 @@ public class AlarmManagerServiceTest { } } // 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() { setPrioritizedAlarm(ELAPSED_REALTIME, mNowElapsedTest + futurity, window, new IAlarmListener.Stub() { @Override public void doAlarm(IAlarmCompleteListener callback) throws RemoteException { public void doAlarm(IAlarmCompleteListener callback) throws RemoteException { } }); assertEquals(1, mService.mAlarmStore.size()); Loading Loading
apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +8 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -2408,6 +2404,13 @@ public class AlarmManagerService extends SystemService { return hasPermission; } /** * 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. Loading
services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +51 −6 Original line number Diff line number Diff line Loading @@ -2309,12 +2309,42 @@ 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); assertEquals(window, a.windowLength); } } @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); Loading @@ -2322,17 +2352,32 @@ public class AlarmManagerServiceTest { } } // 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() { setPrioritizedAlarm(ELAPSED_REALTIME, mNowElapsedTest + futurity, window, new IAlarmListener.Stub() { @Override public void doAlarm(IAlarmCompleteListener callback) throws RemoteException { public void doAlarm(IAlarmCompleteListener callback) throws RemoteException { } }); assertEquals(1, mService.mAlarmStore.size()); Loading