Make availableCommands known when bundling PlayerInfo
When bundling PlayerInfo, we remove data when the controller is not allowed to access this data via getters. We also remove data for performance reasons. In the toBundle() method, it's currently hard to make the connection between allowed commands and filtering, because the values are checked at a different place. This can be made more readable by forwarding the applicable Commands directly. The only functional fix is to filter the Timeline when sending the first PlayerInfo after a connecting a controller if the command to get the Timeline is not available. This also allows us to remove a path to filter MediaItems from Timelines as it isn't used. PiperOrigin-RevId: 502607391
This commit is contained in:
parent
a3b0708d31
commit
c90ca7ba5f
@ -430,18 +430,17 @@ public abstract class Timeline implements Bundleable {
|
|||||||
private static final String FIELD_POSITION_IN_FIRST_PERIOD_US = Util.intToStringMaxRadix(13);
|
private static final String FIELD_POSITION_IN_FIRST_PERIOD_US = Util.intToStringMaxRadix(13);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@link Bundle} representing the information stored in this object.
|
* {@inheritDoc}
|
||||||
*
|
*
|
||||||
* <p>It omits the {@link #uid} and {@link #manifest} fields. The {@link #uid} of an instance
|
* <p>It omits the {@link #uid} and {@link #manifest} fields. The {@link #uid} of an instance
|
||||||
* restored by {@link #CREATOR} will be a fake {@link Object} and the {@link #manifest} of the
|
* restored by {@link #CREATOR} will be a fake {@link Object} and the {@link #manifest} of the
|
||||||
* instance will be {@code null}.
|
* instance will be {@code null}.
|
||||||
*
|
|
||||||
* @param excludeMediaItem Whether to exclude {@link #mediaItem} of window.
|
|
||||||
*/
|
*/
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
public Bundle toBundle(boolean excludeMediaItem) {
|
@Override
|
||||||
|
public Bundle toBundle() {
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
if (!excludeMediaItem) {
|
if (!MediaItem.EMPTY.equals(mediaItem)) {
|
||||||
bundle.putBundle(FIELD_MEDIA_ITEM, mediaItem.toBundle());
|
bundle.putBundle(FIELD_MEDIA_ITEM, mediaItem.toBundle());
|
||||||
}
|
}
|
||||||
if (presentationStartTimeMs != C.TIME_UNSET) {
|
if (presentationStartTimeMs != C.TIME_UNSET) {
|
||||||
@ -485,20 +484,6 @@ public abstract class Timeline implements Bundleable {
|
|||||||
return bundle;
|
return bundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*
|
|
||||||
* <p>It omits the {@link #uid} and {@link #manifest} fields. The {@link #uid} of an instance
|
|
||||||
* restored by {@link #CREATOR} will be a fake {@link Object} and the {@link #manifest} of the
|
|
||||||
* instance will be {@code null}.
|
|
||||||
*/
|
|
||||||
// TODO(b/166765820): See if missing fields would be okay and add them to the Bundle otherwise.
|
|
||||||
@UnstableApi
|
|
||||||
@Override
|
|
||||||
public Bundle toBundle() {
|
|
||||||
return toBundle(/* excludeMediaItem= */ false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object that can restore {@link Period} from a {@link Bundle}.
|
* Object that can restore {@link Period} from a {@link Bundle}.
|
||||||
*
|
*
|
||||||
@ -1396,18 +1381,15 @@ public abstract class Timeline implements Bundleable {
|
|||||||
* <p>The {@link #getWindow(int, Window)} windows} and {@link #getPeriod(int, Period) periods} of
|
* <p>The {@link #getWindow(int, Window)} windows} and {@link #getPeriod(int, Period) periods} of
|
||||||
* an instance restored by {@link #CREATOR} may have missing fields as described in {@link
|
* an instance restored by {@link #CREATOR} may have missing fields as described in {@link
|
||||||
* Window#toBundle()} and {@link Period#toBundle()}.
|
* Window#toBundle()} and {@link Period#toBundle()}.
|
||||||
*
|
|
||||||
* @param excludeMediaItems Whether to exclude all {@link Window#mediaItem media items} of windows
|
|
||||||
* in the timeline.
|
|
||||||
*/
|
*/
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
public final Bundle toBundle(boolean excludeMediaItems) {
|
@Override
|
||||||
|
public final Bundle toBundle() {
|
||||||
List<Bundle> windowBundles = new ArrayList<>();
|
List<Bundle> windowBundles = new ArrayList<>();
|
||||||
int windowCount = getWindowCount();
|
int windowCount = getWindowCount();
|
||||||
Window window = new Window();
|
Window window = new Window();
|
||||||
for (int i = 0; i < windowCount; i++) {
|
for (int i = 0; i < windowCount; i++) {
|
||||||
windowBundles.add(
|
windowBundles.add(getWindow(i, window, /* defaultPositionProjectionUs= */ 0).toBundle());
|
||||||
getWindow(i, window, /* defaultPositionProjectionUs= */ 0).toBundle(excludeMediaItems));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Bundle> periodBundles = new ArrayList<>();
|
List<Bundle> periodBundles = new ArrayList<>();
|
||||||
@ -1434,19 +1416,6 @@ public abstract class Timeline implements Bundleable {
|
|||||||
return bundle;
|
return bundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*
|
|
||||||
* <p>The {@link #getWindow(int, Window)} windows} and {@link #getPeriod(int, Period) periods} of
|
|
||||||
* an instance restored by {@link #CREATOR} may have missing fields as described in {@link
|
|
||||||
* Window#toBundle()} and {@link Period#toBundle()}.
|
|
||||||
*/
|
|
||||||
@UnstableApi
|
|
||||||
@Override
|
|
||||||
public final Bundle toBundle() {
|
|
||||||
return toBundle(/* excludeMediaItems= */ false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object that can restore a {@link Timeline} from a {@link Bundle}.
|
* Object that can restore a {@link Timeline} from a {@link Bundle}.
|
||||||
*
|
*
|
||||||
|
@ -350,10 +350,8 @@ public class TimelineTest {
|
|||||||
|
|
||||||
Bundle windowBundle = window.toBundle();
|
Bundle windowBundle = window.toBundle();
|
||||||
|
|
||||||
// Check that default values are skipped when bundling. MediaItem key is not added to the bundle
|
// Check that default values are skipped when bundling.
|
||||||
// only when excludeMediaItem is true.
|
assertThat(windowBundle.keySet()).isEmpty();
|
||||||
assertThat(windowBundle.keySet()).hasSize(1);
|
|
||||||
assertThat(window.toBundle(/* excludeMediaItem= */ true).keySet()).isEmpty();
|
|
||||||
|
|
||||||
Timeline.Window restoredWindow = Timeline.Window.CREATOR.fromBundle(windowBundle);
|
Timeline.Window restoredWindow = Timeline.Window.CREATOR.fromBundle(windowBundle);
|
||||||
|
|
||||||
|
@ -94,19 +94,12 @@ import androidx.media3.common.util.Util;
|
|||||||
bundle.putBundle(FIELD_PLAYER_COMMANDS_FROM_SESSION, playerCommandsFromSession.toBundle());
|
bundle.putBundle(FIELD_PLAYER_COMMANDS_FROM_SESSION, playerCommandsFromSession.toBundle());
|
||||||
bundle.putBundle(FIELD_PLAYER_COMMANDS_FROM_PLAYER, playerCommandsFromPlayer.toBundle());
|
bundle.putBundle(FIELD_PLAYER_COMMANDS_FROM_PLAYER, playerCommandsFromPlayer.toBundle());
|
||||||
bundle.putBundle(FIELD_TOKEN_EXTRAS, tokenExtras);
|
bundle.putBundle(FIELD_TOKEN_EXTRAS, tokenExtras);
|
||||||
|
Player.Commands intersectedCommands =
|
||||||
|
MediaUtils.intersect(playerCommandsFromSession, playerCommandsFromPlayer);
|
||||||
bundle.putBundle(
|
bundle.putBundle(
|
||||||
FIELD_PLAYER_INFO,
|
FIELD_PLAYER_INFO,
|
||||||
playerInfo.toBundle(
|
playerInfo.toBundle(
|
||||||
/* excludeMediaItems= */ !playerCommandsFromPlayer.contains(Player.COMMAND_GET_TIMELINE)
|
intersectedCommands, /* excludeTimeline= */ false, /* excludeTracks= */ false));
|
||||||
|| !playerCommandsFromSession.contains(Player.COMMAND_GET_TIMELINE),
|
|
||||||
/* excludeMediaItemsMetadata= */ !playerCommandsFromPlayer.contains(
|
|
||||||
Player.COMMAND_GET_MEDIA_ITEMS_METADATA)
|
|
||||||
|| !playerCommandsFromSession.contains(Player.COMMAND_GET_MEDIA_ITEMS_METADATA),
|
|
||||||
/* excludeCues= */ !playerCommandsFromPlayer.contains(Player.COMMAND_GET_TEXT)
|
|
||||||
|| !playerCommandsFromSession.contains(Player.COMMAND_GET_TEXT),
|
|
||||||
/* excludeTimeline= */ false,
|
|
||||||
/* excludeTracks= */ !playerCommandsFromPlayer.contains(Player.COMMAND_GET_TRACKS)
|
|
||||||
|| !playerCommandsFromSession.contains(Player.COMMAND_GET_TRACKS)));
|
|
||||||
bundle.putInt(FIELD_SESSION_INTERFACE_VERSION, sessionInterfaceVersion);
|
bundle.putInt(FIELD_SESSION_INTERFACE_VERSION, sessionInterfaceVersion);
|
||||||
return bundle;
|
return bundle;
|
||||||
}
|
}
|
||||||
|
@ -1156,9 +1156,7 @@ public class MediaSession {
|
|||||||
default void onPlayerInfoChanged(
|
default void onPlayerInfoChanged(
|
||||||
int seq,
|
int seq,
|
||||||
PlayerInfo playerInfo,
|
PlayerInfo playerInfo,
|
||||||
boolean excludeMediaItems,
|
Player.Commands availableCommands,
|
||||||
boolean excludeMediaItemsMetadata,
|
|
||||||
boolean excludeCues,
|
|
||||||
boolean excludeTimeline,
|
boolean excludeTimeline,
|
||||||
boolean excludeTracks,
|
boolean excludeTracks,
|
||||||
int controllerInterfaceVersion)
|
int controllerInterfaceVersion)
|
||||||
|
@ -15,9 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package androidx.media3.session;
|
package androidx.media3.session;
|
||||||
|
|
||||||
import static androidx.media3.common.Player.COMMAND_GET_MEDIA_ITEMS_METADATA;
|
|
||||||
import static androidx.media3.common.Player.COMMAND_GET_TEXT;
|
|
||||||
import static androidx.media3.common.Player.COMMAND_GET_TIMELINE;
|
|
||||||
import static androidx.media3.common.Player.COMMAND_GET_TRACKS;
|
import static androidx.media3.common.Player.COMMAND_GET_TRACKS;
|
||||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||||
import static androidx.media3.common.util.Assertions.checkStateNotNull;
|
import static androidx.media3.common.util.Assertions.checkStateNotNull;
|
||||||
@ -417,21 +414,17 @@ import org.checkerframework.checker.initialization.qual.Initialized;
|
|||||||
// 0 is OK for legacy controllers, because they didn't have sequence numbers.
|
// 0 is OK for legacy controllers, because they didn't have sequence numbers.
|
||||||
seq = 0;
|
seq = 0;
|
||||||
}
|
}
|
||||||
|
Player.Commands intersectedCommands =
|
||||||
|
MediaUtils.intersect(
|
||||||
|
controllersManager.getAvailablePlayerCommands(controller),
|
||||||
|
getPlayerWrapper().getAvailableCommands());
|
||||||
checkStateNotNull(controller.getControllerCb())
|
checkStateNotNull(controller.getControllerCb())
|
||||||
.onPlayerInfoChanged(
|
.onPlayerInfoChanged(
|
||||||
seq,
|
seq,
|
||||||
playerInfo,
|
playerInfo,
|
||||||
/* excludeMediaItems= */ !controllersManager.isPlayerCommandAvailable(
|
intersectedCommands,
|
||||||
controller, COMMAND_GET_TIMELINE),
|
excludeTimeline,
|
||||||
/* excludeMediaItemsMetadata= */ !controllersManager.isPlayerCommandAvailable(
|
excludeTracks,
|
||||||
controller, COMMAND_GET_MEDIA_ITEMS_METADATA),
|
|
||||||
/* excludeCues= */ !controllersManager.isPlayerCommandAvailable(
|
|
||||||
controller, COMMAND_GET_TEXT),
|
|
||||||
excludeTimeline
|
|
||||||
|| !controllersManager.isPlayerCommandAvailable(
|
|
||||||
controller, COMMAND_GET_TIMELINE),
|
|
||||||
excludeTracks
|
|
||||||
|| !controllersManager.isPlayerCommandAvailable(controller, COMMAND_GET_TRACKS),
|
|
||||||
controller.getInterfaceVersion());
|
controller.getInterfaceVersion());
|
||||||
} catch (DeadObjectException e) {
|
} catch (DeadObjectException e) {
|
||||||
onDeadObjectException(controller);
|
onDeadObjectException(controller);
|
||||||
|
@ -1606,35 +1606,29 @@ import java.util.concurrent.ExecutionException;
|
|||||||
public void onPlayerInfoChanged(
|
public void onPlayerInfoChanged(
|
||||||
int sequenceNumber,
|
int sequenceNumber,
|
||||||
PlayerInfo playerInfo,
|
PlayerInfo playerInfo,
|
||||||
boolean excludeMediaItems,
|
Player.Commands availableCommands,
|
||||||
boolean excludeMediaItemsMetadata,
|
|
||||||
boolean excludeCues,
|
|
||||||
boolean excludeTimeline,
|
boolean excludeTimeline,
|
||||||
boolean excludeTracks,
|
boolean excludeTracks,
|
||||||
int controllerInterfaceVersion)
|
int controllerInterfaceVersion)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
Assertions.checkState(controllerInterfaceVersion != 0);
|
Assertions.checkState(controllerInterfaceVersion != 0);
|
||||||
|
// The bundling exclusions merge the performance overrides with the available commands.
|
||||||
|
boolean bundlingExclusionsTimeline =
|
||||||
|
excludeTimeline || !availableCommands.contains(Player.COMMAND_GET_TIMELINE);
|
||||||
|
boolean bundlingExclusionsTracks =
|
||||||
|
excludeTracks || !availableCommands.contains(Player.COMMAND_GET_TRACKS);
|
||||||
if (controllerInterfaceVersion >= 2) {
|
if (controllerInterfaceVersion >= 2) {
|
||||||
iController.onPlayerInfoChangedWithExclusions(
|
iController.onPlayerInfoChangedWithExclusions(
|
||||||
sequenceNumber,
|
sequenceNumber,
|
||||||
playerInfo.toBundle(
|
playerInfo.toBundle(availableCommands, excludeTimeline, excludeTracks),
|
||||||
excludeMediaItems,
|
new PlayerInfo.BundlingExclusions(bundlingExclusionsTimeline, bundlingExclusionsTracks)
|
||||||
excludeMediaItemsMetadata,
|
.toBundle());
|
||||||
excludeCues,
|
|
||||||
excludeTimeline,
|
|
||||||
excludeTracks),
|
|
||||||
new PlayerInfo.BundlingExclusions(excludeTimeline, excludeTracks).toBundle());
|
|
||||||
} else {
|
} else {
|
||||||
//noinspection deprecation
|
//noinspection deprecation
|
||||||
iController.onPlayerInfoChanged(
|
iController.onPlayerInfoChanged(
|
||||||
sequenceNumber,
|
sequenceNumber,
|
||||||
playerInfo.toBundle(
|
playerInfo.toBundle(availableCommands, excludeTimeline, /* excludeTracks= */ true),
|
||||||
excludeMediaItems,
|
bundlingExclusionsTimeline);
|
||||||
excludeMediaItemsMetadata,
|
|
||||||
excludeCues,
|
|
||||||
excludeTimeline,
|
|
||||||
/* excludeTracks= */ true),
|
|
||||||
excludeTimeline);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1292,7 +1292,10 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
* Returns the intersection of {@link Player.Command commands} from the given two {@link
|
* Returns the intersection of {@link Player.Command commands} from the given two {@link
|
||||||
* Commands}.
|
* Commands}.
|
||||||
*/
|
*/
|
||||||
public static Commands intersect(Commands commands1, Commands commands2) {
|
public static Commands intersect(@Nullable Commands commands1, @Nullable Commands commands2) {
|
||||||
|
if (commands1 == null || commands2 == null) {
|
||||||
|
return Commands.EMPTY;
|
||||||
|
}
|
||||||
Commands.Builder intersectCommandsBuilder = new Commands.Builder();
|
Commands.Builder intersectCommandsBuilder = new Commands.Builder();
|
||||||
for (int i = 0; i < commands1.size(); i++) {
|
for (int i = 0; i < commands1.size(); i++) {
|
||||||
if (commands2.contains(commands1.get(i))) {
|
if (commands2.contains(commands1.get(i))) {
|
||||||
|
@ -799,11 +799,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
|||||||
// Next field key = 31
|
// Next field key = 31
|
||||||
|
|
||||||
public Bundle toBundle(
|
public Bundle toBundle(
|
||||||
boolean excludeMediaItems,
|
Player.Commands availableCommands, boolean excludeTimeline, boolean excludeTracks) {
|
||||||
boolean excludeMediaItemsMetadata,
|
|
||||||
boolean excludeCues,
|
|
||||||
boolean excludeTimeline,
|
|
||||||
boolean excludeTracks) {
|
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
if (playerError != null) {
|
if (playerError != null) {
|
||||||
bundle.putBundle(FIELD_PLAYBACK_ERROR, playerError.toBundle());
|
bundle.putBundle(FIELD_PLAYBACK_ERROR, playerError.toBundle());
|
||||||
@ -816,16 +812,16 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
|||||||
bundle.putBundle(FIELD_PLAYBACK_PARAMETERS, playbackParameters.toBundle());
|
bundle.putBundle(FIELD_PLAYBACK_PARAMETERS, playbackParameters.toBundle());
|
||||||
bundle.putInt(FIELD_REPEAT_MODE, repeatMode);
|
bundle.putInt(FIELD_REPEAT_MODE, repeatMode);
|
||||||
bundle.putBoolean(FIELD_SHUFFLE_MODE_ENABLED, shuffleModeEnabled);
|
bundle.putBoolean(FIELD_SHUFFLE_MODE_ENABLED, shuffleModeEnabled);
|
||||||
if (!excludeTimeline) {
|
if (!excludeTimeline && availableCommands.contains(Player.COMMAND_GET_TIMELINE)) {
|
||||||
bundle.putBundle(FIELD_TIMELINE, timeline.toBundle(excludeMediaItems));
|
bundle.putBundle(FIELD_TIMELINE, timeline.toBundle());
|
||||||
}
|
}
|
||||||
bundle.putBundle(FIELD_VIDEO_SIZE, videoSize.toBundle());
|
bundle.putBundle(FIELD_VIDEO_SIZE, videoSize.toBundle());
|
||||||
if (!excludeMediaItemsMetadata) {
|
if (availableCommands.contains(Player.COMMAND_GET_MEDIA_ITEMS_METADATA)) {
|
||||||
bundle.putBundle(FIELD_PLAYLIST_METADATA, playlistMetadata.toBundle());
|
bundle.putBundle(FIELD_PLAYLIST_METADATA, playlistMetadata.toBundle());
|
||||||
}
|
}
|
||||||
bundle.putFloat(FIELD_VOLUME, volume);
|
bundle.putFloat(FIELD_VOLUME, volume);
|
||||||
bundle.putBundle(FIELD_AUDIO_ATTRIBUTES, audioAttributes.toBundle());
|
bundle.putBundle(FIELD_AUDIO_ATTRIBUTES, audioAttributes.toBundle());
|
||||||
if (!excludeCues) {
|
if (availableCommands.contains(Player.COMMAND_GET_TEXT)) {
|
||||||
bundle.putBundle(FIELD_CUE_GROUP, cueGroup.toBundle());
|
bundle.putBundle(FIELD_CUE_GROUP, cueGroup.toBundle());
|
||||||
}
|
}
|
||||||
bundle.putBundle(FIELD_DEVICE_INFO, deviceInfo.toBundle());
|
bundle.putBundle(FIELD_DEVICE_INFO, deviceInfo.toBundle());
|
||||||
@ -836,13 +832,13 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
|||||||
bundle.putInt(FIELD_PLAYBACK_STATE, playbackState);
|
bundle.putInt(FIELD_PLAYBACK_STATE, playbackState);
|
||||||
bundle.putBoolean(FIELD_IS_PLAYING, isPlaying);
|
bundle.putBoolean(FIELD_IS_PLAYING, isPlaying);
|
||||||
bundle.putBoolean(FIELD_IS_LOADING, isLoading);
|
bundle.putBoolean(FIELD_IS_LOADING, isLoading);
|
||||||
bundle.putBundle(
|
if (availableCommands.contains(Player.COMMAND_GET_TIMELINE)) {
|
||||||
FIELD_MEDIA_METADATA,
|
bundle.putBundle(FIELD_MEDIA_METADATA, mediaMetadata.toBundle());
|
||||||
excludeMediaItems ? MediaMetadata.EMPTY.toBundle() : mediaMetadata.toBundle());
|
}
|
||||||
bundle.putLong(FIELD_SEEK_BACK_INCREMENT_MS, seekBackIncrementMs);
|
bundle.putLong(FIELD_SEEK_BACK_INCREMENT_MS, seekBackIncrementMs);
|
||||||
bundle.putLong(FIELD_SEEK_FORWARD_INCREMENT_MS, seekForwardIncrementMs);
|
bundle.putLong(FIELD_SEEK_FORWARD_INCREMENT_MS, seekForwardIncrementMs);
|
||||||
bundle.putLong(FIELD_MAX_SEEK_TO_PREVIOUS_POSITION_MS, maxSeekToPreviousPositionMs);
|
bundle.putLong(FIELD_MAX_SEEK_TO_PREVIOUS_POSITION_MS, maxSeekToPreviousPositionMs);
|
||||||
if (!excludeTracks) {
|
if (!excludeTracks && availableCommands.contains(Player.COMMAND_GET_TRACKS)) {
|
||||||
bundle.putBundle(FIELD_CURRENT_TRACKS, currentTracks.toBundle());
|
bundle.putBundle(FIELD_CURRENT_TRACKS, currentTracks.toBundle());
|
||||||
}
|
}
|
||||||
bundle.putBundle(FIELD_TRACK_SELECTION_PARAMETERS, trackSelectionParameters.toBundle());
|
bundle.putBundle(FIELD_TRACK_SELECTION_PARAMETERS, trackSelectionParameters.toBundle());
|
||||||
@ -853,9 +849,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
|||||||
@Override
|
@Override
|
||||||
public Bundle toBundle() {
|
public Bundle toBundle() {
|
||||||
return toBundle(
|
return toBundle(
|
||||||
/* excludeMediaItems= */ false,
|
/* availableCommands= */ new Player.Commands.Builder().addAllCommands().build(),
|
||||||
/* excludeMediaItemsMetadata= */ false,
|
|
||||||
/* excludeCues= */ false,
|
|
||||||
/* excludeTimeline= */ false,
|
/* excludeTimeline= */ false,
|
||||||
/* excludeTracks= */ false);
|
/* excludeTracks= */ false);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user