Dispatch notification actions to the originating PlayerNotificationManager only.

Issue #4643

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=211613803
This commit is contained in:
bachinger 2018-09-05 04:37:20 -07:00 committed by Oliver Woodman
parent 782dee266d
commit 0e12eb4d92

View File

@ -145,8 +145,23 @@ public class PlayerNotificationManager {
/** Defines and handles custom actions. */
public interface CustomActionReceiver {
/** Gets the actions handled by this receiver. */
Map<String, NotificationCompat.Action> createCustomActions(Context context);
/**
* Gets the actions handled by this receiver.
*
* <p>If multiple {@link PlayerNotificationManager} instances are in use at the same time, the
* {@code instanceId} must be set as an intent extra with key {@link
* PlayerNotificationManager#EXTRA_INSTANCE_ID} to avoid sending the action to every custom
* action receiver. It's also necessary to ensure something is different about the actions. This
* may be any of the {@link Intent} attributes considered by {@link Intent#filterEquals}, or
* different request code integers when creating the {@link PendingIntent}s with {@link
* PendingIntent#getBroadcast}. The easiest approach is to use the {@code instanceId} as the
* request code.
*
* @param context The {@link Context}.
* @param instanceId The instance id of the {@link PlayerNotificationManager}.
* @return A map of custom actions.
*/
Map<String, NotificationCompat.Action> createCustomActions(Context context, int instanceId);
/**
* Gets the actions to be included in the notification given the current player state.
@ -227,6 +242,8 @@ public class PlayerNotificationManager {
public static final String ACTION_REWIND = "com.google.android.exoplayer.rewind";
/** The action which cancels the notification and stops playback. */
public static final String ACTION_STOP = "com.google.android.exoplayer.stop";
/** The extra key of the instance id of the player notification manager. */
public static final String EXTRA_INSTANCE_ID = "INSTANCE_ID";
/**
* Visibility of notification on the lock screen. One of {@link
@ -264,6 +281,8 @@ public class PlayerNotificationManager {
private static final long MAX_POSITION_FOR_SEEK_TO_PREVIOUS = 3000;
private static int instanceIdCounter;
private final Context context;
private final String channelId;
private final int notificationId;
@ -276,6 +295,7 @@ public class PlayerNotificationManager {
private final NotificationBroadcastReceiver notificationBroadcastReceiver;
private final Map<String, NotificationCompat.Action> playbackActions;
private final Map<String, NotificationCompat.Action> customActions;
private final int instanceId;
private @Nullable Player player;
private ControlDispatcher controlDispatcher;
@ -368,6 +388,7 @@ public class PlayerNotificationManager {
this.mediaDescriptionAdapter = mediaDescriptionAdapter;
this.customActionReceiver = customActionReceiver;
this.controlDispatcher = new DefaultControlDispatcher();
instanceId = instanceIdCounter++;
mainHandler = new Handler(Looper.getMainLooper());
notificationManager = NotificationManagerCompat.from(context);
playerListener = new PlayerListener();
@ -389,13 +410,13 @@ public class PlayerNotificationManager {
visibility = NotificationCompat.VISIBILITY_PUBLIC;
// initialize actions
playbackActions = createPlaybackActions(context);
playbackActions = createPlaybackActions(context, instanceId);
for (String action : playbackActions.keySet()) {
intentFilter.addAction(action);
}
customActions =
customActionReceiver != null
? customActionReceiver.createCustomActions(context)
? customActionReceiver.createCustomActions(context, instanceId)
: Collections.emptyMap();
for (String action : customActions.keySet()) {
intentFilter.addAction(action);
@ -832,8 +853,8 @@ public class PlayerNotificationManager {
* <p>This method can be safely overridden. However, the names must be of the playback actions
* {@link #ACTION_PAUSE}, {@link #ACTION_PLAY}, {@link #ACTION_FAST_FORWARD}, {@link
* #ACTION_REWIND}, {@link #ACTION_NEXT} or {@link #ACTION_PREVIOUS}, or a key contained in the
* map returned by {@link CustomActionReceiver#createCustomActions(Context)}. Otherwise the action
* name is ignored.
* map returned by {@link CustomActionReceiver#createCustomActions(Context, int)}. Otherwise the
* action name is ignored.
*/
protected List<String> getActions(Player player) {
boolean isPlayingAd = player.isPlayingAd();
@ -887,64 +908,62 @@ public class PlayerNotificationManager {
: (playActionIndex != -1 ? new int[] {playActionIndex} : new int[0]);
}
private static Map<String, NotificationCompat.Action> createPlaybackActions(Context context) {
private static Map<String, NotificationCompat.Action> createPlaybackActions(
Context context, int instanceId) {
Map<String, NotificationCompat.Action> actions = new HashMap<>();
Intent playIntent = new Intent(ACTION_PLAY).setPackage(context.getPackageName());
actions.put(
ACTION_PLAY,
new NotificationCompat.Action(
R.drawable.exo_notification_play,
context.getString(R.string.exo_controls_play_description),
PendingIntent.getBroadcast(context, 0, playIntent, PendingIntent.FLAG_CANCEL_CURRENT)));
Intent pauseIntent = new Intent(ACTION_PAUSE).setPackage(context.getPackageName());
createBroadcastIntent(ACTION_PLAY, context, instanceId)));
actions.put(
ACTION_PAUSE,
new NotificationCompat.Action(
R.drawable.exo_notification_pause,
context.getString(R.string.exo_controls_pause_description),
PendingIntent.getBroadcast(
context, 0, pauseIntent, PendingIntent.FLAG_CANCEL_CURRENT)));
Intent stopIntent = new Intent(ACTION_STOP).setPackage(context.getPackageName());
createBroadcastIntent(ACTION_PAUSE, context, instanceId)));
actions.put(
ACTION_STOP,
new NotificationCompat.Action(
R.drawable.exo_notification_stop,
context.getString(R.string.exo_controls_stop_description),
PendingIntent.getBroadcast(context, 0, stopIntent, PendingIntent.FLAG_CANCEL_CURRENT)));
Intent rewindIntent = new Intent(ACTION_REWIND).setPackage(context.getPackageName());
createBroadcastIntent(ACTION_STOP, context, instanceId)));
actions.put(
ACTION_REWIND,
new NotificationCompat.Action(
R.drawable.exo_notification_rewind,
context.getString(R.string.exo_controls_rewind_description),
PendingIntent.getBroadcast(
context, 0, rewindIntent, PendingIntent.FLAG_CANCEL_CURRENT)));
Intent fastForwardIntent = new Intent(ACTION_FAST_FORWARD).setPackage(context.getPackageName());
createBroadcastIntent(ACTION_REWIND, context, instanceId)));
actions.put(
ACTION_FAST_FORWARD,
new NotificationCompat.Action(
R.drawable.exo_notification_fastforward,
context.getString(R.string.exo_controls_fastforward_description),
PendingIntent.getBroadcast(
context, 0, fastForwardIntent, PendingIntent.FLAG_CANCEL_CURRENT)));
Intent previousIntent = new Intent(ACTION_PREVIOUS).setPackage(context.getPackageName());
createBroadcastIntent(ACTION_FAST_FORWARD, context, instanceId)));
actions.put(
ACTION_PREVIOUS,
new NotificationCompat.Action(
R.drawable.exo_notification_previous,
context.getString(R.string.exo_controls_previous_description),
PendingIntent.getBroadcast(
context, 0, previousIntent, PendingIntent.FLAG_CANCEL_CURRENT)));
Intent nextIntent = new Intent(ACTION_NEXT).setPackage(context.getPackageName());
createBroadcastIntent(ACTION_PREVIOUS, context, instanceId)));
actions.put(
ACTION_NEXT,
new NotificationCompat.Action(
R.drawable.exo_notification_next,
context.getString(R.string.exo_controls_next_description),
PendingIntent.getBroadcast(context, 0, nextIntent, PendingIntent.FLAG_CANCEL_CURRENT)));
createBroadcastIntent(ACTION_NEXT, context, instanceId)));
return actions;
}
private static PendingIntent createBroadcastIntent(
String action, Context context, int instanceId) {
Intent intent = new Intent(action).setPackage(context.getPackageName());
intent.putExtra(EXTRA_INSTANCE_ID, instanceId);
return PendingIntent.getBroadcast(
context, instanceId, intent, PendingIntent.FLAG_CANCEL_CURRENT);
}
private class PlayerListener implements Player.EventListener {
@Override
@ -999,7 +1018,9 @@ public class PlayerNotificationManager {
@Override
public void onReceive(Context context, Intent intent) {
Player player = PlayerNotificationManager.this.player;
if (player == null || !isNotificationStarted) {
if (player == null
|| !isNotificationStarted
|| intent.getIntExtra(EXTRA_INSTANCE_ID, instanceId) != instanceId) {
return;
}
String action = intent.getAction();