diff --git a/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java b/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java index ee626ceafc..81b1635f9f 100644 --- a/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java +++ b/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java @@ -94,6 +94,8 @@ public final class CastPlayer extends BasePlayer { COMMAND_PREPARE_STOP, COMMAND_SEEK_TO_DEFAULT_POSITION, COMMAND_SEEK_TO_MEDIA_ITEM, + COMMAND_SET_FAST_FORWARD_INCREMENT, + COMMAND_SET_REWIND_INCREMENT, COMMAND_SET_REPEAT_MODE, COMMAND_GET_CURRENT_MEDIA_ITEM, COMMAND_GET_MEDIA_ITEMS, diff --git a/extensions/cast/src/test/java/com/google/android/exoplayer2/ext/cast/CastPlayerTest.java b/extensions/cast/src/test/java/com/google/android/exoplayer2/ext/cast/CastPlayerTest.java index 692ce2dc4d..2071cc213e 100644 --- a/extensions/cast/src/test/java/com/google/android/exoplayer2/ext/cast/CastPlayerTest.java +++ b/extensions/cast/src/test/java/com/google/android/exoplayer2/ext/cast/CastPlayerTest.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer2.ext.cast; import static com.google.android.exoplayer2.Player.COMMAND_ADJUST_DEVICE_VOLUME; import static com.google.android.exoplayer2.Player.COMMAND_CHANGE_MEDIA_ITEMS; +import static com.google.android.exoplayer2.Player.COMMAND_FAST_FORWARD; import static com.google.android.exoplayer2.Player.COMMAND_GET_AUDIO_ATTRIBUTES; import static com.google.android.exoplayer2.Player.COMMAND_GET_CURRENT_MEDIA_ITEM; import static com.google.android.exoplayer2.Player.COMMAND_GET_DEVICE_VOLUME; @@ -26,14 +27,17 @@ import static com.google.android.exoplayer2.Player.COMMAND_GET_TEXT; import static com.google.android.exoplayer2.Player.COMMAND_GET_VOLUME; import static com.google.android.exoplayer2.Player.COMMAND_PLAY_PAUSE; import static com.google.android.exoplayer2.Player.COMMAND_PREPARE_STOP; +import static com.google.android.exoplayer2.Player.COMMAND_REWIND; import static com.google.android.exoplayer2.Player.COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM; import static com.google.android.exoplayer2.Player.COMMAND_SEEK_TO_DEFAULT_POSITION; import static com.google.android.exoplayer2.Player.COMMAND_SEEK_TO_MEDIA_ITEM; import static com.google.android.exoplayer2.Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM; import static com.google.android.exoplayer2.Player.COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM; import static com.google.android.exoplayer2.Player.COMMAND_SET_DEVICE_VOLUME; +import static com.google.android.exoplayer2.Player.COMMAND_SET_FAST_FORWARD_INCREMENT; import static com.google.android.exoplayer2.Player.COMMAND_SET_MEDIA_ITEMS_METADATA; import static com.google.android.exoplayer2.Player.COMMAND_SET_REPEAT_MODE; +import static com.google.android.exoplayer2.Player.COMMAND_SET_REWIND_INCREMENT; import static com.google.android.exoplayer2.Player.COMMAND_SET_SHUFFLE_MODE; import static com.google.android.exoplayer2.Player.COMMAND_SET_SPEED_AND_PITCH; import static com.google.android.exoplayer2.Player.COMMAND_SET_VIDEO_SURFACE; @@ -1211,6 +1215,10 @@ public class CastPlayerTest { assertThat(castPlayer.isCommandAvailable(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM)).isTrue(); assertThat(castPlayer.isCommandAvailable(COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM)).isFalse(); assertThat(castPlayer.isCommandAvailable(COMMAND_SEEK_TO_MEDIA_ITEM)).isTrue(); + assertThat(castPlayer.isCommandAvailable(COMMAND_SET_FAST_FORWARD_INCREMENT)).isTrue(); + assertThat(castPlayer.isCommandAvailable(COMMAND_FAST_FORWARD)).isTrue(); + assertThat(castPlayer.isCommandAvailable(COMMAND_SET_REWIND_INCREMENT)).isTrue(); + assertThat(castPlayer.isCommandAvailable(COMMAND_REWIND)).isTrue(); assertThat(castPlayer.isCommandAvailable(COMMAND_SET_SPEED_AND_PITCH)).isFalse(); assertThat(castPlayer.isCommandAvailable(COMMAND_SET_SHUFFLE_MODE)).isFalse(); assertThat(castPlayer.isCommandAvailable(COMMAND_SET_REPEAT_MODE)).isTrue(); @@ -1230,7 +1238,7 @@ public class CastPlayerTest { } @Test - public void isCommandAvailable_duringUnseekableItem_isFalseForSeekInCurrent() { + public void isCommandAvailable_duringUnseekableItem_isFalseForSeekInCurrentCommands() { MediaItem mediaItem = createMediaItem(/* mediaQueueItemId= */ 1); List mediaItems = ImmutableList.of(mediaItem); int[] mediaQueueItemIds = new int[] {1}; @@ -1247,6 +1255,8 @@ public class CastPlayerTest { /* positionMs= */ C.TIME_UNSET); assertThat(castPlayer.isCommandAvailable(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM)).isFalse(); + assertThat(castPlayer.isCommandAvailable(COMMAND_FAST_FORWARD)).isFalse(); + assertThat(castPlayer.isCommandAvailable(COMMAND_REWIND)).isFalse(); } @Test @@ -1254,16 +1264,12 @@ public class CastPlayerTest { when(mockRemoteMediaClient.queueJumpToItem(anyInt(), anyLong(), eq(null))) .thenReturn(mockPendingResult); Player.Commands commandsWithSeekInCurrentAndToNext = - createWithPermanentCommands( - COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, COMMAND_SEEK_TO_NEXT_MEDIA_ITEM); + createWithPermanentAndSeekInCurrentCommands(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM); Player.Commands commandsWithSeekInCurrentAndToPrevious = - createWithPermanentCommands( - COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM); + createWithPermanentAndSeekInCurrentCommands(COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM); Player.Commands commandsWithSeekAnywhere = - createWithPermanentCommands( - COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, - COMMAND_SEEK_TO_NEXT_MEDIA_ITEM, - COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM); + createWithPermanentAndSeekInCurrentCommands( + COMMAND_SEEK_TO_NEXT_MEDIA_ITEM, COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM); int[] mediaQueueItemIds = new int[] {1, 2, 3, 4}; List mediaItems = createMediaItems(mediaQueueItemIds); @@ -1290,16 +1296,12 @@ public class CastPlayerTest { when(mockRemoteMediaClient.queueJumpToItem(anyInt(), anyLong(), eq(null))) .thenReturn(mockPendingResult); Player.Commands commandsWithSeekInCurrentAndToNext = - createWithPermanentCommands( - COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, COMMAND_SEEK_TO_NEXT_MEDIA_ITEM); + createWithPermanentAndSeekInCurrentCommands(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM); Player.Commands commandsWithSeekInCurrentAndToPrevious = - createWithPermanentCommands( - COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM); + createWithPermanentAndSeekInCurrentCommands(COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM); Player.Commands commandsWithSeekAnywhere = - createWithPermanentCommands( - COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, - COMMAND_SEEK_TO_NEXT_MEDIA_ITEM, - COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM); + createWithPermanentAndSeekInCurrentCommands( + COMMAND_SEEK_TO_NEXT_MEDIA_ITEM, COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM); int[] mediaQueueItemIds = new int[] {1, 2, 3, 4}; List mediaItems = createMediaItems(mediaQueueItemIds); @@ -1325,8 +1327,7 @@ public class CastPlayerTest { @SuppressWarnings("deprecation") // Mocks deprecated method used by the CastPlayer. public void seekTo_sameWindow_doesNotNotifyAvailableCommandsChanged() { when(mockRemoteMediaClient.seek(anyLong())).thenReturn(mockPendingResult); - Player.Commands commandsWithSeekInCurrent = - createWithPermanentCommands(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM); + Player.Commands commandsWithSeekInCurrent = createWithPermanentAndSeekInCurrentCommands(); int[] mediaQueueItemIds = new int[] {1}; List mediaItems = createMediaItems(mediaQueueItemIds); @@ -1342,11 +1343,10 @@ public class CastPlayerTest { @Test public void addMediaItem_atTheEnd_notifiesAvailableCommandsChanged() { - Player.Commands commandsWithSeekInCurrent = - createWithPermanentCommands(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM); + Player.Commands commandsWithSeekInCurrent = createWithPermanentAndSeekInCurrentCommands(); + ; Player.Commands commandsWithSeekInCurrentAndToNext = - createWithPermanentCommands( - COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, COMMAND_SEEK_TO_NEXT_MEDIA_ITEM); + createWithPermanentAndSeekInCurrentCommands(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM); MediaItem mediaItem1 = createMediaItem(/* mediaQueueItemId= */ 1); MediaItem mediaItem2 = createMediaItem(/* mediaQueueItemId= */ 2); MediaItem mediaItem3 = createMediaItem(/* mediaQueueItemId= */ 3); @@ -1378,11 +1378,10 @@ public class CastPlayerTest { @Test public void addMediaItem_atTheStart_notifiesAvailableCommandsChanged() { - Player.Commands commandsWithSeekInCurrent = - createWithPermanentCommands(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM); + Player.Commands commandsWithSeekInCurrent = createWithPermanentAndSeekInCurrentCommands(); + ; Player.Commands commandsWithSeekInCurrentAndToPrevious = - createWithPermanentCommands( - COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM); + createWithPermanentAndSeekInCurrentCommands(COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM); MediaItem mediaItem1 = createMediaItem(/* mediaQueueItemId= */ 1); MediaItem mediaItem2 = createMediaItem(/* mediaQueueItemId= */ 2); MediaItem mediaItem3 = createMediaItem(/* mediaQueueItemId= */ 3); @@ -1415,11 +1414,10 @@ public class CastPlayerTest { @Test public void removeMediaItem_atTheEnd_notifiesAvailableCommandsChanged() { Player.Commands commandsWithoutSeek = createWithPermanentCommands(); - Player.Commands commandsWithSeekInCurrent = - createWithPermanentCommands(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM); + Player.Commands commandsWithSeekInCurrent = createWithPermanentAndSeekInCurrentCommands(); + ; Player.Commands commandsWithSeekInCurrentAndToNext = - createWithPermanentCommands( - COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, COMMAND_SEEK_TO_NEXT_MEDIA_ITEM); + createWithPermanentAndSeekInCurrentCommands(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM); MediaItem mediaItem1 = createMediaItem(/* mediaQueueItemId= */ 1); MediaItem mediaItem2 = createMediaItem(/* mediaQueueItemId= */ 2); MediaItem mediaItem3 = createMediaItem(/* mediaQueueItemId= */ 3); @@ -1462,11 +1460,10 @@ public class CastPlayerTest { when(mockRemoteMediaClient.queueJumpToItem(anyInt(), anyLong(), eq(null))) .thenReturn(mockPendingResult); Player.Commands commandsWithoutSeek = createWithPermanentCommands(); - Player.Commands commandsWithSeekInCurrent = - createWithPermanentCommands(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM); + Player.Commands commandsWithSeekInCurrent = createWithPermanentAndSeekInCurrentCommands(); + ; Player.Commands commandsWithSeekInCurrentAndToPrevious = - createWithPermanentCommands( - COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM); + createWithPermanentAndSeekInCurrentCommands(COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM); MediaItem mediaItem1 = createMediaItem(/* mediaQueueItemId= */ 1); MediaItem mediaItem2 = createMediaItem(/* mediaQueueItemId= */ 2); MediaItem mediaItem3 = createMediaItem(/* mediaQueueItemId= */ 3); @@ -1506,11 +1503,9 @@ public class CastPlayerTest { @Test public void removeMediaItem_current_notifiesAvailableCommandsChanged() { - Player.Commands commandsWithSeekInCurrent = - createWithPermanentCommands(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM); + Player.Commands commandsWithSeekInCurrent = createWithPermanentAndSeekInCurrentCommands(); Player.Commands commandsWithSeekInCurrentAndToNext = - createWithPermanentCommands( - COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, COMMAND_SEEK_TO_NEXT_MEDIA_ITEM); + createWithPermanentAndSeekInCurrentCommands(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM); MediaItem mediaItem1 = createMediaItem(/* mediaQueueItemId= */ 1); MediaItem mediaItem2 = createMediaItem(/* mediaQueueItemId= */ 2); @@ -1536,13 +1531,11 @@ public class CastPlayerTest { public void setRepeatMode_all_notifiesAvailableCommandsChanged() { when(mockRemoteMediaClient.queueSetRepeatMode(anyInt(), eq(null))) .thenReturn(mockPendingResult); - Player.Commands commandsWithSeekInCurrent = - createWithPermanentCommands(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM); + Player.Commands commandsWithSeekInCurrent = createWithPermanentAndSeekInCurrentCommands(); + ; Player.Commands commandsWithSeekAnywhere = - createWithPermanentCommands( - COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, - COMMAND_SEEK_TO_NEXT_MEDIA_ITEM, - COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM); + createWithPermanentAndSeekInCurrentCommands( + COMMAND_SEEK_TO_NEXT_MEDIA_ITEM, COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM); int[] mediaQueueItemIds = new int[] {1}; List mediaItems = createMediaItems(mediaQueueItemIds); @@ -1561,8 +1554,8 @@ public class CastPlayerTest { public void setRepeatMode_one_doesNotNotifyAvailableCommandsChanged() { when(mockRemoteMediaClient.queueSetRepeatMode(anyInt(), eq(null))) .thenReturn(mockPendingResult); - Player.Commands commandsWithSeekInCurrent = - createWithPermanentCommands(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM); + Player.Commands commandsWithSeekInCurrent = createWithPermanentAndSeekInCurrentCommands(); + ; int[] mediaQueueItemIds = new int[] {1}; List mediaItems = createMediaItems(mediaQueueItemIds); @@ -1670,4 +1663,15 @@ public class CastPlayerTest { builder.addAll(additionalCommands); return builder.build(); } + + private static Player.Commands createWithPermanentAndSeekInCurrentCommands( + @Player.Command int... additionalCommands) { + Player.Commands.Builder builder = new Player.Commands.Builder(); + builder.addAll(CastPlayer.PERMANENT_AVAILABLE_COMMANDS); + builder.add(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM); + builder.add(COMMAND_FAST_FORWARD); + builder.add(COMMAND_REWIND); + builder.addAll(additionalCommands); + return builder.build(); + } } diff --git a/library/common/src/main/java/com/google/android/exoplayer2/BasePlayer.java b/library/common/src/main/java/com/google/android/exoplayer2/BasePlayer.java index 18fe8c72f0..5cb43e857b 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/BasePlayer.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/BasePlayer.java @@ -267,6 +267,8 @@ public abstract class BasePlayer implements Player { .addIf(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM, hasNext() && !isPlayingAd()) .addIf(COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM, hasPrevious() && !isPlayingAd()) .addIf(COMMAND_SEEK_TO_MEDIA_ITEM, !isPlayingAd()) + .addIf(COMMAND_FAST_FORWARD, isCurrentWindowSeekable() && !isPlayingAd()) + .addIf(COMMAND_REWIND, isCurrentWindowSeekable() && !isPlayingAd()) .build(); } diff --git a/library/common/src/main/java/com/google/android/exoplayer2/Player.java b/library/common/src/main/java/com/google/android/exoplayer2/Player.java index 1af138b715..b4ff733896 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/Player.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/Player.java @@ -594,6 +594,10 @@ public interface Player { COMMAND_SEEK_TO_NEXT_MEDIA_ITEM, COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM, COMMAND_SEEK_TO_MEDIA_ITEM, + COMMAND_SET_FAST_FORWARD_INCREMENT, + COMMAND_FAST_FORWARD, + COMMAND_SET_REWIND_INCREMENT, + COMMAND_REWIND, COMMAND_SET_SPEED_AND_PITCH, COMMAND_SET_SHUFFLE_MODE, COMMAND_SET_REPEAT_MODE, @@ -1108,14 +1112,15 @@ public interface Player { * #COMMAND_PREPARE_STOP}, {@link #COMMAND_SEEK_TO_DEFAULT_POSITION}, {@link * #COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM}, {@link #COMMAND_SEEK_TO_NEXT_MEDIA_ITEM}, {@link * #COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM}, {@link #COMMAND_SEEK_TO_MEDIA_ITEM}, {@link - * #COMMAND_SET_SPEED_AND_PITCH}, {@link #COMMAND_SET_SHUFFLE_MODE}, {@link - * #COMMAND_SET_REPEAT_MODE}, {@link #COMMAND_GET_CURRENT_MEDIA_ITEM}, {@link - * #COMMAND_GET_MEDIA_ITEMS}, {@link #COMMAND_GET_MEDIA_ITEMS_METADATA}, {@link - * #COMMAND_SET_MEDIA_ITEMS_METADATA}, {@link #COMMAND_CHANGE_MEDIA_ITEMS}, {@link - * #COMMAND_GET_AUDIO_ATTRIBUTES}, {@link #COMMAND_GET_VOLUME}, {@link - * #COMMAND_GET_DEVICE_VOLUME}, {@link #COMMAND_SET_VOLUME}, {@link #COMMAND_SET_DEVICE_VOLUME}, - * {@link #COMMAND_ADJUST_DEVICE_VOLUME}, {@link #COMMAND_SET_VIDEO_SURFACE} or {@link - * #COMMAND_GET_TEXT}. + * #COMMAND_SET_FAST_FORWARD_INCREMENT}, {@link #COMMAND_FAST_FORWARD}, {@link + * #COMMAND_SET_REWIND_INCREMENT}, {@link #COMMAND_REWIND}, {@link #COMMAND_SET_SPEED_AND_PITCH}, + * {@link #COMMAND_SET_SHUFFLE_MODE}, {@link #COMMAND_SET_REPEAT_MODE}, {@link + * #COMMAND_GET_CURRENT_MEDIA_ITEM}, {@link #COMMAND_GET_MEDIA_ITEMS}, {@link + * #COMMAND_GET_MEDIA_ITEMS_METADATA}, {@link #COMMAND_SET_MEDIA_ITEMS_METADATA}, {@link + * #COMMAND_CHANGE_MEDIA_ITEMS}, {@link #COMMAND_GET_AUDIO_ATTRIBUTES}, {@link + * #COMMAND_GET_VOLUME}, {@link #COMMAND_GET_DEVICE_VOLUME}, {@link #COMMAND_SET_VOLUME}, {@link + * #COMMAND_SET_DEVICE_VOLUME}, {@link #COMMAND_ADJUST_DEVICE_VOLUME}, {@link + * #COMMAND_SET_VIDEO_SURFACE} or {@link #COMMAND_GET_TEXT}. */ @Documented @Retention(RetentionPolicy.SOURCE) @@ -1128,6 +1133,10 @@ public interface Player { COMMAND_SEEK_TO_NEXT_MEDIA_ITEM, COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM, COMMAND_SEEK_TO_MEDIA_ITEM, + COMMAND_SET_FAST_FORWARD_INCREMENT, + COMMAND_FAST_FORWARD, + COMMAND_SET_REWIND_INCREMENT, + COMMAND_REWIND, COMMAND_SET_SPEED_AND_PITCH, COMMAND_SET_SHUFFLE_MODE, COMMAND_SET_REPEAT_MODE, @@ -1160,38 +1169,46 @@ public interface Player { int COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM = 6; /** Command to seek anywhere in any window. */ int COMMAND_SEEK_TO_MEDIA_ITEM = 7; + /** Command to set the fast forward increment. */ + int COMMAND_SET_FAST_FORWARD_INCREMENT = 8; + /** Command to fast forward into the current window. */ + int COMMAND_FAST_FORWARD = 9; + /** Command to set the rewind increment. */ + int COMMAND_SET_REWIND_INCREMENT = 10; + /** Command to rewind into the current window. */ + int COMMAND_REWIND = 11; /** Command to set the playback speed and pitch. */ - int COMMAND_SET_SPEED_AND_PITCH = 8; + int COMMAND_SET_SPEED_AND_PITCH = 12; /** Command to enable shuffling. */ - int COMMAND_SET_SHUFFLE_MODE = 9; + int COMMAND_SET_SHUFFLE_MODE = 13; /** Command to set the repeat mode. */ - int COMMAND_SET_REPEAT_MODE = 10; + int COMMAND_SET_REPEAT_MODE = 14; /** Command to get the {@link MediaItem} of the current window. */ - int COMMAND_GET_CURRENT_MEDIA_ITEM = 11; + int COMMAND_GET_CURRENT_MEDIA_ITEM = 15; /** Command to get the current timeline and its {@link MediaItem MediaItems}. */ - int COMMAND_GET_MEDIA_ITEMS = 12; + int COMMAND_GET_MEDIA_ITEMS = 16; /** Command to get the {@link MediaItem MediaItems} metadata. */ - int COMMAND_GET_MEDIA_ITEMS_METADATA = 13; + int COMMAND_GET_MEDIA_ITEMS_METADATA = 17; /** Command to set the {@link MediaItem MediaItems} metadata. */ - int COMMAND_SET_MEDIA_ITEMS_METADATA = 14; + int COMMAND_SET_MEDIA_ITEMS_METADATA = 18; /** Command to change the {@link MediaItem MediaItems} in the playlist. */ - int COMMAND_CHANGE_MEDIA_ITEMS = 15; + int COMMAND_CHANGE_MEDIA_ITEMS = 19; /** Command to get the player current {@link AudioAttributes}. */ - int COMMAND_GET_AUDIO_ATTRIBUTES = 16; + int COMMAND_GET_AUDIO_ATTRIBUTES = 20; /** Command to get the player volume. */ - int COMMAND_GET_VOLUME = 17; + int COMMAND_GET_VOLUME = 21; /** Command to get the device volume and whether it is muted. */ - int COMMAND_GET_DEVICE_VOLUME = 18; + int COMMAND_GET_DEVICE_VOLUME = 22; /** Command to set the player volume. */ - int COMMAND_SET_VOLUME = 19; + int COMMAND_SET_VOLUME = 23; /** Command to set the device volume and mute it. */ - int COMMAND_SET_DEVICE_VOLUME = 20; + int COMMAND_SET_DEVICE_VOLUME = 24; /** Command to increase and decrease the device volume and mute it. */ - int COMMAND_ADJUST_DEVICE_VOLUME = 21; + int COMMAND_ADJUST_DEVICE_VOLUME = 25; /** Command to set and clear the surface on which to render the video. */ - int COMMAND_SET_VIDEO_SURFACE = 22; + int COMMAND_SET_VIDEO_SURFACE = 26; /** Command to get the text that should currently be displayed by the player. */ - int COMMAND_GET_TEXT = 23; + int COMMAND_GET_TEXT = 27; /** Represents an invalid {@link Command}. */ int COMMAND_INVALID = -1; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java index cf7ac041ae..d46e9949cf 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java @@ -197,6 +197,8 @@ import java.util.concurrent.CopyOnWriteArraySet; .addAll( COMMAND_PLAY_PAUSE, COMMAND_PREPARE_STOP, + COMMAND_SET_FAST_FORWARD_INCREMENT, + COMMAND_SET_REWIND_INCREMENT, COMMAND_SET_SPEED_AND_PITCH, COMMAND_SET_SHUFFLE_MODE, COMMAND_SET_REPEAT_MODE, diff --git a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java index 3ce78d6cb8..8b8920f9fb 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer2; import static com.google.android.exoplayer2.Player.COMMAND_ADJUST_DEVICE_VOLUME; import static com.google.android.exoplayer2.Player.COMMAND_CHANGE_MEDIA_ITEMS; +import static com.google.android.exoplayer2.Player.COMMAND_FAST_FORWARD; import static com.google.android.exoplayer2.Player.COMMAND_GET_AUDIO_ATTRIBUTES; import static com.google.android.exoplayer2.Player.COMMAND_GET_CURRENT_MEDIA_ITEM; import static com.google.android.exoplayer2.Player.COMMAND_GET_DEVICE_VOLUME; @@ -26,14 +27,17 @@ import static com.google.android.exoplayer2.Player.COMMAND_GET_TEXT; import static com.google.android.exoplayer2.Player.COMMAND_GET_VOLUME; import static com.google.android.exoplayer2.Player.COMMAND_PLAY_PAUSE; import static com.google.android.exoplayer2.Player.COMMAND_PREPARE_STOP; +import static com.google.android.exoplayer2.Player.COMMAND_REWIND; import static com.google.android.exoplayer2.Player.COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM; import static com.google.android.exoplayer2.Player.COMMAND_SEEK_TO_DEFAULT_POSITION; import static com.google.android.exoplayer2.Player.COMMAND_SEEK_TO_MEDIA_ITEM; import static com.google.android.exoplayer2.Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM; import static com.google.android.exoplayer2.Player.COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM; import static com.google.android.exoplayer2.Player.COMMAND_SET_DEVICE_VOLUME; +import static com.google.android.exoplayer2.Player.COMMAND_SET_FAST_FORWARD_INCREMENT; import static com.google.android.exoplayer2.Player.COMMAND_SET_MEDIA_ITEMS_METADATA; import static com.google.android.exoplayer2.Player.COMMAND_SET_REPEAT_MODE; +import static com.google.android.exoplayer2.Player.COMMAND_SET_REWIND_INCREMENT; import static com.google.android.exoplayer2.Player.COMMAND_SET_SHUFFLE_MODE; import static com.google.android.exoplayer2.Player.COMMAND_SET_SPEED_AND_PITCH; import static com.google.android.exoplayer2.Player.COMMAND_SET_VIDEO_SURFACE; @@ -8130,6 +8134,10 @@ public final class ExoPlayerTest { assertThat(player.isCommandAvailable(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM)).isTrue(); assertThat(player.isCommandAvailable(COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM)).isFalse(); assertThat(player.isCommandAvailable(COMMAND_SEEK_TO_MEDIA_ITEM)).isTrue(); + assertThat(player.isCommandAvailable(COMMAND_SET_FAST_FORWARD_INCREMENT)).isTrue(); + assertThat(player.isCommandAvailable(COMMAND_FAST_FORWARD)).isFalse(); + assertThat(player.isCommandAvailable(COMMAND_SET_REWIND_INCREMENT)).isTrue(); + assertThat(player.isCommandAvailable(COMMAND_REWIND)).isFalse(); assertThat(player.isCommandAvailable(COMMAND_SET_SPEED_AND_PITCH)).isTrue(); assertThat(player.isCommandAvailable(COMMAND_SET_SHUFFLE_MODE)).isTrue(); assertThat(player.isCommandAvailable(COMMAND_SET_REPEAT_MODE)).isTrue(); @@ -8177,10 +8185,13 @@ public final class ExoPlayerTest { assertThat(player.isCommandAvailable(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM)).isFalse(); assertThat(player.isCommandAvailable(COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM)).isFalse(); assertThat(player.isCommandAvailable(COMMAND_SEEK_TO_MEDIA_ITEM)).isFalse(); + assertThat(player.isCommandAvailable(COMMAND_FAST_FORWARD)).isFalse(); + assertThat(player.isCommandAvailable(COMMAND_REWIND)).isFalse(); } @Test - public void isCommandAvailable_duringUnseekableItem_isFalseForSeekInCurrent() throws Exception { + public void isCommandAvailable_duringUnseekableItem_isFalseForSeekInCurrentCommands() + throws Exception { Timeline timelineWithUnseekableWindow = new FakeTimeline( new TimelineWindowDefinition( @@ -8194,6 +8205,8 @@ public final class ExoPlayerTest { runUntilPlaybackState(player, Player.STATE_READY); assertThat(player.isCommandAvailable(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM)).isFalse(); + assertThat(player.isCommandAvailable(COMMAND_FAST_FORWARD)).isFalse(); + assertThat(player.isCommandAvailable(COMMAND_REWIND)).isFalse(); } @Test @@ -8285,13 +8298,21 @@ public final class ExoPlayerTest { createWithDefaultCommands(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM); Player.Commands commandsWithSeekInCurrentAndToNext = createWithDefaultCommands( - COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, COMMAND_SEEK_TO_NEXT_MEDIA_ITEM); + COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, + COMMAND_FAST_FORWARD, + COMMAND_REWIND, + COMMAND_SEEK_TO_NEXT_MEDIA_ITEM); Player.Commands commandsWithSeekInCurrentAndToPrevious = createWithDefaultCommands( - COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM); + COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, + COMMAND_FAST_FORWARD, + COMMAND_REWIND, + COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM); Player.Commands commandsWithSeekAnywhere = createWithDefaultCommands( COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, + COMMAND_FAST_FORWARD, + COMMAND_REWIND, COMMAND_SEEK_TO_NEXT_MEDIA_ITEM, COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM); Player.Listener mockListener = mock(Player.Listener.class); @@ -10682,6 +10703,8 @@ public final class ExoPlayerTest { builder.addAll( COMMAND_PLAY_PAUSE, COMMAND_PREPARE_STOP, + COMMAND_SET_FAST_FORWARD_INCREMENT, + COMMAND_SET_REWIND_INCREMENT, COMMAND_SET_SPEED_AND_PITCH, COMMAND_SET_SHUFFLE_MODE, COMMAND_SET_REPEAT_MODE,