Loading apex/jobscheduler/framework/java/android/app/AlarmManager.java +11 −0 Original line number Diff line number Diff line Loading @@ -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. Loading apex/jobscheduler/framework/java/android/app/IAlarmManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +21 −3 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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", Loading @@ -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 Loading Loading @@ -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--) { Loading core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -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); services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +58 −4 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -328,7 +329,7 @@ public class AlarmManagerServiceTest { @Override int getCallingUid() { return TEST_CALLING_UID; return mTestCallingUid; } @Override Loading Loading @@ -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)); } Loading Loading @@ -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); Loading Loading @@ -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); Loading @@ -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); Loading Loading
apex/jobscheduler/framework/java/android/app/AlarmManager.java +11 −0 Original line number Diff line number Diff line Loading @@ -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. Loading
apex/jobscheduler/framework/java/android/app/IAlarmManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +21 −3 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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", Loading @@ -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 Loading Loading @@ -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--) { Loading
core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -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);
services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +58 −4 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -328,7 +329,7 @@ public class AlarmManagerServiceTest { @Override int getCallingUid() { return TEST_CALLING_UID; return mTestCallingUid; } @Override Loading Loading @@ -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)); } Loading Loading @@ -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); Loading Loading @@ -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); Loading @@ -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); Loading