Commit 063f5704 by olly Committed by Oliver Woodman

Simplify MediaSessionConnector

- Make MediaSessionConnector use a ControlDispatcher and add setControlDispatcher,
  setFastForwardIncrementMs and setRewindIncrementMs methods. This brings it in line
  with our other UI components, including PlayerControlView and
  PlayerNotificationManager.
- Collapsed DefaultPlaybackController into MediaSessionConnector, since I'm not
  sure there's a legitimate alternative implementation (note ControlDispatcher does
  provide some equivalent functionality e.g. to modify calls being made on the
  player).
- Pass the Player and ControlDispatcher to command receivers and custom actions,
  so they don't need their own references.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=220822082
parent 8ec757ad
/*
* 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}.
* <p>
* 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.
*
* <p>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;
}
}
...@@ -18,6 +18,7 @@ package com.google.android.exoplayer2.ext.mediasession; ...@@ -18,6 +18,7 @@ package com.google.android.exoplayer2.ext.mediasession;
import android.content.Context; 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.ControlDispatcher;
import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.util.RepeatModeUtil; import com.google.android.exoplayer2.util.RepeatModeUtil;
...@@ -33,7 +34,6 @@ public final class RepeatModeActionProvider implements MediaSessionConnector.Cus ...@@ -33,7 +34,6 @@ public final class RepeatModeActionProvider implements MediaSessionConnector.Cus
private static final String ACTION_REPEAT_MODE = "ACTION_EXO_REPEAT_MODE"; private static final String ACTION_REPEAT_MODE = "ACTION_EXO_REPEAT_MODE";
private final Player player;
@RepeatModeUtil.RepeatToggleModes @RepeatModeUtil.RepeatToggleModes
private final int repeatToggleModes; private final int repeatToggleModes;
private final CharSequence repeatAllDescription; private final CharSequence repeatAllDescription;
...@@ -42,27 +42,23 @@ public final class RepeatModeActionProvider implements MediaSessionConnector.Cus ...@@ -42,27 +42,23 @@ public final class RepeatModeActionProvider implements MediaSessionConnector.Cus
/** /**
* Creates a new instance. * Creates a new instance.
* <p> *
* Equivalent to {@code RepeatModeActionProvider(context, player, * <p>Equivalent to {@code RepeatModeActionProvider(context, DEFAULT_REPEAT_TOGGLE_MODES)}.
* MediaSessionConnector.DEFAULT_REPEAT_TOGGLE_MODES)}.
* *
* @param context The context. * @param context The context.
* @param player The player on which to toggle the repeat mode.
*/ */
public RepeatModeActionProvider(Context context, Player player) { public RepeatModeActionProvider(Context context) {
this(context, player, DEFAULT_REPEAT_TOGGLE_MODES); this(context, DEFAULT_REPEAT_TOGGLE_MODES);
} }
/** /**
* Creates a new instance enabling the given repeat toggle modes. * Creates a new instance enabling 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, Player player, public RepeatModeActionProvider(
@RepeatModeUtil.RepeatToggleModes int repeatToggleModes) { Context context, @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);
...@@ -70,16 +66,17 @@ public final class RepeatModeActionProvider implements MediaSessionConnector.Cus ...@@ -70,16 +66,17 @@ public final class RepeatModeActionProvider implements MediaSessionConnector.Cus
} }
@Override @Override
public void onCustomAction(String action, Bundle extras) { public void onCustomAction(
Player player, ControlDispatcher controlDispatcher, 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) {
player.setRepeatMode(proposedMode); controlDispatcher.dispatchSetRepeatMode(player, proposedMode);
} }
} }
@Override @Override
public PlaybackStateCompat.CustomAction getCustomAction() { public PlaybackStateCompat.CustomAction getCustomAction(Player player) {
CharSequence actionLabel; CharSequence actionLabel;
int iconResourceId; int iconResourceId;
switch (player.getRepeatMode()) { switch (player.getRepeatMode()) {
......
...@@ -23,6 +23,7 @@ import android.support.v4.media.MediaDescriptionCompat; ...@@ -23,6 +23,7 @@ import android.support.v4.media.MediaDescriptionCompat;
import android.support.v4.media.session.MediaControllerCompat; import android.support.v4.media.session.MediaControllerCompat;
import android.support.v4.media.session.MediaSessionCompat; import android.support.v4.media.session.MediaSessionCompat;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ControlDispatcher;
import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.source.ConcatenatingMediaSource; import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MediaSource;
...@@ -194,7 +195,12 @@ public final class TimelineQueueEditor ...@@ -194,7 +195,12 @@ public final class TimelineQueueEditor
// CommandReceiver implementation. // CommandReceiver implementation.
@Override @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)) { if (!COMMAND_MOVE_QUEUE_ITEM.equals(command)) {
return false; return false;
} }
......
...@@ -22,6 +22,7 @@ import android.support.v4.media.MediaDescriptionCompat; ...@@ -22,6 +22,7 @@ import android.support.v4.media.MediaDescriptionCompat;
import android.support.v4.media.session.MediaSessionCompat; import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat; import android.support.v4.media.session.PlaybackStateCompat;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ControlDispatcher;
import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
...@@ -124,7 +125,7 @@ public abstract class TimelineQueueNavigator implements MediaSessionConnector.Qu ...@@ -124,7 +125,7 @@ public abstract class TimelineQueueNavigator implements MediaSessionConnector.Qu
} }
@Override @Override
public void onSkipToPrevious(Player player) { public void onSkipToPrevious(Player player, ControlDispatcher controlDispatcher) {
Timeline timeline = player.getCurrentTimeline(); Timeline timeline = player.getCurrentTimeline();
if (timeline.isEmpty() || player.isPlayingAd()) { if (timeline.isEmpty() || player.isPlayingAd()) {
return; return;
...@@ -135,26 +136,26 @@ public abstract class TimelineQueueNavigator implements MediaSessionConnector.Qu ...@@ -135,26 +136,26 @@ public abstract class TimelineQueueNavigator implements MediaSessionConnector.Qu
if (previousWindowIndex != C.INDEX_UNSET if (previousWindowIndex != C.INDEX_UNSET
&& (player.getCurrentPosition() <= MAX_POSITION_FOR_SEEK_TO_PREVIOUS && (player.getCurrentPosition() <= MAX_POSITION_FOR_SEEK_TO_PREVIOUS
|| (window.isDynamic && !window.isSeekable))) { || (window.isDynamic && !window.isSeekable))) {
player.seekTo(previousWindowIndex, C.TIME_UNSET); controlDispatcher.dispatchSeekTo(player, previousWindowIndex, C.TIME_UNSET);
} else { } else {
player.seekTo(0); controlDispatcher.dispatchSeekTo(player, windowIndex, 0);
} }
} }
@Override @Override
public void onSkipToQueueItem(Player player, long id) { public void onSkipToQueueItem(Player player, ControlDispatcher controlDispatcher, long id) {
Timeline timeline = player.getCurrentTimeline(); Timeline timeline = player.getCurrentTimeline();
if (timeline.isEmpty() || player.isPlayingAd()) { if (timeline.isEmpty() || player.isPlayingAd()) {
return; return;
} }
int windowIndex = (int) id; int windowIndex = (int) id;
if (0 <= windowIndex && windowIndex < timeline.getWindowCount()) { if (0 <= windowIndex && windowIndex < timeline.getWindowCount()) {
player.seekTo(windowIndex, C.TIME_UNSET); controlDispatcher.dispatchSeekTo(player, windowIndex, C.TIME_UNSET);
} }
} }
@Override @Override
public void onSkipToNext(Player player) { public void onSkipToNext(Player player, ControlDispatcher controlDispatcher) {
Timeline timeline = player.getCurrentTimeline(); Timeline timeline = player.getCurrentTimeline();
if (timeline.isEmpty() || player.isPlayingAd()) { if (timeline.isEmpty() || player.isPlayingAd()) {
return; return;
...@@ -162,16 +163,21 @@ public abstract class TimelineQueueNavigator implements MediaSessionConnector.Qu ...@@ -162,16 +163,21 @@ public abstract class TimelineQueueNavigator implements MediaSessionConnector.Qu
int windowIndex = player.getCurrentWindowIndex(); int windowIndex = player.getCurrentWindowIndex();
int nextWindowIndex = player.getNextWindowIndex(); int nextWindowIndex = player.getNextWindowIndex();
if (nextWindowIndex != C.INDEX_UNSET) { 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) { } else if (timeline.getWindow(windowIndex, window).isDynamic) {
player.seekTo(windowIndex, C.TIME_UNSET); controlDispatcher.dispatchSeekTo(player, windowIndex, C.TIME_UNSET);
} }
} }
// CommandReceiver implementation. // CommandReceiver implementation.
@Override @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; return false;
} }
...@@ -197,4 +203,3 @@ public abstract class TimelineQueueNavigator implements MediaSessionConnector.Qu ...@@ -197,4 +203,3 @@ public abstract class TimelineQueueNavigator implements MediaSessionConnector.Qu
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment