Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 156c837c authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Exempt some callers from min-window restrictions" into sc-dev am: 916a356f

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14988270

Change-Id: I40f3ac586976f7a7d41e8ab46a7d0b48c24323ab
parents ea0cbc44 916a356f
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -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.
+51 −6
Original line number Diff line number Diff line
@@ -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);
@@ -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());