From cff8ac82e1b2bf0a8371e1af543d5bf4c43d414d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Hern=C3=A1ndez?= Date: Tue, 31 Jan 2023 18:37:16 +0100 Subject: [PATCH] Fix notifications containing null entries in actions Before this change, posting such a notification would throw an exception much later, in calculateGrantableUris(). Test: atest NotificationManagerServiceTest Bug: 214494609 Change-Id: Ic99413228408ec19fcd9bcf8465e3840a8d350f9 --- .../NotificationManagerService.java | 25 ++++++++++++ .../NotificationManagerServiceTest.java | 40 +++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 6bc85824763cc..b5fceb50f1dcc 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -6687,6 +6687,31 @@ public class NotificationManagerService extends SystemService { } } + // Ensure all actions are present + if (notification.actions != null) { + boolean hasNullActions = false; + int nActions = notification.actions.length; + for (int i = 0; i < nActions; i++) { + if (notification.actions[i] == null) { + hasNullActions = true; + break; + } + } + if (hasNullActions) { + ArrayList nonNullActions = new ArrayList<>(); + for (int i = 0; i < nActions; i++) { + if (notification.actions[i] != null) { + nonNullActions.add(notification.actions[i]); + } + } + if (nonNullActions.size() != 0) { + notification.actions = nonNullActions.toArray(new Notification.Action[0]); + } else { + notification.actions = null; + } + } + } + // Ensure CallStyle has all the correct actions if (notification.isStyle(Notification.CallStyle.class)) { Notification.Builder builder = 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 3f3b052931ab5..96e2a0916bb1e 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -1644,6 +1644,46 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { FLAG_FOREGROUND_SERVICE | FLAG_CAN_COLORIZE | FLAG_NO_CLEAR | FLAG_ONGOING_EVENT); } + @Test + public void testEnqueueNotificationWithTag_nullAction_fixed() throws Exception { + Notification n = new Notification.Builder(mContext, mTestNotificationChannel.getId()) + .setContentTitle("foo") + .setSmallIcon(android.R.drawable.sym_def_app_icon) + .addAction(new Notification.Action.Builder(null, "one", null).build()) + .addAction(new Notification.Action.Builder(null, "two", null).build()) + .addAction(new Notification.Action.Builder(null, "three", null).build()) + .build(); + n.actions[1] = null; + + mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0, n, 0); + waitForIdle(); + + StatusBarNotification[] posted = mBinderService.getActiveNotifications(PKG); + assertThat(posted).hasLength(1); + assertThat(posted[0].getNotification().actions).hasLength(2); + assertThat(posted[0].getNotification().actions[0].title.toString()).isEqualTo("one"); + assertThat(posted[0].getNotification().actions[1].title.toString()).isEqualTo("three"); + } + + @Test + public void testEnqueueNotificationWithTag_allNullActions_fixed() throws Exception { + Notification n = new Notification.Builder(mContext, mTestNotificationChannel.getId()) + .setContentTitle("foo") + .setSmallIcon(android.R.drawable.sym_def_app_icon) + .addAction(new Notification.Action.Builder(null, "one", null).build()) + .addAction(new Notification.Action.Builder(null, "two", null).build()) + .build(); + n.actions[0] = null; + n.actions[1] = null; + + mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0, n, 0); + waitForIdle(); + + StatusBarNotification[] posted = mBinderService.getActiveNotifications(PKG); + assertThat(posted).hasLength(1); + assertThat(posted[0].getNotification().actions).isNull(); + } + @Test public void testCancelNonexistentNotification() throws Exception { mBinderService.cancelNotificationWithTag(PKG, PKG,