Loading services/core/java/com/android/server/AlarmManagerService.java +24 −2 Original line number Diff line number Diff line Loading @@ -210,6 +210,7 @@ class AlarmManagerService extends SystemService { IAlarmListener mTimeTickTrigger; PendingIntent mDateChangeSender; Random mRandom; PendingIntent.CancelListener mOperationCancelListener; boolean mInteractive = true; long mNonInteractiveStartTime; long mNonInteractiveTime; Loading Loading @@ -1497,6 +1498,7 @@ class AlarmManagerService extends SystemService { synchronized (mLock) { mHandler = new AlarmHandler(); mOperationCancelListener = (intent) -> removeImpl(intent, null); mConstants = new Constants(mHandler); mAppWakeupHistory = new AppWakeupHistory(Constants.DEFAULT_APP_STANDBY_WINDOW); Loading Loading @@ -1748,7 +1750,9 @@ class AlarmManagerService extends SystemService { } else { maxElapsed = triggerElapsed + windowLength; } if (operation != null) { operation.registerCancelListener(mOperationCancelListener); } synchronized (mLock) { if (DEBUG_BATCH) { Slog.v(TAG, "set(" + operation + ") : type=" + type Loading @@ -1761,6 +1765,8 @@ class AlarmManagerService extends SystemService { "Maximum limit of concurrent alarms " + mConstants.MAX_ALARMS_PER_UID + " reached for uid: " + UserHandle.formatUid(callingUid) + ", callingPackage: " + callingPackage; mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER, operation).sendToTarget(); // STOPSHIP (b/128866264): Just to catch breakages. Remove before final release. Slog.wtf(TAG, errorMsg); throw new IllegalStateException(errorMsg); Loading @@ -1782,6 +1788,8 @@ class AlarmManagerService extends SystemService { if (ActivityManager.getService().isAppStartModeDisabled(callingUid, callingPackage)) { Slog.w(TAG, "Not setting alarm from " + callingUid + ":" + a + " -- package not allowed to start"); mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER, operation).sendToTarget(); return; } } catch (RemoteException e) { Loading Loading @@ -2136,10 +2144,11 @@ class AlarmManagerService extends SystemService { Slog.w(TAG, "remove() with no intent or listener"); return; } synchronized (mLock) { removeLocked(operation, listener); } mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER, operation).sendToTarget(); } @Override Loading Loading @@ -4179,6 +4188,7 @@ class AlarmManagerService extends SystemService { public static final int APP_STANDBY_BUCKET_CHANGED = 5; public static final int APP_STANDBY_PAROLE_CHANGED = 6; public static final int REMOVE_FOR_STOPPED = 7; public static final int UNREGISTER_CANCEL_LISTENER = 8; AlarmHandler() { super(Looper.myLooper()); Loading Loading @@ -4261,6 +4271,13 @@ class AlarmManagerService extends SystemService { } break; case UNREGISTER_CANCEL_LISTENER: final PendingIntent pi = (PendingIntent) msg.obj; if (pi != null) { pi.unregisterCancelListener(mOperationCancelListener); } break; default: // nope, just ignore it break; Loading Loading @@ -4716,6 +4733,11 @@ class AlarmManagerService extends SystemService { Intent.EXTRA_ALARM_COUNT, alarm.count), mDeliveryTracker, mHandler, null, allowWhileIdle ? mIdleOptions : null); if (alarm.repeatInterval == 0) { // Keep the listener for repeating alarms until they get cancelled mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER, alarm.operation).sendToTarget(); } } catch (PendingIntent.CanceledException e) { if (alarm.repeatInterval > 0) { // This IntentSender is no longer valid, but this Loading services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java +10 −0 Original line number Diff line number Diff line Loading @@ -1032,6 +1032,16 @@ public class AlarmManagerServiceTest { assertEquals(-1, mService.mAlarmsPerUid.get(TEST_CALLING_UID, -1)); } @Test public void alarmCountOnPendingIntentCancel() { final PendingIntent pi = getNewMockPendingIntent(); setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 123, pi); verify(pi).registerCancelListener(mService.mOperationCancelListener); assertEquals(1, mService.mAlarmsPerUid.get(TEST_CALLING_UID)); mService.mOperationCancelListener.onCancelled(pi); assertEquals(0, mService.mAlarmsPerUid.get(TEST_CALLING_UID)); } @After public void tearDown() { if (mMockingSession != null) { Loading Loading
services/core/java/com/android/server/AlarmManagerService.java +24 −2 Original line number Diff line number Diff line Loading @@ -210,6 +210,7 @@ class AlarmManagerService extends SystemService { IAlarmListener mTimeTickTrigger; PendingIntent mDateChangeSender; Random mRandom; PendingIntent.CancelListener mOperationCancelListener; boolean mInteractive = true; long mNonInteractiveStartTime; long mNonInteractiveTime; Loading Loading @@ -1497,6 +1498,7 @@ class AlarmManagerService extends SystemService { synchronized (mLock) { mHandler = new AlarmHandler(); mOperationCancelListener = (intent) -> removeImpl(intent, null); mConstants = new Constants(mHandler); mAppWakeupHistory = new AppWakeupHistory(Constants.DEFAULT_APP_STANDBY_WINDOW); Loading Loading @@ -1748,7 +1750,9 @@ class AlarmManagerService extends SystemService { } else { maxElapsed = triggerElapsed + windowLength; } if (operation != null) { operation.registerCancelListener(mOperationCancelListener); } synchronized (mLock) { if (DEBUG_BATCH) { Slog.v(TAG, "set(" + operation + ") : type=" + type Loading @@ -1761,6 +1765,8 @@ class AlarmManagerService extends SystemService { "Maximum limit of concurrent alarms " + mConstants.MAX_ALARMS_PER_UID + " reached for uid: " + UserHandle.formatUid(callingUid) + ", callingPackage: " + callingPackage; mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER, operation).sendToTarget(); // STOPSHIP (b/128866264): Just to catch breakages. Remove before final release. Slog.wtf(TAG, errorMsg); throw new IllegalStateException(errorMsg); Loading @@ -1782,6 +1788,8 @@ class AlarmManagerService extends SystemService { if (ActivityManager.getService().isAppStartModeDisabled(callingUid, callingPackage)) { Slog.w(TAG, "Not setting alarm from " + callingUid + ":" + a + " -- package not allowed to start"); mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER, operation).sendToTarget(); return; } } catch (RemoteException e) { Loading Loading @@ -2136,10 +2144,11 @@ class AlarmManagerService extends SystemService { Slog.w(TAG, "remove() with no intent or listener"); return; } synchronized (mLock) { removeLocked(operation, listener); } mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER, operation).sendToTarget(); } @Override Loading Loading @@ -4179,6 +4188,7 @@ class AlarmManagerService extends SystemService { public static final int APP_STANDBY_BUCKET_CHANGED = 5; public static final int APP_STANDBY_PAROLE_CHANGED = 6; public static final int REMOVE_FOR_STOPPED = 7; public static final int UNREGISTER_CANCEL_LISTENER = 8; AlarmHandler() { super(Looper.myLooper()); Loading Loading @@ -4261,6 +4271,13 @@ class AlarmManagerService extends SystemService { } break; case UNREGISTER_CANCEL_LISTENER: final PendingIntent pi = (PendingIntent) msg.obj; if (pi != null) { pi.unregisterCancelListener(mOperationCancelListener); } break; default: // nope, just ignore it break; Loading Loading @@ -4716,6 +4733,11 @@ class AlarmManagerService extends SystemService { Intent.EXTRA_ALARM_COUNT, alarm.count), mDeliveryTracker, mHandler, null, allowWhileIdle ? mIdleOptions : null); if (alarm.repeatInterval == 0) { // Keep the listener for repeating alarms until they get cancelled mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER, alarm.operation).sendToTarget(); } } catch (PendingIntent.CanceledException e) { if (alarm.repeatInterval > 0) { // This IntentSender is no longer valid, but this Loading
services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java +10 −0 Original line number Diff line number Diff line Loading @@ -1032,6 +1032,16 @@ public class AlarmManagerServiceTest { assertEquals(-1, mService.mAlarmsPerUid.get(TEST_CALLING_UID, -1)); } @Test public void alarmCountOnPendingIntentCancel() { final PendingIntent pi = getNewMockPendingIntent(); setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 123, pi); verify(pi).registerCancelListener(mService.mOperationCancelListener); assertEquals(1, mService.mAlarmsPerUid.get(TEST_CALLING_UID)); mService.mOperationCancelListener.onCancelled(pi); assertEquals(0, mService.mAlarmsPerUid.get(TEST_CALLING_UID)); } @After public void tearDown() { if (mMockingSession != null) { Loading