Make MediaSessionConnector depend only on ExoPlayer

This is possible to do without passing the player instance to
custom action providers through their constructors, given we
no longer have a MuteActionProvider. Passing the player through
the constructors generalizes better to such cases, however, so
feels like the right thing to do.

It's also possible to use generics and keep passing the player
instance via the CustomActionProvider methods, but this adds
some unnecessary complexity.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=162333043
This commit is contained in:
olly 2017-07-18 03:29:29 -07:00 committed by Oliver Woodman
parent 1d046d5da8
commit 4fd516e35b
2 changed files with 30 additions and 27 deletions

View File

@ -46,7 +46,7 @@ import java.util.Map;
/** /**
* Mediates between a {@link MediaSessionCompat} and an {@link SimpleExoPlayer} instance set with * Mediates between a {@link MediaSessionCompat} and an {@link SimpleExoPlayer} instance set with
* {@link #setPlayer(SimpleExoPlayer)}. * {@link #setPlayer(SimpleExoPlayer, CustomActionProvider...)}.
* <p> * <p>
* By default the {@code MediaSessionConnector} listens for {@link #DEFAULT_PLAYBACK_ACTIONS} sent * By default the {@code MediaSessionConnector} listens for {@link #DEFAULT_PLAYBACK_ACTIONS} sent
* by a media controller and realizes these actions by calling appropriate ExoPlayer methods. * by a media controller and realizes these actions by calling appropriate ExoPlayer methods.
@ -216,21 +216,19 @@ public final class MediaSessionConnector {
/** /**
* Called when a custom action provided by this provider is sent to the media session. * Called when a custom action provided by this provider is sent to the media session.
* *
* @param player The player for which to process the custom action.
* @param action The name of the action which was sent by a media controller. * @param action The name of the action which was sent by a media controller.
* @param extras Optional extras sent by a media controller. * @param extras Optional extras sent by a media controller.
*/ */
void onCustomAction(SimpleExoPlayer player, String action, Bundle extras); void onCustomAction(String action, Bundle extras);
/** /**
* Returns a {@link PlaybackStateCompat.CustomAction} which will be published to the * Returns a {@link PlaybackStateCompat.CustomAction} which will be published to the
* media session by the connector or {@code null} if this action should not be published at the * media session by the connector or {@code null} if this action should not be published at the
* given player state. * given player state.
* *
* @param player The player for which to provide actions.
* @return The custom action to be included in the session playback state or {@code null}. * @return The custom action to be included in the session playback state or {@code null}.
*/ */
PlaybackStateCompat.CustomAction getCustomAction(SimpleExoPlayer player); PlaybackStateCompat.CustomAction getCustomAction();
} }
/** /**
@ -253,9 +251,9 @@ public final class MediaSessionConnector {
private final boolean doMaintainMetadata; private final boolean doMaintainMetadata;
private final ExoPlayerEventListener exoPlayerEventListener; private final ExoPlayerEventListener exoPlayerEventListener;
private final MediaSessionCallback mediaSessionCallback; private final MediaSessionCallback mediaSessionCallback;
private final CustomActionProvider[] customActionProviders;
private SimpleExoPlayer player; private SimpleExoPlayer player;
private CustomActionProvider[] customActionProviders;
private int currentWindowIndex; private int currentWindowIndex;
private long playbackActions; private long playbackActions;
private long fastForwardIncrementMs; private long fastForwardIncrementMs;
@ -283,9 +281,6 @@ public final class MediaSessionConnector {
/** /**
* Creates a {@code MediaSessionConnector} with {@link CustomActionProvider}s. * Creates a {@code MediaSessionConnector} with {@link CustomActionProvider}s.
* <p> * <p>
* The order in which the {@link CustomActionProvider}s are passed to the constructor determines
* the order of the actions published with the playback state of the session.
* <p>
* If you choose to pass {@code false} for {@code doMaintainMetadata} you need to maintain the * If you choose to pass {@code false} for {@code doMaintainMetadata} you need to maintain the
* metadata of the media session yourself (provide at least the duration to allow clients to show * metadata of the media session yourself (provide at least the duration to allow clients to show
* a progress bar). * a progress bar).
@ -296,17 +291,12 @@ public final class MediaSessionConnector {
* @param mediaSession The {@link MediaSessionCompat} to connect to. * @param mediaSession The {@link MediaSessionCompat} to connect to.
* @param doMaintainMetadata Sets whether the connector should maintain the metadata of the * @param doMaintainMetadata Sets whether the connector should maintain the metadata of the
* session. * session.
* @param customActionProviders {@link CustomActionProvider}s to publish and handle custom
* actions.
*/ */
public MediaSessionConnector(MediaSessionCompat mediaSession, boolean doMaintainMetadata, public MediaSessionConnector(MediaSessionCompat mediaSession, boolean doMaintainMetadata) {
CustomActionProvider... customActionProviders) {
this.mediaSession = mediaSession; this.mediaSession = mediaSession;
this.handler = new Handler(Looper.myLooper() != null ? Looper.myLooper() this.handler = new Handler(Looper.myLooper() != null ? Looper.myLooper()
: Looper.getMainLooper()); : Looper.getMainLooper());
this.doMaintainMetadata = doMaintainMetadata; this.doMaintainMetadata = doMaintainMetadata;
this.customActionProviders = customActionProviders != null ? customActionProviders
: new CustomActionProvider[0];
mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS
| MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mediaController = mediaSession.getController(); mediaController = mediaSession.getController();
@ -323,15 +313,22 @@ public final class MediaSessionConnector {
* <p> * <p>
* The media session callback is set if the {@code player} is not {@code null} and the callback is * The media session callback is set if the {@code player} is not {@code null} and the callback is
* removed if the {@code player} is {@code null}. * removed if the {@code player} is {@code null}.
* <p>
* The order in which any {@link CustomActionProvider}s are passed determines the order of the
* actions published with the playback state of the session.
* *
* @param player The player to be connected to the {@code MediaSession}. * @param player The player to be connected to the {@code MediaSession}.
* @param customActionProviders Optional {@link CustomActionProvider}s to publish and handle
* custom actions.
*/ */
public void setPlayer(SimpleExoPlayer player) { public void setPlayer(SimpleExoPlayer player, CustomActionProvider... customActionProviders) {
if (this.player != null) { if (this.player != null) {
this.player.removeListener(exoPlayerEventListener); this.player.removeListener(exoPlayerEventListener);
mediaSession.setCallback(null); mediaSession.setCallback(null);
} }
this.player = player; this.player = player;
this.customActionProviders = (player != null && customActionProviders != null)
? customActionProviders : new CustomActionProvider[0];
if (player != null) { if (player != null) {
mediaSession.setCallback(mediaSessionCallback, handler); mediaSession.setCallback(mediaSessionCallback, handler);
player.addListener(exoPlayerEventListener); player.addListener(exoPlayerEventListener);
@ -472,8 +469,7 @@ public final class MediaSessionConnector {
Map<String, CustomActionProvider> currentActions = new HashMap<>(); Map<String, CustomActionProvider> currentActions = new HashMap<>();
for (CustomActionProvider customActionProvider : customActionProviders) { for (CustomActionProvider customActionProvider : customActionProviders) {
PlaybackStateCompat.CustomAction customAction = customActionProvider PlaybackStateCompat.CustomAction customAction = customActionProvider.getCustomAction();
.getCustomAction(player);
if (customAction != null) { if (customAction != null) {
currentActions.put(customAction.getAction(), customActionProvider); currentActions.put(customAction.getAction(), customActionProvider);
builder.addCustomAction(customAction); builder.addCustomAction(customAction);
@ -735,7 +731,7 @@ public final class MediaSessionConnector {
public void onCustomAction(@NonNull String action, @Nullable Bundle extras) { public void onCustomAction(@NonNull String action, @Nullable Bundle extras) {
Map<String, CustomActionProvider> actionMap = customActionMap; Map<String, CustomActionProvider> actionMap = customActionMap;
if (actionMap.containsKey(action)) { if (actionMap.containsKey(action)) {
actionMap.get(action).onCustomAction(player, action, extras); actionMap.get(action).onCustomAction(action, extras);
updateMediaSessionPlaybackState(); updateMediaSessionPlaybackState();
} }
} }

View File

@ -19,17 +19,21 @@ import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.media.session.PlaybackStateCompat; import android.support.v4.media.session.PlaybackStateCompat;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.util.RepeatModeUtil; import com.google.android.exoplayer2.util.RepeatModeUtil;
/** /**
* Provides a custom action for toggling repeat actions. * Provides a custom action for toggling repeat modes.
*/ */
public final class RepeatModeActionProvider implements MediaSessionConnector.CustomActionProvider { public final class RepeatModeActionProvider implements MediaSessionConnector.CustomActionProvider {
private static final String ACTION_REPEAT_MODE = "ACTION_EXO_REPEAT_MODE"; private static final String ACTION_REPEAT_MODE = "ACTION_EXO_REPEAT_MODE";
@RepeatModeUtil.RepeatToggleModes
private static final int DEFAULT_REPEAT_MODES = RepeatModeUtil.REPEAT_TOGGLE_MODE_ONE
| RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL;
private final @RepeatModeUtil.RepeatToggleModes int repeatToggleModes; private final ExoPlayer player;
@RepeatModeUtil.RepeatToggleModes
private final int repeatToggleModes;
private final CharSequence repeatAllDescription; private final CharSequence repeatAllDescription;
private final CharSequence repeatOneDescription; private final CharSequence repeatOneDescription;
private final CharSequence repeatOffDescription; private final CharSequence repeatOffDescription;
@ -41,19 +45,22 @@ public final class RepeatModeActionProvider implements MediaSessionConnector.Cus
* {@code RepeatModeUtil#REPEAT_TOGGLE_MODE_ONE | RepeatModeUtil#REPEAT_TOGGLE_MODE_ALL}. * {@code RepeatModeUtil#REPEAT_TOGGLE_MODE_ONE | RepeatModeUtil#REPEAT_TOGGLE_MODE_ALL}.
* *
* @param context The context. * @param context The context.
* @param player The player on which to toggle the repeat mode.
*/ */
public RepeatModeActionProvider(Context context) { public RepeatModeActionProvider(Context context, ExoPlayer player) {
this(context, RepeatModeUtil.REPEAT_TOGGLE_MODE_ONE | RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL); this(context, player, DEFAULT_REPEAT_MODES);
} }
/** /**
* Creates a new {@link RepeatModeActionProvider} for the given repeat toggle modes. * Creates a new {@link RepeatModeActionProvider} for the given repeat toggle modes.
* *
* @param context The context. * @param context The context.
* @param player The player on which to toggle the repeat mode.
* @param repeatToggleModes The toggle modes to enable. * @param repeatToggleModes The toggle modes to enable.
*/ */
public RepeatModeActionProvider(Context context, public RepeatModeActionProvider(Context context, ExoPlayer player,
@RepeatModeUtil.RepeatToggleModes int repeatToggleModes) { @RepeatModeUtil.RepeatToggleModes int repeatToggleModes) {
this.player = player;
this.repeatToggleModes = repeatToggleModes; this.repeatToggleModes = repeatToggleModes;
repeatAllDescription = context.getString(R.string.exo_media_action_repeat_all_description); repeatAllDescription = context.getString(R.string.exo_media_action_repeat_all_description);
repeatOneDescription = context.getString(R.string.exo_media_action_repeat_one_description); repeatOneDescription = context.getString(R.string.exo_media_action_repeat_one_description);
@ -61,7 +68,7 @@ public final class RepeatModeActionProvider implements MediaSessionConnector.Cus
} }
@Override @Override
public void onCustomAction(SimpleExoPlayer player, String action, Bundle extras) { public void onCustomAction(String action, Bundle extras) {
int mode = player.getRepeatMode(); int mode = player.getRepeatMode();
int proposedMode = RepeatModeUtil.getNextRepeatMode(mode, repeatToggleModes); int proposedMode = RepeatModeUtil.getNextRepeatMode(mode, repeatToggleModes);
if (mode != proposedMode) { if (mode != proposedMode) {
@ -70,7 +77,7 @@ public final class RepeatModeActionProvider implements MediaSessionConnector.Cus
} }
@Override @Override
public PlaybackStateCompat.CustomAction getCustomAction(SimpleExoPlayer player) { public PlaybackStateCompat.CustomAction getCustomAction() {
CharSequence actionLabel; CharSequence actionLabel;
int iconResourceId; int iconResourceId;
switch (player.getRepeatMode()) { switch (player.getRepeatMode()) {