From e91aa6cb7d70e095c59f9bbd96efe42efbb7e243 Mon Sep 17 00:00:00 2001 From: Beth Thibodeau Date: Fri, 12 Nov 2021 17:12:19 -0500 Subject: [PATCH] Check media session token type When checking whether a notification has a media session, make sure that the value in the extra is the correct type. In addition, moves this check inside of Notification#isMediaNotification for consistency - existing usages either already checked both or will not be impacted, given that valid MediaStyle notifications are now shown in the media carousel instead of with other notifications in the shade. Fixes: 205570941 Test: atest Test: manual, repro case in bug Change-Id: I5d0134d2ce81e9e6a2ed16748f84252bf765a1c9 --- core/java/android/app/Notification.java | 26 +++++++------------ .../src/android/app/NotificationTest.java | 24 +++++++++++++++++ .../systemui/media/MediaDataManager.kt | 10 +------ .../media/dialog/MediaOutputController.java | 2 +- .../statusbar/NotificationMediaManager.java | 3 ++- .../provider/HighPriorityProvider.java | 2 +- .../row/ExpandableNotificationRow.java | 5 +--- .../dialog/MediaOutputControllerTest.java | 6 ++--- .../server/notification/BadgeExtractor.java | 7 ++--- .../notification/NotificationComparator.java | 2 +- 10 files changed, 46 insertions(+), 41 deletions(-) diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 61b1abe25ca29..9605cbdb48c6e 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -6793,7 +6793,7 @@ public class Notification implements Parcelable // We show these sorts of notifications immediately in the absence of // any explicit app declaration - if (isMediaNotification() || hasMediaSession() + if (isMediaNotification() || CATEGORY_CALL.equals(category) || CATEGORY_NAVIGATION.equals(category) || (actions != null && actions.length > 0)) { @@ -6812,14 +6812,6 @@ public class Notification implements Parcelable return FOREGROUND_SERVICE_DEFERRED == mFgsDeferBehavior; } - /** - * @return whether this notification has a media session attached - * @hide - */ - public boolean hasMediaSession() { - return extras.getParcelable(Notification.EXTRA_MEDIA_SESSION) != null; - } - /** * @return the style class of this notification * @hide @@ -6863,18 +6855,20 @@ public class Notification implements Parcelable } /** - * @return true if this is a media notification + * @return true if this is a media style notification with a media session * * @hide */ public boolean isMediaNotification() { Class style = getNotificationStyle(); - if (MediaStyle.class.equals(style)) { - return true; - } else if (DecoratedMediaCustomViewStyle.class.equals(style)) { - return true; - } - return false; + boolean isMediaStyle = (MediaStyle.class.equals(style) + || DecoratedMediaCustomViewStyle.class.equals(style)); + + boolean hasMediaSession = (extras.getParcelable(Notification.EXTRA_MEDIA_SESSION) != null + && extras.getParcelable(Notification.EXTRA_MEDIA_SESSION) + instanceof MediaSession.Token); + + return isMediaStyle && hasMediaSession; } /** diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java index 34c1763b32869..37cf514e92eae 100644 --- a/core/tests/coretests/src/android/app/NotificationTest.java +++ b/core/tests/coretests/src/android/app/NotificationTest.java @@ -43,6 +43,7 @@ import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.drawable.Icon; import android.os.Build; +import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.text.Spannable; @@ -545,6 +546,29 @@ public class NotificationTest { validateColorizedPaletteForColor(Color.BLACK); } + @Test + public void testIsMediaNotification_nullSession_returnsFalse() { + // Null media session + Notification.MediaStyle mediaStyle = new Notification.MediaStyle(); + Notification notification = new Notification.Builder(mContext, "test id") + .setStyle(mediaStyle) + .build(); + assertFalse(notification.isMediaNotification()); + } + + @Test + public void testIsMediaNotification_invalidSession_returnsFalse() { + // Extra was set manually to an invalid type + Bundle extras = new Bundle(); + extras.putParcelable(Notification.EXTRA_MEDIA_SESSION, new Intent()); + Notification.MediaStyle mediaStyle = new Notification.MediaStyle(); + Notification notification = new Notification.Builder(mContext, "test id") + .setStyle(mediaStyle) + .addExtras(extras) + .build(); + assertFalse(notification.isMediaNotification()); + } + public void validateColorizedPaletteForColor(int rawColor) { Notification.Colors cDay = new Notification.Colors(); Notification.Colors cNight = new Notification.Colors(); diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt index 3631d2fa04fb5..c9b6d9c50e7a4 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt @@ -85,15 +85,7 @@ internal val EMPTY_SMARTSPACE_MEDIA_DATA = SmartspaceMediaData("INVALID", false, "INVALID", null, emptyList(), null, 0) fun isMediaNotification(sbn: StatusBarNotification): Boolean { - if (!sbn.notification.hasMediaSession()) { - return false - } - val notificationStyle = sbn.notification.notificationStyle - if (Notification.DecoratedMediaCustomViewStyle::class.java.equals(notificationStyle) || - Notification.MediaStyle::class.java.equals(notificationStyle)) { - return true - } - return false + return sbn.notification.isMediaNotification() } /** diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java index 19812697719c0..6da4d4811ac92 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java @@ -242,7 +242,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback { for (NotificationEntry entry : mNotificationEntryManager.getActiveNotificationsForCurrentUser()) { final Notification notification = entry.getSbn().getNotification(); - if (notification.hasMediaSession() + if (notification.isMediaNotification() && TextUtils.equals(entry.getSbn().getPackageName(), mPackageName)) { final Icon icon = notification.getLargeIcon(); if (icon == null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java index dcb1e4f341888..09dbea8d2404a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java @@ -468,7 +468,8 @@ public class NotificationMediaManager implements Dumpable { NotificationEntry mediaNotification = null; MediaController controller = null; for (NotificationEntry entry : allNotifications) { - if (entry.isMediaNotification()) { + Notification notif = entry.getSbn().getNotification(); + if (notif.isMediaNotification()) { final MediaSession.Token token = entry.getSbn().getNotification().extras.getParcelable( Notification.EXTRA_MEDIA_SESSION); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java index 047865845c439..e7ef2ec084b7a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java @@ -99,7 +99,7 @@ public class HighPriorityProvider { private boolean hasHighPriorityCharacteristics(NotificationEntry entry) { return !hasUserSetImportance(entry) - && (entry.getSbn().getNotification().hasMediaSession() + && (entry.getSbn().getNotification().isMediaNotification() || isPeopleNotification(entry) || isMessagingStyle(entry)); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index 1bbd45192bea8..8a3cbf83128d5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -3182,11 +3182,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return getCurrentBottomRoundness() == 0.0f && getCurrentTopRoundness() == 0.0f; } - //TODO: this logic can't depend on layout if we are recycling! public boolean isMediaRow() { - return getExpandedContentView() != null - && getExpandedContentView().findViewById( - com.android.internal.R.id.media_actions) != null; + return mEntry.getSbn().getNotification().isMediaNotification(); } public boolean isTopLevelChild() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java index f7e60caa2624b..09ec4ca0e1dfd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java @@ -469,7 +469,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { when(entry.getSbn()).thenReturn(sbn); when(sbn.getNotification()).thenReturn(notification); when(sbn.getPackageName()).thenReturn(TEST_PACKAGE_NAME); - when(notification.hasMediaSession()).thenReturn(true); + when(notification.isMediaNotification()).thenReturn(true); when(notification.getLargeIcon()).thenReturn(null); assertThat(mMediaOutputController.getNotificationIcon()).isNull(); @@ -489,7 +489,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { when(entry.getSbn()).thenReturn(sbn); when(sbn.getNotification()).thenReturn(notification); when(sbn.getPackageName()).thenReturn(TEST_PACKAGE_NAME); - when(notification.hasMediaSession()).thenReturn(true); + when(notification.isMediaNotification()).thenReturn(true); when(notification.getLargeIcon()).thenReturn(icon); assertThat(mMediaOutputController.getNotificationIcon() instanceof IconCompat).isTrue(); @@ -509,7 +509,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { when(entry.getSbn()).thenReturn(sbn); when(sbn.getNotification()).thenReturn(notification); when(sbn.getPackageName()).thenReturn(TEST_PACKAGE_NAME); - when(notification.hasMediaSession()).thenReturn(false); + when(notification.isMediaNotification()).thenReturn(false); when(notification.getLargeIcon()).thenReturn(icon); assertThat(mMediaOutputController.getNotificationIcon()).isNull(); diff --git a/services/core/java/com/android/server/notification/BadgeExtractor.java b/services/core/java/com/android/server/notification/BadgeExtractor.java index 70edfa171356e..642cbb3242296 100644 --- a/services/core/java/com/android/server/notification/BadgeExtractor.java +++ b/services/core/java/com/android/server/notification/BadgeExtractor.java @@ -69,11 +69,8 @@ public class BadgeExtractor implements NotificationSignalExtractor { if (mConfig.isMediaNotificationFilteringEnabled()) { final Notification notif = record.getNotification(); - if (notif.hasMediaSession()) { - if (notif.isStyle(Notification.DecoratedMediaCustomViewStyle.class) - || notif.isStyle(Notification.MediaStyle.class)) { - record.setShowBadge(false); - } + if (notif.isMediaNotification()) { + record.setShowBadge(false); } } return null; diff --git a/services/core/java/com/android/server/notification/NotificationComparator.java b/services/core/java/com/android/server/notification/NotificationComparator.java index 8aae6e09bd31f..583cdd599780c 100644 --- a/services/core/java/com/android/server/notification/NotificationComparator.java +++ b/services/core/java/com/android/server/notification/NotificationComparator.java @@ -179,7 +179,7 @@ public class NotificationComparator } private boolean isMediaNotification(NotificationRecord record) { - return record.getNotification().hasMediaSession(); + return record.getNotification().isMediaNotification(); } private boolean isCallCategory(NotificationRecord record) {