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

Commit f24bb33b authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Adding an API to cancel all alarms"

parents fb940011 ca41ed61
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -1256,6 +1256,17 @@ public class AlarmManager {
        wrapper.cancel();
    }

    /**
     * Remove all alarms previously set by the caller, if any.
     */
    public void cancelAll() {
        try {
            mService.removeAll(mContext.getOpPackageName());
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }

    /**
     * Set the system wall clock time.
     * Requires the permission android.permission.SET_TIME.
+1 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ interface IAlarmManager {
    boolean setTime(long millis);
    void setTimeZone(String zone);
    void remove(in PendingIntent operation, in IAlarmListener listener);
    void removeAll(String packageName);
    long getNextWakeFromIdleTime();
    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
    AlarmManager.AlarmClockInfo getNextAlarmClock(int userId);
+21 −3
Original line number Diff line number Diff line
@@ -2969,6 +2969,24 @@ public class AlarmManagerService extends SystemService {
            }
        }

        @Override
        public void removeAll(String callingPackage) {
            final int callingUid = mInjector.getCallingUid();
            if (callingUid == Process.SYSTEM_UID) {
                Slog.wtfStack(TAG, "Attempt to remove all alarms from the system uid package: "
                        + callingPackage);
                return;
            }
            if (callingUid != mPackageManagerInternal.getPackageUid(callingPackage, 0,
                    UserHandle.getUserId(callingUid))) {
                throw new SecurityException("Package " + callingPackage
                        + " does not belong to the calling uid " + callingUid);
            }
            synchronized (mLock) {
                removeLocked(callingPackage, REMOVE_REASON_ALARM_CANCELLED);
            }
        }

        @Override
        public long getNextWakeFromIdleTime() {
            return getNextWakeFromIdleTimeImpl();
@@ -4081,7 +4099,7 @@ public class AlarmManagerService extends SystemService {
    }

    @GuardedBy("mLock")
    void removeLocked(final String packageName) {
    void removeLocked(final String packageName, int reason) {
        if (packageName == null) {
            if (localLOGV) {
                Slog.w(TAG, "requested remove() of null packageName",
@@ -4089,7 +4107,7 @@ public class AlarmManagerService extends SystemService {
            }
            return;
        }
        removeAlarmsInternalLocked(a -> a.matches(packageName), REMOVE_REASON_UNDEFINED);
        removeAlarmsInternalLocked(a -> a.matches(packageName), reason);
    }

    // Only called for ephemeral apps
@@ -5132,7 +5150,7 @@ public class AlarmManagerService extends SystemService {
                            removeLocked(uid, REMOVE_REASON_UNDEFINED);
                        } else {
                            // external-applications-unavailable case
                            removeLocked(pkg);
                            removeLocked(pkg, REMOVE_REASON_UNDEFINED);
                        }
                        mPriorities.remove(pkg);
                        for (int i = mBroadcastStats.size() - 1; i >= 0; i--) {
+1 −0
Original line number Diff line number Diff line
@@ -4596,6 +4596,7 @@ package android.app {
    method public boolean canScheduleExactAlarms();
    method public void cancel(android.app.PendingIntent);
    method public void cancel(android.app.AlarmManager.OnAlarmListener);
    method public void cancelAll();
    method public android.app.AlarmManager.AlarmClockInfo getNextAlarmClock();
    method public void set(int, long, android.app.PendingIntent);
    method public void set(int, long, String, android.app.AlarmManager.OnAlarmListener, android.os.Handler);
+58 −4
Original line number Diff line number Diff line
@@ -254,6 +254,7 @@ public class AlarmManagerServiceTest {
    private Injector mInjector;
    private volatile long mNowElapsedTest;
    private volatile long mNowRtcTest;
    private volatile int mTestCallingUid = TEST_CALLING_UID;
    @GuardedBy("mTestTimer")
    private TestTimer mTestTimer = new TestTimer();

@@ -328,7 +329,7 @@ public class AlarmManagerServiceTest {

        @Override
        int getCallingUid() {
            return TEST_CALLING_UID;
            return mTestCallingUid;
        }

        @Override
@@ -1395,7 +1396,7 @@ public class AlarmManagerServiceTest {
            setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 10, getNewMockPendingIntent());
        }
        assertEquals(numAlarms, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
        mService.removeLocked(TEST_CALLING_PACKAGE);
        mService.removeLocked(TEST_CALLING_PACKAGE, REMOVE_REASON_UNDEFINED);
        assertEquals(0, mService.mAlarmsPerUid.get(TEST_CALLING_UID, 0));
    }

@@ -2682,6 +2683,59 @@ public class AlarmManagerServiceTest {
                eq(EXACT_ALLOW_REASON_ALLOW_LIST));
    }

    @Test
    public void removeAllBinderCall() throws RemoteException {
        for (int i = 0; i < 10; i++) {
            setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 1, getNewMockPendingIntent());
        }

        final String otherUidPackage1 = "other.uid.package1";
        final String otherUidPackage2 = "other.uid.package2";
        final int otherUid = 1243;

        registerAppIds(
                new String[]{TEST_CALLING_PACKAGE, otherUidPackage1, otherUidPackage2},
                new Integer[]{TEST_CALLING_UID, otherUid, otherUid}
        );

        for (int i = 0; i < 9; i++) {
            setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 11, 0,
                    getNewMockPendingIntent(otherUid, otherUidPackage1), 0, 0, otherUid,
                    otherUidPackage1, null);
        }

        for (int i = 0; i < 8; i++) {
            setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 20, 0,
                    getNewMockPendingIntent(otherUid, otherUidPackage2), 0, 0, otherUid,
                    otherUidPackage2, null);
        }

        assertEquals(27, mService.mAlarmStore.size());

        try {
            mBinder.removeAll(otherUidPackage1);
            fail("removeAll() for wrong package did not throw SecurityException");
        } catch (SecurityException se) {
            // Expected
        }

        try {
            mBinder.removeAll(otherUidPackage2);
            fail("removeAll() for wrong package did not throw SecurityException");
        } catch (SecurityException se) {
            // Expected
        }

        mBinder.removeAll(TEST_CALLING_PACKAGE);
        assertEquals(17, mService.mAlarmStore.size());
        assertEquals(0, mService.mAlarmStore.getCount(a -> a.matches(TEST_CALLING_PACKAGE)));

        mTestCallingUid = otherUid;
        mBinder.removeAll(otherUidPackage1);
        assertEquals(0, mService.mAlarmStore.getCount(a -> a.matches(otherUidPackage1)));
        assertEquals(8, mService.mAlarmStore.getCount(a -> a.matches(otherUidPackage2)));
    }

    @Test
    public void minWindowChangeEnabled() {
        mockChangeEnabled(AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS, true);
@@ -3577,7 +3631,7 @@ public class AlarmManagerServiceTest {
                getNewMockPendingIntent()), standbyQuota + temporaryQuota, mAppStandbyWindow);

        // refresh the state.
        mService.removeLocked(TEST_CALLING_PACKAGE);
        mService.removeLocked(TEST_CALLING_PACKAGE, REMOVE_REASON_UNDEFINED);
        mService.mAppWakeupHistory.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER);
        mService.mTemporaryQuotaReserve.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER);

@@ -3586,7 +3640,7 @@ public class AlarmManagerServiceTest {
                getNewMockPendingIntent()), standbyQuota + temporaryQuota, mAppStandbyWindow);

        // refresh the state.
        mService.removeLocked(TEST_CALLING_PACKAGE);
        mService.removeLocked(TEST_CALLING_PACKAGE, REMOVE_REASON_UNDEFINED);
        mService.mAppWakeupHistory.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER);
        mService.mTemporaryQuotaReserve.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER);