Limit number of notification actions created
Fixes: 228149865 Test: manual; atest MediaDataManagerTest Change-Id: I110f103b5111edc9ed69285c3d07a779acb06dee
This commit is contained in:
@@ -611,12 +611,11 @@ public class MediaControlPanel {
|
||||
|
||||
private void bindActionButtons(MediaData data) {
|
||||
MediaButton semanticActions = data.getSemanticActions();
|
||||
ImageButton[] genericButtons = new ImageButton[]{
|
||||
mMediaViewHolder.getAction0(),
|
||||
mMediaViewHolder.getAction1(),
|
||||
mMediaViewHolder.getAction2(),
|
||||
mMediaViewHolder.getAction3(),
|
||||
mMediaViewHolder.getAction4()};
|
||||
|
||||
List<ImageButton> genericButtons = new ArrayList<>();
|
||||
for (int id : MediaViewHolder.Companion.getGenericButtonIds()) {
|
||||
genericButtons.add(mMediaViewHolder.getAction(id));
|
||||
}
|
||||
|
||||
ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
|
||||
ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
|
||||
@@ -643,19 +642,19 @@ public class MediaControlPanel {
|
||||
List<Integer> actionsWhenCollapsed = data.getActionsToShowInCompact();
|
||||
List<MediaAction> actions = data.getActions();
|
||||
int i = 0;
|
||||
for (; i < actions.size(); i++) {
|
||||
for (; i < actions.size() && i < genericButtons.size(); i++) {
|
||||
boolean showInCompact = actionsWhenCollapsed.contains(i);
|
||||
setGenericButton(
|
||||
genericButtons[i],
|
||||
genericButtons.get(i),
|
||||
actions.get(i),
|
||||
collapsedSet,
|
||||
expandedSet,
|
||||
showInCompact);
|
||||
}
|
||||
for (; i < 5; i++) {
|
||||
for (; i < genericButtons.size(); i++) {
|
||||
// Hide any unused buttons
|
||||
setGenericButton(
|
||||
genericButtons[i],
|
||||
genericButtons.get(i),
|
||||
/* mediaAction= */ null,
|
||||
collapsedSet,
|
||||
expandedSet,
|
||||
|
||||
@@ -161,6 +161,10 @@ class MediaDataManager(
|
||||
@JvmField
|
||||
val MAX_COMPACT_ACTIONS = 3
|
||||
|
||||
// Maximum number of actions allowed in expanded view
|
||||
@JvmField
|
||||
val MAX_NOTIFICATION_ACTIONS = MediaViewHolder.genericButtonIds.size
|
||||
|
||||
/** Maximum number of [PlaybackState.CustomAction] buttons supported */
|
||||
@JvmField
|
||||
val MAX_CUSTOM_ACTIONS = 4
|
||||
@@ -727,6 +731,11 @@ class MediaDataManager(
|
||||
|
||||
if (actions != null) {
|
||||
for ((index, action) in actions.withIndex()) {
|
||||
if (index == MAX_NOTIFICATION_ACTIONS) {
|
||||
Log.w(TAG, "Too many notification actions for ${sbn.key}," +
|
||||
" limiting to first $MAX_NOTIFICATION_ACTIONS")
|
||||
break
|
||||
}
|
||||
if (action.getIcon() == null) {
|
||||
if (DEBUG) Log.i(TAG, "No icon for action $index ${action.title}")
|
||||
actionsToShowCollapsed.remove(index)
|
||||
|
||||
@@ -178,5 +178,14 @@ class MediaViewHolder constructor(itemView: View) {
|
||||
R.id.dismiss,
|
||||
R.id.settings
|
||||
)
|
||||
|
||||
// Buttons used for notification-based actions
|
||||
val genericButtonIds = setOf(
|
||||
R.id.action0,
|
||||
R.id.action1,
|
||||
R.id.action2,
|
||||
R.id.action3,
|
||||
R.id.action4
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.android.systemui.media
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.Notification.MediaStyle
|
||||
import android.app.PendingIntent
|
||||
import android.app.smartspace.SmartspaceAction
|
||||
@@ -620,6 +621,36 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
MediaDataManager.MAX_COMPACT_ACTIONS)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTooManyNotificationActions_isTruncated() {
|
||||
// GIVEN a notification where too many notification actions are added
|
||||
val action = Notification.Action(R.drawable.ic_android, "action", null)
|
||||
val notif = SbnBuilder().run {
|
||||
setPkg(PACKAGE_NAME)
|
||||
modifyNotification(context).also {
|
||||
it.setSmallIcon(android.R.drawable.ic_media_pause)
|
||||
it.setStyle(MediaStyle().apply {
|
||||
setMediaSession(session.sessionToken)
|
||||
})
|
||||
for (i in 0..MediaDataManager.MAX_NOTIFICATION_ACTIONS) {
|
||||
it.addAction(action)
|
||||
}
|
||||
}
|
||||
build()
|
||||
}
|
||||
|
||||
// WHEN the notification is loaded
|
||||
mediaDataManager.onNotificationAdded(KEY, notif)
|
||||
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
|
||||
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
||||
|
||||
// THEN only the first MAX_NOTIFICATION_ACTIONS are actually included
|
||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
|
||||
eq(0), eq(false))
|
||||
assertThat(mediaDataCaptor.value.actions.size).isEqualTo(
|
||||
MediaDataManager.MAX_NOTIFICATION_ACTIONS)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPlaybackActions_noState_usesNotification() {
|
||||
val desc = "Notification Action"
|
||||
|
||||
Reference in New Issue
Block a user