diff --git a/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/DefaultPlaybackController.java b/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/DefaultPlaybackController.java deleted file mode 100644 index 655fc878ba..0000000000 --- a/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/DefaultPlaybackController.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.android.exoplayer2.ext.mediasession; - -import android.os.Bundle; -import android.os.ResultReceiver; -import android.support.v4.media.session.PlaybackStateCompat; -import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.Player; - -/** - * A default implementation of {@link MediaSessionConnector.PlaybackController}. - *
- * Methods can be safely overridden by subclasses to intercept calls for given actions. - */ -public class DefaultPlaybackController implements MediaSessionConnector.PlaybackController { - - /** - * The default fast forward increment, in milliseconds. - */ - public static final int DEFAULT_FAST_FORWARD_MS = 15000; - /** - * The default rewind increment, in milliseconds. - */ - public static final int DEFAULT_REWIND_MS = 5000; - - private static final long BASE_ACTIONS = PlaybackStateCompat.ACTION_PLAY_PAUSE - | PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PAUSE - | PlaybackStateCompat.ACTION_STOP | PlaybackStateCompat.ACTION_SET_SHUFFLE_MODE - | PlaybackStateCompat.ACTION_SET_REPEAT_MODE; - - protected final long rewindIncrementMs; - protected final long fastForwardIncrementMs; - - /** - * Creates a new instance. - * - *
Equivalent to {@code DefaultPlaybackController(DefaultPlaybackController.DEFAULT_REWIND_MS,
- * DefaultPlaybackController.DEFAULT_FAST_FORWARD_MS)}.
- */
- public DefaultPlaybackController() {
- this(DEFAULT_REWIND_MS, DEFAULT_FAST_FORWARD_MS);
- }
-
- /**
- * Creates a new instance with the given fast forward and rewind increments.
- *
- * @param rewindIncrementMs The rewind increment in milliseconds. A zero or negative value will
- * cause the rewind action to be disabled.
- * @param fastForwardIncrementMs The fast forward increment in milliseconds. A zero or negative
- */
- public DefaultPlaybackController(long rewindIncrementMs, long fastForwardIncrementMs) {
- this.rewindIncrementMs = rewindIncrementMs;
- this.fastForwardIncrementMs = fastForwardIncrementMs;
- }
-
- @Override
- public long getSupportedPlaybackActions(Player player) {
- if (player == null || player.getCurrentTimeline().isEmpty()) {
- return 0;
- } else if (!player.isCurrentWindowSeekable()) {
- return BASE_ACTIONS;
- }
- long actions = BASE_ACTIONS | PlaybackStateCompat.ACTION_SEEK_TO;
- if (fastForwardIncrementMs > 0) {
- actions |= PlaybackStateCompat.ACTION_FAST_FORWARD;
- }
- if (rewindIncrementMs > 0) {
- actions |= PlaybackStateCompat.ACTION_REWIND;
- }
- return actions;
- }
-
- @Override
- public void onPlay(Player player) {
- player.setPlayWhenReady(true);
- }
-
- @Override
- public void onPause(Player player) {
- player.setPlayWhenReady(false);
- }
-
- @Override
- public void onSeekTo(Player player, long positionMs) {
- long duration = player.getDuration();
- if (duration != C.TIME_UNSET) {
- positionMs = Math.min(positionMs, duration);
- }
- player.seekTo(Math.max(positionMs, 0));
- }
-
- @Override
- public void onFastForward(Player player) {
- if (fastForwardIncrementMs <= 0) {
- return;
- }
- onSeekTo(player, player.getCurrentPosition() + fastForwardIncrementMs);
- }
-
- @Override
- public void onRewind(Player player) {
- if (rewindIncrementMs <= 0) {
- return;
- }
- onSeekTo(player, player.getCurrentPosition() - rewindIncrementMs);
- }
-
- @Override
- public void onStop(Player player) {
- player.stop(true);
- }
-
- @Override
- public void onSetShuffleMode(Player player, int shuffleMode) {
- player.setShuffleModeEnabled(shuffleMode == PlaybackStateCompat.SHUFFLE_MODE_ALL
- || shuffleMode == PlaybackStateCompat.SHUFFLE_MODE_GROUP);
- }
-
- @Override
- public void onSetRepeatMode(Player player, int mediaSessionRepeatMode) {
- int repeatMode;
- switch (mediaSessionRepeatMode) {
- case PlaybackStateCompat.REPEAT_MODE_ALL:
- case PlaybackStateCompat.REPEAT_MODE_GROUP:
- repeatMode = Player.REPEAT_MODE_ALL;
- break;
- case PlaybackStateCompat.REPEAT_MODE_ONE:
- repeatMode = Player.REPEAT_MODE_ONE;
- break;
- default:
- repeatMode = Player.REPEAT_MODE_OFF;
- break;
- }
- player.setRepeatMode(repeatMode);
- }
-
- // CommandReceiver implementation.
-
- @Override
- public boolean onCommand(Player player, String command, Bundle extras, ResultReceiver cb) {
- return false;
- }
-
-}
diff --git a/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/MediaSessionConnector.java b/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/MediaSessionConnector.java
index 16dc40d1e9..0b5fdbc624 100644
--- a/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/MediaSessionConnector.java
+++ b/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/MediaSessionConnector.java
@@ -22,6 +22,7 @@ import android.os.Handler;
import android.os.Looper;
import android.os.ResultReceiver;
import android.os.SystemClock;
+import android.support.annotation.LongDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.media.MediaDescriptionCompat;
@@ -32,6 +33,8 @@ import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import android.util.Pair;
import com.google.android.exoplayer2.C;
+import com.google.android.exoplayer2.ControlDispatcher;
+import com.google.android.exoplayer2.DefaultControlDispatcher;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
import com.google.android.exoplayer2.PlaybackParameters;
@@ -39,7 +42,10 @@ import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.ErrorMessageProvider;
+import com.google.android.exoplayer2.util.RepeatModeUtil;
import com.google.android.exoplayer2.util.Util;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -76,7 +82,52 @@ public final class MediaSessionConnector {
ExoPlayerLibraryInfo.registerModule("goog.exo.mediasession");
}
+ /** Playback actions supported by the connector. */
+ @LongDef(
+ flag = true,
+ value = {
+ PlaybackStateCompat.ACTION_PLAY_PAUSE,
+ PlaybackStateCompat.ACTION_PLAY,
+ PlaybackStateCompat.ACTION_PAUSE,
+ PlaybackStateCompat.ACTION_SEEK_TO,
+ PlaybackStateCompat.ACTION_FAST_FORWARD,
+ PlaybackStateCompat.ACTION_REWIND,
+ PlaybackStateCompat.ACTION_STOP,
+ PlaybackStateCompat.ACTION_SET_REPEAT_MODE,
+ PlaybackStateCompat.ACTION_SET_SHUFFLE_MODE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface PlaybackActions {}
+
+ @PlaybackActions
+ public static final long ALL_PLAYBACK_ACTIONS =
+ PlaybackStateCompat.ACTION_PLAY_PAUSE
+ | PlaybackStateCompat.ACTION_PLAY
+ | PlaybackStateCompat.ACTION_PAUSE
+ | PlaybackStateCompat.ACTION_SEEK_TO
+ | PlaybackStateCompat.ACTION_FAST_FORWARD
+ | PlaybackStateCompat.ACTION_REWIND
+ | PlaybackStateCompat.ACTION_STOP
+ | PlaybackStateCompat.ACTION_SET_REPEAT_MODE
+ | PlaybackStateCompat.ACTION_SET_SHUFFLE_MODE;
+
+ /** The default playback actions. */
+ @PlaybackActions public static final long DEFAULT_PLAYBACK_ACTIONS = ALL_PLAYBACK_ACTIONS;
+
+ /** The default fast forward increment, in milliseconds. */
+ public static final int DEFAULT_FAST_FORWARD_MS = 15000;
+ /** The default rewind increment, in milliseconds. */
+ public static final int DEFAULT_REWIND_MS = 5000;
+
public static final String EXTRAS_PITCH = "EXO_PITCH";
+
+ private static final long BASE_PLAYBACK_ACTIONS =
+ PlaybackStateCompat.ACTION_PLAY_PAUSE
+ | PlaybackStateCompat.ACTION_PLAY
+ | PlaybackStateCompat.ACTION_PAUSE
+ | PlaybackStateCompat.ACTION_STOP
+ | PlaybackStateCompat.ACTION_SET_SHUFFLE_MODE
+ | PlaybackStateCompat.ACTION_SET_REPEAT_MODE;
private static final int BASE_MEDIA_SESSION_FLAGS =
MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS
| MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS;
@@ -86,11 +137,24 @@ public final class MediaSessionConnector {
/** Receiver of media commands sent by a media controller. */
public interface CommandReceiver {
/**
- * See {@link MediaSessionCompat.Callback#onCommand(String, Bundle, ResultReceiver)}.
+ * See {@link MediaSessionCompat.Callback#onCommand(String, Bundle, ResultReceiver)}. The
+ * receiver may handle the command, but is not required to do so. Changes to the player should
+ * be made via the {@link ControlDispatcher}.
*
- * @return Whether the command was handled by the receiver.
+ * @param player The player connected to the media session.
+ * @param controlDispatcher A {@link ControlDispatcher} that should be used for dispatching
+ * changes to the player.
+ * @param command The command name.
+ * @param extras Optional parameters for the command, may be null.
+ * @param cb A result receiver to which a result may be sent by the command, may be null.
+ * @return Whether the receiver handled the command.
*/
- boolean onCommand(Player player, String command, Bundle extras, ResultReceiver cb);
+ boolean onCommand(
+ Player player,
+ ControlDispatcher controlDispatcher,
+ String command,
+ Bundle extras,
+ ResultReceiver cb);
}
/** Interface to which playback preparation actions are delegated. */
@@ -128,51 +192,6 @@ public final class MediaSessionConnector {
void onPrepareFromUri(Uri uri, Bundle extras);
}
- /** Interface to which playback actions are delegated. */
- public interface PlaybackController extends CommandReceiver {
-
- long ACTIONS =
- PlaybackStateCompat.ACTION_PLAY_PAUSE
- | PlaybackStateCompat.ACTION_PLAY
- | PlaybackStateCompat.ACTION_PAUSE
- | PlaybackStateCompat.ACTION_SEEK_TO
- | PlaybackStateCompat.ACTION_FAST_FORWARD
- | PlaybackStateCompat.ACTION_REWIND
- | PlaybackStateCompat.ACTION_STOP
- | PlaybackStateCompat.ACTION_SET_REPEAT_MODE
- | PlaybackStateCompat.ACTION_SET_SHUFFLE_MODE;
-
- /**
- * Returns the actions which are supported by the controller. The supported actions must be a
- * bitmask combined out of {@link PlaybackStateCompat#ACTION_PLAY_PAUSE}, {@link
- * PlaybackStateCompat#ACTION_PLAY}, {@link PlaybackStateCompat#ACTION_PAUSE}, {@link
- * PlaybackStateCompat#ACTION_SEEK_TO}, {@link PlaybackStateCompat#ACTION_FAST_FORWARD}, {@link
- * PlaybackStateCompat#ACTION_REWIND}, {@link PlaybackStateCompat#ACTION_STOP}, {@link
- * PlaybackStateCompat#ACTION_SET_REPEAT_MODE} and {@link
- * PlaybackStateCompat#ACTION_SET_SHUFFLE_MODE}.
- *
- * @param player The player.
- * @return The bitmask of the supported media actions.
- */
- long getSupportedPlaybackActions(@Nullable Player player);
- /** See {@link MediaSessionCompat.Callback#onPlay()}. */
- void onPlay(Player player);
- /** See {@link MediaSessionCompat.Callback#onPause()}. */
- void onPause(Player player);
- /** See {@link MediaSessionCompat.Callback#onSeekTo(long)}. */
- void onSeekTo(Player player, long positionMs);
- /** See {@link MediaSessionCompat.Callback#onFastForward()}. */
- void onFastForward(Player player);
- /** See {@link MediaSessionCompat.Callback#onRewind()}. */
- void onRewind(Player player);
- /** See {@link MediaSessionCompat.Callback#onStop()}. */
- void onStop(Player player);
- /** See {@link MediaSessionCompat.Callback#onSetShuffleMode(int)}. */
- void onSetShuffleMode(Player player, int shuffleMode);
- /** See {@link MediaSessionCompat.Callback#onSetRepeatMode(int)}. */
- void onSetRepeatMode(Player player, int repeatMode);
- }
-
/**
* Handles queue navigation actions, and updates the media session queue by calling {@code
* MediaSessionCompat.setQueue()}.
@@ -190,20 +209,20 @@ public final class MediaSessionConnector {
* PlaybackStateCompat#ACTION_SKIP_TO_NEXT}, {@link
* PlaybackStateCompat#ACTION_SKIP_TO_PREVIOUS}.
*
- * @param player The {@link Player}.
+ * @param player The player connected to the media session.
* @return The bitmask of the supported media actions.
*/
long getSupportedQueueNavigatorActions(@Nullable Player player);
/**
* Called when the timeline of the player has changed.
*
- * @param player The player of which the timeline has changed.
+ * @param player The player connected to the media session.
*/
void onTimelineChanged(Player player);
/**
* Called when the current window index changed.
*
- * @param player The player of which the current window index of the timeline has changed.
+ * @param player The player connected to the media session.
*/
void onCurrentWindowIndexChanged(Player player);
/**
@@ -218,12 +237,30 @@ public final class MediaSessionConnector {
* @return The id of the active queue item.
*/
long getActiveQueueItemId(@Nullable Player player);
- /** See {@link MediaSessionCompat.Callback#onSkipToPrevious()}. */
- void onSkipToPrevious(Player player);
- /** See {@link MediaSessionCompat.Callback#onSkipToQueueItem(long)}. */
- void onSkipToQueueItem(Player player, long id);
- /** See {@link MediaSessionCompat.Callback#onSkipToNext()}. */
- void onSkipToNext(Player player);
+ /**
+ * See {@link MediaSessionCompat.Callback#onSkipToPrevious()}.
+ *
+ * @param player The player connected to the media session.
+ * @param controlDispatcher A {@link ControlDispatcher} that should be used for dispatching
+ * changes to the player.
+ */
+ void onSkipToPrevious(Player player, ControlDispatcher controlDispatcher);
+ /**
+ * See {@link MediaSessionCompat.Callback#onSkipToQueueItem(long)}.
+ *
+ * @param player The player connected to the media session.
+ * @param controlDispatcher A {@link ControlDispatcher} that should be used for dispatching
+ * changes to the player.
+ */
+ void onSkipToQueueItem(Player player, ControlDispatcher controlDispatcher, long id);
+ /**
+ * See {@link MediaSessionCompat.Callback#onSkipToNext()}.
+ *
+ * @param player The player connected to the media session.
+ * @param controlDispatcher A {@link ControlDispatcher} that should be used for dispatching
+ * changes to the player.
+ */
+ void onSkipToNext(Player player, ControlDispatcher controlDispatcher);
}
/** Handles media session queue edits. */
@@ -263,19 +300,24 @@ public final class MediaSessionConnector {
/**
* Called when a custom action provided by this provider is sent to the media session.
*
+ * @param player The player connected to the media session.
+ * @param controlDispatcher A {@link ControlDispatcher} that should be used for dispatching
+ * changes to the player.
* @param action The name of the action which was sent by a media controller.
* @param extras Optional extras sent by a media controller.
*/
- void onCustomAction(String action, Bundle extras);
+ void onCustomAction(
+ Player player, ControlDispatcher controlDispatcher, String action, Bundle extras);
/**
* 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 given
* player state.
*
+ * @param player The player connected to the media session.
* @return The custom action to be included in the session playback state or {@code null}.
*/
- PlaybackStateCompat.CustomAction getCustomAction();
+ PlaybackStateCompat.CustomAction getCustomAction(Player player);
}
/** Provides a {@link MediaMetadataCompat} for a given player state. */
@@ -283,7 +325,7 @@ public final class MediaSessionConnector {
/**
* Gets the {@link MediaMetadataCompat} to be published to the session.
*
- * @param player The player for which to provide metadata.
+ * @param player The player connected to the media session.
* @return The {@link MediaMetadataCompat} to be published to the session.
*/
MediaMetadataCompat getMetadata(Player player);
@@ -292,47 +334,37 @@ public final class MediaSessionConnector {
/** The wrapped {@link MediaSessionCompat}. */
public final MediaSessionCompat mediaSession;
- private @Nullable final MediaMetadataProvider mediaMetadataProvider;
+ @Nullable private final MediaMetadataProvider mediaMetadataProvider;
private final ExoPlayerEventListener exoPlayerEventListener;
private final MediaSessionCallback mediaSessionCallback;
- private final PlaybackController playbackController;
private final ArrayList Equivalent to {@code MediaSessionConnector(mediaSession, new DefaultPlaybackController())}.
- *
- * @param mediaSession The {@link MediaSessionCompat} to connect to.
- */
- public MediaSessionConnector(MediaSessionCompat mediaSession) {
- this(mediaSession, null);
- }
+ private long enabledPlaybackActions;
+ private int rewindMs;
+ private int fastForwardMs;
/**
* Creates an instance.
*
- * Equivalent to {@code MediaSessionConnector(mediaSession, playbackController, new
+ * Equivalent to {@code MediaSessionConnector(mediaSession, new
* DefaultMediaMetadataProvider(mediaSession.getController(), null))}.
*
* @param mediaSession The {@link MediaSessionCompat} to connect to.
- * @param playbackController A {@link PlaybackController} for handling playback actions.
*/
- public MediaSessionConnector(
- MediaSessionCompat mediaSession, PlaybackController playbackController) {
+ public MediaSessionConnector(MediaSessionCompat mediaSession) {
this(
mediaSession,
- playbackController,
new DefaultMediaMetadataProvider(mediaSession.getController(), null));
}
@@ -340,52 +372,24 @@ public final class MediaSessionConnector {
* Creates an instance.
*
* @param mediaSession The {@link MediaSessionCompat} to connect to.
- * @param playbackController A {@link PlaybackController} for handling playback actions, or {@code
- * null} if the connector should handle playback actions directly.
- * @param doMaintainMetadata Whether the connector should maintain the metadata of the session.
- * @param metadataExtrasPrefix A string to prefix extra keys which are propagated from the active
- * queue item to the session metadata.
- * @deprecated Use {@link MediaSessionConnector#MediaSessionConnector(MediaSessionCompat,
- * PlaybackController, MediaMetadataProvider)}.
- */
- @Deprecated
- public MediaSessionConnector(
- MediaSessionCompat mediaSession,
- @Nullable PlaybackController playbackController,
- boolean doMaintainMetadata,
- @Nullable String metadataExtrasPrefix) {
- this(
- mediaSession,
- playbackController,
- doMaintainMetadata
- ? new DefaultMediaMetadataProvider(mediaSession.getController(), metadataExtrasPrefix)
- : null);
- }
-
- /**
- * Creates an instance.
- *
- * @param mediaSession The {@link MediaSessionCompat} to connect to.
- * @param playbackController A {@link PlaybackController} for handling playback actions, or {@code
- * null} if the connector should handle playback actions directly.
* @param mediaMetadataProvider A {@link MediaMetadataProvider} for providing a custom metadata
* object to be published to the media session, or {@code null} if metadata shouldn't be
* published.
*/
public MediaSessionConnector(
MediaSessionCompat mediaSession,
- @Nullable PlaybackController playbackController,
@Nullable MediaMetadataProvider mediaMetadataProvider) {
this.mediaSession = mediaSession;
- this.playbackController =
- playbackController != null ? playbackController : new DefaultPlaybackController();
this.mediaMetadataProvider = mediaMetadataProvider;
mediaSession.setFlags(BASE_MEDIA_SESSION_FLAGS);
mediaSessionCallback = new MediaSessionCallback();
exoPlayerEventListener = new ExoPlayerEventListener();
+ controlDispatcher = new DefaultControlDispatcher();
customActionMap = Collections.emptyMap();
commandReceivers = new ArrayList<>();
- registerCommandReceiver(playbackController);
+ enabledPlaybackActions = DEFAULT_PLAYBACK_ACTIONS;
+ rewindMs = DEFAULT_REWIND_MS;
+ fastForwardMs = DEFAULT_FAST_FORWARD_MS;
}
/**
@@ -410,8 +414,8 @@ public final class MediaSessionConnector {
this.player.removeListener(exoPlayerEventListener);
mediaSession.setCallback(null);
}
- unregisterCommandReceiver(this.playbackPreparer);
+ unregisterCommandReceiver(this.playbackPreparer);
this.player = player;
this.playbackPreparer = playbackPreparer;
registerCommandReceiver(playbackPreparer);
@@ -429,6 +433,58 @@ public final class MediaSessionConnector {
invalidateMediaSessionMetadata();
}
+ /**
+ * Sets the {@link ControlDispatcher}.
+ *
+ * @param controlDispatcher The {@link ControlDispatcher}, or null to use {@link
+ * DefaultControlDispatcher}.
+ */
+ public void setControlDispatcher(@Nullable ControlDispatcher controlDispatcher) {
+ if (this.controlDispatcher != controlDispatcher) {
+ this.controlDispatcher =
+ controlDispatcher == null ? new DefaultControlDispatcher() : controlDispatcher;
+ }
+ }
+
+ /**
+ * Sets the enabled playback actions.
+ *
+ * @param enabledPlaybackActions The enabled playback actions.
+ */
+ public void setEnabledPlaybackActions(@PlaybackActions long enabledPlaybackActions) {
+ enabledPlaybackActions &= ALL_PLAYBACK_ACTIONS;
+ if (this.enabledPlaybackActions != enabledPlaybackActions) {
+ this.enabledPlaybackActions = enabledPlaybackActions;
+ invalidateMediaSessionPlaybackState();
+ }
+ }
+
+ /**
+ * Sets the rewind increment in milliseconds.
+ *
+ * @param rewindMs The rewind increment in milliseconds. A non-positive value will cause the
+ * rewind button to be disabled.
+ */
+ public void setRewindIncrementMs(int rewindMs) {
+ if (this.rewindMs != rewindMs) {
+ this.rewindMs = rewindMs;
+ invalidateMediaSessionPlaybackState();
+ }
+ }
+
+ /**
+ * Sets the fast forward increment in milliseconds.
+ *
+ * @param fastForwardMs The fast forward increment in milliseconds. A non-positive value will
+ * cause the fast forward button to be disabled.
+ */
+ public void setFastForwardIncrementMs(int fastForwardMs) {
+ if (this.fastForwardMs != fastForwardMs) {
+ this.fastForwardMs = fastForwardMs;
+ invalidateMediaSessionPlaybackState();
+ }
+ }
+
/**
* Sets the optional {@link ErrorMessageProvider}.
*
@@ -537,7 +593,7 @@ public final class MediaSessionConnector {
Map
- * Equivalent to {@code RepeatModeActionProvider(context, player,
- * MediaSessionConnector.DEFAULT_REPEAT_TOGGLE_MODES)}.
+ *
+ * Equivalent to {@code RepeatModeActionProvider(context, DEFAULT_REPEAT_TOGGLE_MODES)}.
*
* @param context The context.
- * @param player The player on which to toggle the repeat mode.
*/
- public RepeatModeActionProvider(Context context, Player player) {
- this(context, player, DEFAULT_REPEAT_TOGGLE_MODES);
+ public RepeatModeActionProvider(Context context) {
+ this(context, DEFAULT_REPEAT_TOGGLE_MODES);
}
/**
* Creates a new instance enabling the given repeat toggle modes.
*
* @param context The context.
- * @param player The player on which to toggle the repeat mode.
* @param repeatToggleModes The toggle modes to enable.
*/
- public RepeatModeActionProvider(Context context, Player player,
- @RepeatModeUtil.RepeatToggleModes int repeatToggleModes) {
- this.player = player;
+ public RepeatModeActionProvider(
+ Context context, @RepeatModeUtil.RepeatToggleModes int repeatToggleModes) {
this.repeatToggleModes = repeatToggleModes;
repeatAllDescription = context.getString(R.string.exo_media_action_repeat_all_description);
repeatOneDescription = context.getString(R.string.exo_media_action_repeat_one_description);
@@ -70,16 +66,17 @@ public final class RepeatModeActionProvider implements MediaSessionConnector.Cus
}
@Override
- public void onCustomAction(String action, Bundle extras) {
+ public void onCustomAction(
+ Player player, ControlDispatcher controlDispatcher, String action, Bundle extras) {
int mode = player.getRepeatMode();
int proposedMode = RepeatModeUtil.getNextRepeatMode(mode, repeatToggleModes);
if (mode != proposedMode) {
- player.setRepeatMode(proposedMode);
+ controlDispatcher.dispatchSetRepeatMode(player, proposedMode);
}
}
@Override
- public PlaybackStateCompat.CustomAction getCustomAction() {
+ public PlaybackStateCompat.CustomAction getCustomAction(Player player) {
CharSequence actionLabel;
int iconResourceId;
switch (player.getRepeatMode()) {
diff --git a/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/TimelineQueueEditor.java b/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/TimelineQueueEditor.java
index ab296afad7..093913fd8c 100644
--- a/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/TimelineQueueEditor.java
+++ b/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/TimelineQueueEditor.java
@@ -23,6 +23,7 @@ import android.support.v4.media.MediaDescriptionCompat;
import android.support.v4.media.session.MediaControllerCompat;
import android.support.v4.media.session.MediaSessionCompat;
import com.google.android.exoplayer2.C;
+import com.google.android.exoplayer2.ControlDispatcher;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
@@ -194,7 +195,12 @@ public final class TimelineQueueEditor
// CommandReceiver implementation.
@Override
- public boolean onCommand(Player player, String command, Bundle extras, ResultReceiver cb) {
+ public boolean onCommand(
+ Player player,
+ ControlDispatcher controlDispatcher,
+ String command,
+ Bundle extras,
+ ResultReceiver cb) {
if (!COMMAND_MOVE_QUEUE_ITEM.equals(command)) {
return false;
}
diff --git a/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/TimelineQueueNavigator.java b/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/TimelineQueueNavigator.java
index 53f784e021..6eb1b4d4ca 100644
--- a/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/TimelineQueueNavigator.java
+++ b/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/TimelineQueueNavigator.java
@@ -22,6 +22,7 @@ import android.support.v4.media.MediaDescriptionCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import com.google.android.exoplayer2.C;
+import com.google.android.exoplayer2.ControlDispatcher;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.util.Util;
@@ -124,7 +125,7 @@ public abstract class TimelineQueueNavigator implements MediaSessionConnector.Qu
}
@Override
- public void onSkipToPrevious(Player player) {
+ public void onSkipToPrevious(Player player, ControlDispatcher controlDispatcher) {
Timeline timeline = player.getCurrentTimeline();
if (timeline.isEmpty() || player.isPlayingAd()) {
return;
@@ -135,26 +136,26 @@ public abstract class TimelineQueueNavigator implements MediaSessionConnector.Qu
if (previousWindowIndex != C.INDEX_UNSET
&& (player.getCurrentPosition() <= MAX_POSITION_FOR_SEEK_TO_PREVIOUS
|| (window.isDynamic && !window.isSeekable))) {
- player.seekTo(previousWindowIndex, C.TIME_UNSET);
+ controlDispatcher.dispatchSeekTo(player, previousWindowIndex, C.TIME_UNSET);
} else {
- player.seekTo(0);
+ controlDispatcher.dispatchSeekTo(player, windowIndex, 0);
}
}
@Override
- public void onSkipToQueueItem(Player player, long id) {
+ public void onSkipToQueueItem(Player player, ControlDispatcher controlDispatcher, long id) {
Timeline timeline = player.getCurrentTimeline();
if (timeline.isEmpty() || player.isPlayingAd()) {
return;
}
int windowIndex = (int) id;
if (0 <= windowIndex && windowIndex < timeline.getWindowCount()) {
- player.seekTo(windowIndex, C.TIME_UNSET);
+ controlDispatcher.dispatchSeekTo(player, windowIndex, C.TIME_UNSET);
}
}
@Override
- public void onSkipToNext(Player player) {
+ public void onSkipToNext(Player player, ControlDispatcher controlDispatcher) {
Timeline timeline = player.getCurrentTimeline();
if (timeline.isEmpty() || player.isPlayingAd()) {
return;
@@ -162,16 +163,21 @@ public abstract class TimelineQueueNavigator implements MediaSessionConnector.Qu
int windowIndex = player.getCurrentWindowIndex();
int nextWindowIndex = player.getNextWindowIndex();
if (nextWindowIndex != C.INDEX_UNSET) {
- player.seekTo(nextWindowIndex, C.TIME_UNSET);
+ controlDispatcher.dispatchSeekTo(player, nextWindowIndex, C.TIME_UNSET);
} else if (timeline.getWindow(windowIndex, window).isDynamic) {
- player.seekTo(windowIndex, C.TIME_UNSET);
+ controlDispatcher.dispatchSeekTo(player, windowIndex, C.TIME_UNSET);
}
}
// CommandReceiver implementation.
@Override
- public boolean onCommand(Player player, String command, Bundle extras, ResultReceiver cb) {
+ public boolean onCommand(
+ Player player,
+ ControlDispatcher controlDispatcher,
+ String command,
+ Bundle extras,
+ ResultReceiver cb) {
return false;
}
@@ -197,4 +203,3 @@ public abstract class TimelineQueueNavigator implements MediaSessionConnector.Qu
}
}
-