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;
} 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;
@@ -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.

View File

@@ -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);
@@ -2322,19 +2324,62 @@ 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);