diff options
| author | 2024-02-01 22:32:28 +0000 | |
|---|---|---|
| committer | 2024-02-01 22:32:28 +0000 | |
| commit | b400b0e68ec3fd5f355b5425fe5022fcc3959b9f (patch) | |
| tree | 1aae3814cecb396d7c1dd461f6846102b68b8c70 | |
| parent | 2728622cc13f5923e9bb8c546c45d67c62c43b2e (diff) | |
| parent | c11765ac782525cb803ac13886bd61dcdf71e33b (diff) | |
Merge "notification: fix Alarm & PendingIntent leak" into main am: 11a67a20cc am: c11765ac78
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2928072
Change-Id: I38d9b5851645695d077da27c53bb3aee984d3636
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
2 files changed, 32 insertions, 24 deletions
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 1c9bbab3969e..31c1d7653926 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -8844,19 +8844,26 @@ public class NotificationManagerService extends SystemService { } } + private PendingIntent getNotificationTimeoutPendingIntent(NotificationRecord record, + int flags) { + flags |= PendingIntent.FLAG_IMMUTABLE; + return PendingIntent.getBroadcast(getContext(), + REQUEST_CODE_TIMEOUT, + new Intent(ACTION_NOTIFICATION_TIMEOUT) + .setPackage(PackageManagerService.PLATFORM_PACKAGE_NAME) + .setData(new Uri.Builder().scheme(SCHEME_TIMEOUT) + .appendPath(record.getKey()).build()) + .addFlags(Intent.FLAG_RECEIVER_FOREGROUND) + .putExtra(EXTRA_KEY, record.getKey()), + flags); + } + @VisibleForTesting @GuardedBy("mNotificationLock") void scheduleTimeoutLocked(NotificationRecord record) { if (record.getNotification().getTimeoutAfter() > 0) { - final PendingIntent pi = PendingIntent.getBroadcast(getContext(), - REQUEST_CODE_TIMEOUT, - new Intent(ACTION_NOTIFICATION_TIMEOUT) - .setPackage(PackageManagerService.PLATFORM_PACKAGE_NAME) - .setData(new Uri.Builder().scheme(SCHEME_TIMEOUT) - .appendPath(record.getKey()).build()) - .addFlags(Intent.FLAG_RECEIVER_FOREGROUND) - .putExtra(EXTRA_KEY, record.getKey()), - PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + final PendingIntent pi = getNotificationTimeoutPendingIntent( + record, PendingIntent.FLAG_UPDATE_CURRENT); mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + record.getNotification().getTimeoutAfter(), pi); } @@ -8864,6 +8871,16 @@ public class NotificationManagerService extends SystemService { @VisibleForTesting @GuardedBy("mNotificationLock") + void cancelScheduledTimeoutLocked(NotificationRecord record) { + final PendingIntent pi = getNotificationTimeoutPendingIntent( + record, PendingIntent.FLAG_CANCEL_CURRENT); + if (pi != null) { + mAlarmManager.cancel(pi); + } + } + + @VisibleForTesting + @GuardedBy("mNotificationLock") /** * Determine whether this notification should attempt to make noise, vibrate, or flash the LED * @return buzzBeepBlink - bitfield (buzz ? 1 : 0) | (beep ? 2 : 0) | (blink ? 4 : 0) @@ -9894,21 +9911,7 @@ public class NotificationManagerService extends SystemService { int rank, int count, boolean wasPosted, String listenerName, @ElapsedRealtimeLong long cancellationElapsedTimeMs) { final String canceledKey = r.getKey(); - - // Get pending intent used to create alarm, use FLAG_NO_CREATE if PendingIntent - // does not already exist, then null will be returned. - final PendingIntent pi = PendingIntent.getBroadcast(getContext(), - REQUEST_CODE_TIMEOUT, - new Intent(ACTION_NOTIFICATION_TIMEOUT) - .setData(new Uri.Builder().scheme(SCHEME_TIMEOUT) - .appendPath(r.getKey()).build()) - .addFlags(Intent.FLAG_RECEIVER_FOREGROUND), - PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_IMMUTABLE); - - // Cancel alarm corresponding to pi. - if (pi != null) { - mAlarmManager.cancel(pi); - } + cancelScheduledTimeoutLocked(r); // Record caller. recordCallerLocked(r); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index ef0ac33bcfc5..df314c241179 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -1254,6 +1254,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { verify(mAlarmManager).setExactAndAllowWhileIdle(anyInt(), anyLong(), captor.capture()); assertEquals(PackageManagerService.PLATFORM_PACKAGE_NAME, captor.getValue().getIntent().getPackage()); + + mService.cancelScheduledTimeoutLocked(r); + verify(mAlarmManager).cancel(captor.capture()); + assertEquals(PackageManagerService.PLATFORM_PACKAGE_NAME, + captor.getValue().getIntent().getPackage()); } @Test |