Merge "Limit number of notification actions created" into tm-dev

This commit is contained in:
TreeHugger Robot
2022-04-09 02:11:33 +00:00
committed by Android (Google) Code Review
4 changed files with 58 additions and 10 deletions

View File

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

View File

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

View File

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

View File

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