diff --git a/libraries/common/src/main/java/androidx/media3/common/Timeline.java b/libraries/common/src/main/java/androidx/media3/common/Timeline.java index 8e37968a0c..1d7706f907 100644 --- a/libraries/common/src/main/java/androidx/media3/common/Timeline.java +++ b/libraries/common/src/main/java/androidx/media3/common/Timeline.java @@ -430,18 +430,17 @@ public abstract class Timeline implements Bundleable { 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} * *
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}. - * - * @param excludeMediaItem Whether to exclude {@link #mediaItem} of window. */ @UnstableApi - public Bundle toBundle(boolean excludeMediaItem) { + @Override + public Bundle toBundle() { Bundle bundle = new Bundle(); - if (!excludeMediaItem) { + if (!MediaItem.EMPTY.equals(mediaItem)) { bundle.putBundle(FIELD_MEDIA_ITEM, mediaItem.toBundle()); } if (presentationStartTimeMs != C.TIME_UNSET) { @@ -485,20 +484,6 @@ public abstract class Timeline implements Bundleable { return bundle; } - /** - * {@inheritDoc} - * - *
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}. * @@ -1396,18 +1381,15 @@ public abstract class Timeline implements Bundleable { *
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()}.
- *
- * @param excludeMediaItems Whether to exclude all {@link Window#mediaItem media items} of windows
- * in the timeline.
*/
@UnstableApi
- public final Bundle toBundle(boolean excludeMediaItems) {
+ @Override
+ public final Bundle toBundle() {
List 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}.
*
diff --git a/libraries/common/src/test/java/androidx/media3/common/TimelineTest.java b/libraries/common/src/test/java/androidx/media3/common/TimelineTest.java
index 111652b38b..716e16ec3c 100644
--- a/libraries/common/src/test/java/androidx/media3/common/TimelineTest.java
+++ b/libraries/common/src/test/java/androidx/media3/common/TimelineTest.java
@@ -350,10 +350,8 @@ public class TimelineTest {
Bundle windowBundle = window.toBundle();
- // Check that default values are skipped when bundling. MediaItem key is not added to the bundle
- // only when excludeMediaItem is true.
- assertThat(windowBundle.keySet()).hasSize(1);
- assertThat(window.toBundle(/* excludeMediaItem= */ true).keySet()).isEmpty();
+ // Check that default values are skipped when bundling.
+ assertThat(windowBundle.keySet()).isEmpty();
Timeline.Window restoredWindow = Timeline.Window.CREATOR.fromBundle(windowBundle);
diff --git a/libraries/session/src/main/java/androidx/media3/session/ConnectionState.java b/libraries/session/src/main/java/androidx/media3/session/ConnectionState.java
index 113848eda0..c681ab4420 100644
--- a/libraries/session/src/main/java/androidx/media3/session/ConnectionState.java
+++ b/libraries/session/src/main/java/androidx/media3/session/ConnectionState.java
@@ -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_PLAYER, playerCommandsFromPlayer.toBundle());
bundle.putBundle(FIELD_TOKEN_EXTRAS, tokenExtras);
+ Player.Commands intersectedCommands =
+ MediaUtils.intersect(playerCommandsFromSession, playerCommandsFromPlayer);
bundle.putBundle(
FIELD_PLAYER_INFO,
playerInfo.toBundle(
- /* excludeMediaItems= */ !playerCommandsFromPlayer.contains(Player.COMMAND_GET_TIMELINE)
- || !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)));
+ intersectedCommands, /* excludeTimeline= */ false, /* excludeTracks= */ false));
bundle.putInt(FIELD_SESSION_INTERFACE_VERSION, sessionInterfaceVersion);
return bundle;
}
diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaSession.java b/libraries/session/src/main/java/androidx/media3/session/MediaSession.java
index 44af689db4..29b57bd0c5 100644
--- a/libraries/session/src/main/java/androidx/media3/session/MediaSession.java
+++ b/libraries/session/src/main/java/androidx/media3/session/MediaSession.java
@@ -1156,9 +1156,7 @@ public class MediaSession {
default void onPlayerInfoChanged(
int seq,
PlayerInfo playerInfo,
- boolean excludeMediaItems,
- boolean excludeMediaItemsMetadata,
- boolean excludeCues,
+ Player.Commands availableCommands,
boolean excludeTimeline,
boolean excludeTracks,
int controllerInterfaceVersion)
diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaSessionImpl.java b/libraries/session/src/main/java/androidx/media3/session/MediaSessionImpl.java
index 9803450241..b5ab1b28c1 100644
--- a/libraries/session/src/main/java/androidx/media3/session/MediaSessionImpl.java
+++ b/libraries/session/src/main/java/androidx/media3/session/MediaSessionImpl.java
@@ -15,9 +15,6 @@
*/
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.util.Assertions.checkNotNull;
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.
seq = 0;
}
+ Player.Commands intersectedCommands =
+ MediaUtils.intersect(
+ controllersManager.getAvailablePlayerCommands(controller),
+ getPlayerWrapper().getAvailableCommands());
checkStateNotNull(controller.getControllerCb())
.onPlayerInfoChanged(
seq,
playerInfo,
- /* excludeMediaItems= */ !controllersManager.isPlayerCommandAvailable(
- controller, COMMAND_GET_TIMELINE),
- /* excludeMediaItemsMetadata= */ !controllersManager.isPlayerCommandAvailable(
- 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),
+ intersectedCommands,
+ excludeTimeline,
+ excludeTracks,
controller.getInterfaceVersion());
} catch (DeadObjectException e) {
onDeadObjectException(controller);
diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaSessionStub.java b/libraries/session/src/main/java/androidx/media3/session/MediaSessionStub.java
index aa51cb519c..1cbb8106d5 100644
--- a/libraries/session/src/main/java/androidx/media3/session/MediaSessionStub.java
+++ b/libraries/session/src/main/java/androidx/media3/session/MediaSessionStub.java
@@ -1606,35 +1606,29 @@ import java.util.concurrent.ExecutionException;
public void onPlayerInfoChanged(
int sequenceNumber,
PlayerInfo playerInfo,
- boolean excludeMediaItems,
- boolean excludeMediaItemsMetadata,
- boolean excludeCues,
+ Player.Commands availableCommands,
boolean excludeTimeline,
boolean excludeTracks,
int controllerInterfaceVersion)
throws RemoteException {
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) {
iController.onPlayerInfoChangedWithExclusions(
sequenceNumber,
- playerInfo.toBundle(
- excludeMediaItems,
- excludeMediaItemsMetadata,
- excludeCues,
- excludeTimeline,
- excludeTracks),
- new PlayerInfo.BundlingExclusions(excludeTimeline, excludeTracks).toBundle());
+ playerInfo.toBundle(availableCommands, excludeTimeline, excludeTracks),
+ new PlayerInfo.BundlingExclusions(bundlingExclusionsTimeline, bundlingExclusionsTracks)
+ .toBundle());
} else {
//noinspection deprecation
iController.onPlayerInfoChanged(
sequenceNumber,
- playerInfo.toBundle(
- excludeMediaItems,
- excludeMediaItemsMetadata,
- excludeCues,
- excludeTimeline,
- /* excludeTracks= */ true),
- excludeTimeline);
+ playerInfo.toBundle(availableCommands, excludeTimeline, /* excludeTracks= */ true),
+ bundlingExclusionsTimeline);
}
}
diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaUtils.java b/libraries/session/src/main/java/androidx/media3/session/MediaUtils.java
index 716f08a29d..0d61696904 100644
--- a/libraries/session/src/main/java/androidx/media3/session/MediaUtils.java
+++ b/libraries/session/src/main/java/androidx/media3/session/MediaUtils.java
@@ -1292,7 +1292,10 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
* Returns the intersection of {@link Player.Command commands} from the given two {@link
* 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();
for (int i = 0; i < commands1.size(); i++) {
if (commands2.contains(commands1.get(i))) {
diff --git a/libraries/session/src/main/java/androidx/media3/session/PlayerInfo.java b/libraries/session/src/main/java/androidx/media3/session/PlayerInfo.java
index 6caf4b48f9..85ff904b80 100644
--- a/libraries/session/src/main/java/androidx/media3/session/PlayerInfo.java
+++ b/libraries/session/src/main/java/androidx/media3/session/PlayerInfo.java
@@ -799,11 +799,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
// Next field key = 31
public Bundle toBundle(
- boolean excludeMediaItems,
- boolean excludeMediaItemsMetadata,
- boolean excludeCues,
- boolean excludeTimeline,
- boolean excludeTracks) {
+ Player.Commands availableCommands, boolean excludeTimeline, boolean excludeTracks) {
Bundle bundle = new Bundle();
if (playerError != null) {
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.putInt(FIELD_REPEAT_MODE, repeatMode);
bundle.putBoolean(FIELD_SHUFFLE_MODE_ENABLED, shuffleModeEnabled);
- if (!excludeTimeline) {
- bundle.putBundle(FIELD_TIMELINE, timeline.toBundle(excludeMediaItems));
+ if (!excludeTimeline && availableCommands.contains(Player.COMMAND_GET_TIMELINE)) {
+ bundle.putBundle(FIELD_TIMELINE, timeline.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.putFloat(FIELD_VOLUME, volume);
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_DEVICE_INFO, deviceInfo.toBundle());
@@ -836,13 +832,13 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
bundle.putInt(FIELD_PLAYBACK_STATE, playbackState);
bundle.putBoolean(FIELD_IS_PLAYING, isPlaying);
bundle.putBoolean(FIELD_IS_LOADING, isLoading);
- bundle.putBundle(
- FIELD_MEDIA_METADATA,
- excludeMediaItems ? MediaMetadata.EMPTY.toBundle() : mediaMetadata.toBundle());
+ if (availableCommands.contains(Player.COMMAND_GET_TIMELINE)) {
+ bundle.putBundle(FIELD_MEDIA_METADATA, mediaMetadata.toBundle());
+ }
bundle.putLong(FIELD_SEEK_BACK_INCREMENT_MS, seekBackIncrementMs);
bundle.putLong(FIELD_SEEK_FORWARD_INCREMENT_MS, seekForwardIncrementMs);
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_TRACK_SELECTION_PARAMETERS, trackSelectionParameters.toBundle());
@@ -853,9 +849,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
@Override
public Bundle toBundle() {
return toBundle(
- /* excludeMediaItems= */ false,
- /* excludeMediaItemsMetadata= */ false,
- /* excludeCues= */ false,
+ /* availableCommands= */ new Player.Commands.Builder().addAllCommands().build(),
/* excludeTimeline= */ false,
/* excludeTracks= */ false);
}