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
This commit is contained in:
Beth Thibodeau
2021-11-12 17:12:19 -05:00
parent 2ab2685cca
commit e91aa6cb7d
10 changed files with 46 additions and 41 deletions

View File

@@ -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<? extends Style> 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;
}
/**

View File

@@ -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();

View File

@@ -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()
}
/**

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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));
}

View File

@@ -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() {

View File

@@ -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();

View File

@@ -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;

View File

@@ -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) {