Merge "Exempt some callers from min-window restrictions" into sc-dev

This commit is contained in:
TreeHugger Robot
2021-06-16 20:30:44 +00:00
committed by Android (Google) Code Review
2 changed files with 59 additions and 11 deletions

View File

@@ -2006,16 +2006,12 @@ public class AlarmManagerService extends SystemService {
windowLength = INTERVAL_DAY; windowLength = INTERVAL_DAY;
} else if ((flags & FLAG_PRIORITIZE) == 0 && windowLength < minAllowedWindow) { } else if ((flags & FLAG_PRIORITIZE) == 0 && windowLength < minAllowedWindow) {
// Prioritized alarms are exempt from minimum window limits. // Prioritized alarms are exempt from minimum window limits.
if (CompatChanges.isChangeEnabled( if (!isExemptFromMinWindowRestrictions(callingUid) && CompatChanges.isChangeEnabled(
AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS, callingPackage, AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS, callingPackage,
UserHandle.getUserHandleForUid(callingUid))) { UserHandle.getUserHandleForUid(callingUid))) {
Slog.w(TAG, "Window length " + windowLength + "ms too short; expanding to " Slog.w(TAG, "Window length " + windowLength + "ms too short; expanding to "
+ minAllowedWindow + "ms."); + minAllowedWindow + "ms.");
windowLength = minAllowedWindow; 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; maxElapsed = triggerElapsed + windowLength;
@@ -2408,6 +2404,13 @@ public class AlarmManagerService extends SystemService {
return hasPermission; 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, * Returns true if the given uid does not require SCHEDULE_EXACT_ALARM to set exact,
* allow-while-idle alarms. * allow-while-idle alarms.

View File

@@ -2309,12 +2309,14 @@ public class AlarmManagerServiceTest {
public void minWindowChangeDisabled() { public void minWindowChangeDisabled() {
mockChangeEnabled(AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS, false); mockChangeEnabled(AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS, false);
final long minWindow = 73; final long minWindow = 73;
final long futurity = 10_000;
setDeviceConfigLong(KEY_MIN_WINDOW, minWindow); setDeviceConfigLong(KEY_MIN_WINDOW, minWindow);
// 0 is WINDOW_EXACT and < 0 is WINDOW_HEURISTIC. // 0 is WINDOW_EXACT and < 0 is WINDOW_HEURISTIC.
for (int window = 1; window <= minWindow; window++) { for (int window = 1; window <= minWindow; window++) {
final PendingIntent pi = getNewMockPendingIntent(); 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()); assertEquals(1, mService.mAlarmStore.size());
final Alarm a = mService.mAlarmStore.remove(unused -> true).get(0); final Alarm a = mService.mAlarmStore.remove(unused -> true).get(0);
@@ -2322,17 +2324,60 @@ 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 @Test
public void minWindowPriorityAlarm() { public void minWindowPriorityAlarm() {
mockChangeEnabled(AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS, true); mockChangeEnabled(AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS, true);
final long minWindow = 73; final long minWindow = 73;
final long futurity = 10_000;
setDeviceConfigLong(KEY_MIN_WINDOW, minWindow); setDeviceConfigLong(KEY_MIN_WINDOW, minWindow);
// 0 is WINDOW_EXACT and < 0 is WINDOW_HEURISTIC. // 0 is WINDOW_EXACT and < 0 is WINDOW_HEURISTIC.
for (int window = 1; window <= minWindow; window++) { 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 @Override
public void doAlarm(IAlarmCompleteListener callback) throws RemoteException { public void doAlarm(IAlarmCompleteListener callback)
throws RemoteException {
} }
}); });
assertEquals(1, mService.mAlarmStore.size()); assertEquals(1, mService.mAlarmStore.size());