diff --git a/libraries/common/src/main/java/androidx/media3/common/Player.java b/libraries/common/src/main/java/androidx/media3/common/Player.java index 3a631280ca..6340f5b461 100644 --- a/libraries/common/src/main/java/androidx/media3/common/Player.java +++ b/libraries/common/src/main/java/androidx/media3/common/Player.java @@ -350,15 +350,9 @@ public interface Player { return false; } PositionInfo that = (PositionInfo) o; - return mediaItemIndex == that.mediaItemIndex - && periodIndex == that.periodIndex - && positionMs == that.positionMs - && contentPositionMs == that.contentPositionMs - && adGroupIndex == that.adGroupIndex - && adIndexInAdGroup == that.adIndexInAdGroup + return equalsForBundling(that) && Objects.equal(windowUid, that.windowUid) - && Objects.equal(periodUid, that.periodUid) - && Objects.equal(mediaItem, that.mediaItem); + && Objects.equal(periodUid, that.periodUid); } @Override @@ -375,6 +369,21 @@ public interface Player { adIndexInAdGroup); } + /** + * Returns whether this position info and the other position info would result in the same + * {@link #toBundle() Bundle}. + */ + @UnstableApi + public boolean equalsForBundling(PositionInfo other) { + return mediaItemIndex == other.mediaItemIndex + && periodIndex == other.periodIndex + && positionMs == other.positionMs + && contentPositionMs == other.contentPositionMs + && adGroupIndex == other.adGroupIndex + && adIndexInAdGroup == other.adIndexInAdGroup + && Objects.equal(mediaItem, other.mediaItem); + } + // Bundleable implementation. private static final String FIELD_MEDIA_ITEM_INDEX = Util.intToStringMaxRadix(0); @@ -385,6 +394,36 @@ public interface Player { private static final String FIELD_AD_GROUP_INDEX = Util.intToStringMaxRadix(5); private static final String FIELD_AD_INDEX_IN_AD_GROUP = Util.intToStringMaxRadix(6); + /** + * Returns a copy of this position info, filtered by the specified available commands. + * + *
The filtered fields are reset to their default values. + * + *
The return value may be the same object if nothing is filtered. + * + * @param canAccessCurrentMediaItem Whether {@link Player#COMMAND_GET_CURRENT_MEDIA_ITEM} is + * available. + * @param canAccessTimeline Whether {@link Player#COMMAND_GET_TIMELINE} is available. + * @return The filtered position info. + */ + @UnstableApi + public PositionInfo filterByAvailableCommands( + boolean canAccessCurrentMediaItem, boolean canAccessTimeline) { + if (canAccessCurrentMediaItem && canAccessTimeline) { + return this; + } + return new PositionInfo( + windowUid, + canAccessTimeline ? mediaItemIndex : 0, + canAccessCurrentMediaItem ? mediaItem : null, + periodUid, + canAccessTimeline ? periodIndex : 0, + canAccessCurrentMediaItem ? positionMs : 0, + canAccessCurrentMediaItem ? contentPositionMs : 0, + canAccessCurrentMediaItem ? adGroupIndex : C.INDEX_UNSET, + canAccessCurrentMediaItem ? adIndexInAdGroup : C.INDEX_UNSET); + } + /** * {@inheritDoc} * @@ -394,31 +433,28 @@ public interface Player { @UnstableApi @Override public Bundle toBundle() { - return toBundle(/* canAccessCurrentMediaItem= */ true, /* canAccessTimeline= */ true); - } - - /** - * Returns a {@link Bundle} representing the information stored in this object, filtered by - * available commands. - * - * @param canAccessCurrentMediaItem Whether the {@link Bundle} should contain information - * accessbile with {@link #COMMAND_GET_CURRENT_MEDIA_ITEM}. - * @param canAccessTimeline Whether the {@link Bundle} should contain information accessbile - * with {@link #COMMAND_GET_TIMELINE}. - */ - @UnstableApi - public Bundle toBundle(boolean canAccessCurrentMediaItem, boolean canAccessTimeline) { Bundle bundle = new Bundle(); - bundle.putInt(FIELD_MEDIA_ITEM_INDEX, canAccessTimeline ? mediaItemIndex : 0); - if (mediaItem != null && canAccessCurrentMediaItem) { + if (mediaItemIndex != 0) { + bundle.putInt(FIELD_MEDIA_ITEM_INDEX, mediaItemIndex); + } + if (mediaItem != null) { bundle.putBundle(FIELD_MEDIA_ITEM, mediaItem.toBundle()); } - bundle.putInt(FIELD_PERIOD_INDEX, canAccessTimeline ? periodIndex : 0); - bundle.putLong(FIELD_POSITION_MS, canAccessCurrentMediaItem ? positionMs : 0); - bundle.putLong(FIELD_CONTENT_POSITION_MS, canAccessCurrentMediaItem ? contentPositionMs : 0); - bundle.putInt(FIELD_AD_GROUP_INDEX, canAccessCurrentMediaItem ? adGroupIndex : C.INDEX_UNSET); - bundle.putInt( - FIELD_AD_INDEX_IN_AD_GROUP, canAccessCurrentMediaItem ? adIndexInAdGroup : C.INDEX_UNSET); + if (periodIndex != 0) { + bundle.putInt(FIELD_PERIOD_INDEX, periodIndex); + } + if (positionMs != 0) { + bundle.putLong(FIELD_POSITION_MS, positionMs); + } + if (contentPositionMs != 0) { + bundle.putLong(FIELD_CONTENT_POSITION_MS, contentPositionMs); + } + if (adGroupIndex != C.INDEX_UNSET) { + bundle.putInt(FIELD_AD_GROUP_INDEX, adGroupIndex); + } + if (adIndexInAdGroup != C.INDEX_UNSET) { + bundle.putInt(FIELD_AD_INDEX_IN_AD_GROUP, adIndexInAdGroup); + } return bundle; } 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 d92f586ccc..4b338ee44b 100644 --- a/libraries/common/src/main/java/androidx/media3/common/Timeline.java +++ b/libraries/common/src/main/java/androidx/media3/common/Timeline.java @@ -1443,36 +1443,29 @@ public abstract class Timeline implements Bundleable { } /** - * Returns a {@link Bundle} containing just the specified {@link Window}. + * Returns a copy of this timeline containing just the single specified {@link Window}. * - *
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()}. + *
The method returns the same instance if there is only one window.
*
- * @param windowIndex The index of the {@link Window} to include in the {@link Bundle}.
+ * @param windowIndex The index of the {@link Window} to include in the copy.
+ * @return A {@link Timeline} with just the single specified {@link Window}.
*/
@UnstableApi
- public final Bundle toBundleWithOneWindowOnly(int windowIndex) {
- Window window = getWindow(windowIndex, new Window(), /* defaultPositionProjectionUs= */ 0);
-
- List The filtered fields are reset to their default values.
+ *
+ * @param availableCommands The available {@link Player.Commands} used to filter values.
+ * @param excludeTimeline Whether to filter the {@link #timeline} even if {@link
+ * Player#COMMAND_GET_TIMELINE} is available.
+ * @param excludeTracks Whether to filter the {@link #currentTracks} even if {@link
+ * Player#COMMAND_GET_TRACKS} is available.
+ * @return The filtered player info.
+ */
+ public PlayerInfo filterByAvailableCommands(
Player.Commands availableCommands, boolean excludeTimeline, boolean excludeTracks) {
- Bundle bundle = new Bundle();
+ PlayerInfo.Builder builder = new Builder(this);
boolean canAccessCurrentMediaItem =
availableCommands.contains(Player.COMMAND_GET_CURRENT_MEDIA_ITEM);
boolean canAccessTimeline = availableCommands.contains(Player.COMMAND_GET_TIMELINE);
- if (playerError != null) {
- bundle.putBundle(FIELD_PLAYBACK_ERROR, playerError.toBundle());
+ builder.setSessionPositionInfo(
+ sessionPositionInfo.filterByAvailableCommands(
+ canAccessCurrentMediaItem, canAccessTimeline));
+ builder.setOldPositionInfo(
+ oldPositionInfo.filterByAvailableCommands(canAccessCurrentMediaItem, canAccessTimeline));
+ builder.setNewPositionInfo(
+ newPositionInfo.filterByAvailableCommands(canAccessCurrentMediaItem, canAccessTimeline));
+ if (!canAccessTimeline && canAccessCurrentMediaItem && !timeline.isEmpty()) {
+ builder.setTimeline(
+ timeline.copyWithSingleWindow(sessionPositionInfo.positionInfo.mediaItemIndex));
+ } else if (excludeTimeline || !canAccessTimeline) {
+ builder.setTimeline(Timeline.EMPTY);
}
- bundle.putInt(FIELD_MEDIA_ITEM_TRANSITION_REASON, mediaItemTransitionReason);
- bundle.putBundle(
- FIELD_SESSION_POSITION_INFO,
- sessionPositionInfo.toBundle(canAccessCurrentMediaItem, canAccessTimeline));
- bundle.putBundle(
- FIELD_OLD_POSITION_INFO,
- oldPositionInfo.toBundle(canAccessCurrentMediaItem, canAccessTimeline));
- bundle.putBundle(
- FIELD_NEW_POSITION_INFO,
- newPositionInfo.toBundle(canAccessCurrentMediaItem, canAccessTimeline));
- bundle.putInt(FIELD_DISCONTINUITY_REASON, discontinuityReason);
- bundle.putBundle(FIELD_PLAYBACK_PARAMETERS, playbackParameters.toBundle());
- bundle.putInt(FIELD_REPEAT_MODE, repeatMode);
- bundle.putBoolean(FIELD_SHUFFLE_MODE_ENABLED, shuffleModeEnabled);
- if (!excludeTimeline && canAccessTimeline) {
- bundle.putBundle(FIELD_TIMELINE, timeline.toBundle());
- } else if (!canAccessTimeline && canAccessCurrentMediaItem && !timeline.isEmpty()) {
- bundle.putBundle(
- FIELD_TIMELINE,
- timeline.toBundleWithOneWindowOnly(sessionPositionInfo.positionInfo.mediaItemIndex));
+ if (!availableCommands.contains(Player.COMMAND_GET_METADATA)) {
+ builder.setPlaylistMetadata(MediaMetadata.EMPTY);
}
- bundle.putInt(FIELD_TIMELINE_CHANGE_REASON, timelineChangeReason);
- bundle.putBundle(FIELD_VIDEO_SIZE, videoSize.toBundle());
- if (availableCommands.contains(Player.COMMAND_GET_METADATA)) {
- bundle.putBundle(FIELD_PLAYLIST_METADATA, playlistMetadata.toBundle());
+ if (!availableCommands.contains(Player.COMMAND_GET_VOLUME)) {
+ builder.setVolume(1);
}
- if (availableCommands.contains(Player.COMMAND_GET_VOLUME)) {
- bundle.putFloat(FIELD_VOLUME, volume);
+ if (!availableCommands.contains(Player.COMMAND_GET_AUDIO_ATTRIBUTES)) {
+ builder.setAudioAttributes(AudioAttributes.DEFAULT);
}
- if (availableCommands.contains(Player.COMMAND_GET_AUDIO_ATTRIBUTES)) {
- bundle.putBundle(FIELD_AUDIO_ATTRIBUTES, audioAttributes.toBundle());
+ if (!availableCommands.contains(Player.COMMAND_GET_TEXT)) {
+ builder.setCues(CueGroup.EMPTY_TIME_ZERO);
}
- if (availableCommands.contains(Player.COMMAND_GET_TEXT)) {
- bundle.putBundle(FIELD_CUE_GROUP, cueGroup.toBundle());
+ if (!availableCommands.contains(Player.COMMAND_GET_DEVICE_VOLUME)) {
+ builder.setDeviceVolume(0).setDeviceMuted(false);
}
- bundle.putBundle(FIELD_DEVICE_INFO, deviceInfo.toBundle());
- if (availableCommands.contains(Player.COMMAND_GET_DEVICE_VOLUME)) {
- bundle.putInt(FIELD_DEVICE_VOLUME, deviceVolume);
- bundle.putBoolean(FIELD_DEVICE_MUTED, deviceMuted);
+ if (!availableCommands.contains(Player.COMMAND_GET_METADATA)) {
+ builder.setMediaMetadata(MediaMetadata.EMPTY);
}
- bundle.putBoolean(FIELD_PLAY_WHEN_READY, playWhenReady);
- bundle.putInt(FIELD_PLAYBACK_SUPPRESSION_REASON, playbackSuppressionReason);
- bundle.putInt(FIELD_PLAYBACK_STATE, playbackState);
- bundle.putBoolean(FIELD_IS_PLAYING, isPlaying);
- bundle.putBoolean(FIELD_IS_LOADING, isLoading);
- if (availableCommands.contains(Player.COMMAND_GET_METADATA)) {
- bundle.putBundle(FIELD_MEDIA_METADATA, mediaMetadata.toBundle());
+ if (excludeTracks || !availableCommands.contains(Player.COMMAND_GET_TRACKS)) {
+ builder.setCurrentTracks(Tracks.EMPTY);
}
- 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 && availableCommands.contains(Player.COMMAND_GET_TRACKS)) {
- bundle.putBundle(FIELD_CURRENT_TRACKS, currentTracks.toBundle());
- }
- bundle.putBundle(FIELD_TRACK_SELECTION_PARAMETERS, trackSelectionParameters.toBundle());
- return bundle;
+ return builder.build();
}
@Override
public Bundle toBundle() {
- return toBundle(
- /* availableCommands= */ new Player.Commands.Builder().addAllCommands().build(),
- /* excludeTimeline= */ false,
- /* excludeTracks= */ false);
+ Bundle bundle = new Bundle();
+ if (playerError != null) {
+ bundle.putBundle(FIELD_PLAYBACK_ERROR, playerError.toBundle());
+ }
+ if (mediaItemTransitionReason != MEDIA_ITEM_TRANSITION_REASON_DEFAULT) {
+ bundle.putInt(FIELD_MEDIA_ITEM_TRANSITION_REASON, mediaItemTransitionReason);
+ }
+ if (!sessionPositionInfo.equals(SessionPositionInfo.DEFAULT)) {
+ bundle.putBundle(FIELD_SESSION_POSITION_INFO, sessionPositionInfo.toBundle());
+ }
+ if (!SessionPositionInfo.DEFAULT_POSITION_INFO.equalsForBundling(oldPositionInfo)) {
+ bundle.putBundle(FIELD_OLD_POSITION_INFO, oldPositionInfo.toBundle());
+ }
+ if (!SessionPositionInfo.DEFAULT_POSITION_INFO.equalsForBundling(newPositionInfo)) {
+ bundle.putBundle(FIELD_NEW_POSITION_INFO, newPositionInfo.toBundle());
+ }
+ if (discontinuityReason != DISCONTINUITY_REASON_DEFAULT) {
+ bundle.putInt(FIELD_DISCONTINUITY_REASON, discontinuityReason);
+ }
+ if (!playbackParameters.equals(PlaybackParameters.DEFAULT)) {
+ bundle.putBundle(FIELD_PLAYBACK_PARAMETERS, playbackParameters.toBundle());
+ }
+ if (repeatMode != Player.REPEAT_MODE_OFF) {
+ bundle.putInt(FIELD_REPEAT_MODE, repeatMode);
+ }
+ if (shuffleModeEnabled) {
+ bundle.putBoolean(FIELD_SHUFFLE_MODE_ENABLED, shuffleModeEnabled);
+ }
+ if (!timeline.equals(Timeline.EMPTY)) {
+ bundle.putBundle(FIELD_TIMELINE, timeline.toBundle());
+ }
+ if (timelineChangeReason != TIMELINE_CHANGE_REASON_DEFAULT) {
+ bundle.putInt(FIELD_TIMELINE_CHANGE_REASON, timelineChangeReason);
+ }
+ if (!videoSize.equals(VideoSize.UNKNOWN)) {
+ bundle.putBundle(FIELD_VIDEO_SIZE, videoSize.toBundle());
+ }
+ if (!playlistMetadata.equals(MediaMetadata.EMPTY)) {
+ bundle.putBundle(FIELD_PLAYLIST_METADATA, playlistMetadata.toBundle());
+ }
+ if (volume != 1) {
+ bundle.putFloat(FIELD_VOLUME, volume);
+ }
+ if (!audioAttributes.equals(AudioAttributes.DEFAULT)) {
+ bundle.putBundle(FIELD_AUDIO_ATTRIBUTES, audioAttributes.toBundle());
+ }
+ if (!cueGroup.equals(CueGroup.EMPTY_TIME_ZERO)) {
+ bundle.putBundle(FIELD_CUE_GROUP, cueGroup.toBundle());
+ }
+ if (!deviceInfo.equals(DeviceInfo.UNKNOWN)) {
+ bundle.putBundle(FIELD_DEVICE_INFO, deviceInfo.toBundle());
+ }
+ if (deviceVolume != 0) {
+ bundle.putInt(FIELD_DEVICE_VOLUME, deviceVolume);
+ }
+ if (deviceMuted) {
+ bundle.putBoolean(FIELD_DEVICE_MUTED, deviceMuted);
+ }
+ if (playWhenReady) {
+ bundle.putBoolean(FIELD_PLAY_WHEN_READY, playWhenReady);
+ }
+ if (playWhenReadyChangeReason != PLAY_WHEN_READY_CHANGE_REASON_DEFAULT) {
+ bundle.putInt(FIELD_PLAY_WHEN_READY_CHANGE_REASON, playWhenReadyChangeReason);
+ }
+ if (playbackSuppressionReason != PLAYBACK_SUPPRESSION_REASON_NONE) {
+ bundle.putInt(FIELD_PLAYBACK_SUPPRESSION_REASON, playbackSuppressionReason);
+ }
+ if (playbackState != STATE_IDLE) {
+ bundle.putInt(FIELD_PLAYBACK_STATE, playbackState);
+ }
+ if (isPlaying) {
+ bundle.putBoolean(FIELD_IS_PLAYING, isPlaying);
+ }
+ if (isLoading) {
+ bundle.putBoolean(FIELD_IS_LOADING, isLoading);
+ }
+ if (!mediaMetadata.equals(MediaMetadata.EMPTY)) {
+ bundle.putBundle(FIELD_MEDIA_METADATA, mediaMetadata.toBundle());
+ }
+ if (seekBackIncrementMs != 0) {
+ bundle.putLong(FIELD_SEEK_BACK_INCREMENT_MS, seekBackIncrementMs);
+ }
+ if (seekForwardIncrementMs != 0) {
+ bundle.putLong(FIELD_SEEK_FORWARD_INCREMENT_MS, seekForwardIncrementMs);
+ }
+ if (maxSeekToPreviousPositionMs != 0) {
+ bundle.putLong(FIELD_MAX_SEEK_TO_PREVIOUS_POSITION_MS, maxSeekToPreviousPositionMs);
+ }
+ if (!currentTracks.equals(Tracks.EMPTY)) {
+ bundle.putBundle(FIELD_CURRENT_TRACKS, currentTracks.toBundle());
+ }
+ if (!trackSelectionParameters.equals(TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT)) {
+ bundle.putBundle(FIELD_TRACK_SELECTION_PARAMETERS, trackSelectionParameters.toBundle());
+ }
+ return bundle;
}
/** Object that can restore {@link PlayerInfo} from a {@link Bundle}. */
@@ -911,7 +990,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
PlaybackException playerError =
playerErrorBundle == null ? null : PlaybackException.CREATOR.fromBundle(playerErrorBundle);
int mediaItemTransitionReason =
- bundle.getInt(FIELD_MEDIA_ITEM_TRANSITION_REASON, MEDIA_ITEM_TRANSITION_REASON_REPEAT);
+ bundle.getInt(FIELD_MEDIA_ITEM_TRANSITION_REASON, MEDIA_ITEM_TRANSITION_REASON_DEFAULT);
@Nullable Bundle sessionPositionInfoBundle = bundle.getBundle(FIELD_SESSION_POSITION_INFO);
SessionPositionInfo sessionPositionInfo =
sessionPositionInfoBundle == null
@@ -928,7 +1007,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
? SessionPositionInfo.DEFAULT_POSITION_INFO
: PositionInfo.CREATOR.fromBundle(newPositionInfoBundle);
int discontinuityReason =
- bundle.getInt(FIELD_DISCONTINUITY_REASON, DISCONTINUITY_REASON_AUTO_TRANSITION);
+ bundle.getInt(FIELD_DISCONTINUITY_REASON, DISCONTINUITY_REASON_DEFAULT);
@Nullable Bundle playbackParametersBundle = bundle.getBundle(FIELD_PLAYBACK_PARAMETERS);
PlaybackParameters playbackParameters =
playbackParametersBundle == null
@@ -974,7 +1053,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
int playWhenReadyChangeReason =
bundle.getInt(
FIELD_PLAY_WHEN_READY_CHANGE_REASON,
- /* defaultValue= */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST);
+ /* defaultValue= */ PLAY_WHEN_READY_CHANGE_REASON_DEFAULT);
@Player.PlaybackSuppressionReason
int playbackSuppressionReason =
bundle.getInt(
diff --git a/libraries/session/src/main/java/androidx/media3/session/SessionPositionInfo.java b/libraries/session/src/main/java/androidx/media3/session/SessionPositionInfo.java
index a4d537f0cc..fa811a6a69 100644
--- a/libraries/session/src/main/java/androidx/media3/session/SessionPositionInfo.java
+++ b/libraries/session/src/main/java/androidx/media3/session/SessionPositionInfo.java
@@ -21,6 +21,7 @@ import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.media3.common.Bundleable;
import androidx.media3.common.C;
+import androidx.media3.common.Player;
import androidx.media3.common.Player.PositionInfo;
import androidx.media3.common.util.Util;
import com.google.common.base.Objects;
@@ -101,9 +102,9 @@ import com.google.common.base.Objects;
return false;
}
SessionPositionInfo other = (SessionPositionInfo) obj;
- return positionInfo.equals(other.positionInfo)
+ return eventTimeMs == other.eventTimeMs
+ && positionInfo.equals(other.positionInfo)
&& isPlayingAd == other.isPlayingAd
- && eventTimeMs == other.eventTimeMs
&& durationMs == other.durationMs
&& bufferedPositionMs == other.bufferedPositionMs
&& bufferedPercentage == other.bufferedPercentage
@@ -168,30 +169,69 @@ import com.google.common.base.Objects;
private static final String FIELD_CONTENT_DURATION_MS = Util.intToStringMaxRadix(8);
private static final String FIELD_CONTENT_BUFFERED_POSITION_MS = Util.intToStringMaxRadix(9);
- @Override
- public Bundle toBundle() {
- return toBundle(/* canAccessCurrentMediaItem= */ true, /* canAccessTimeline= */ true);
+ /**
+ * Returns a copy of this session position info, filtered by the specified available commands.
+ *
+ * The filtered fields are reset to their default values.
+ *
+ * The return value may be the same object if nothing is filtered.
+ *
+ * @param canAccessCurrentMediaItem Whether {@link Player#COMMAND_GET_CURRENT_MEDIA_ITEM} is
+ * available.
+ * @param canAccessTimeline Whether {@link Player#COMMAND_GET_TIMELINE} is available.
+ * @return The filtered session position info.
+ */
+ public SessionPositionInfo filterByAvailableCommands(
+ boolean canAccessCurrentMediaItem, boolean canAccessTimeline) {
+ if (canAccessCurrentMediaItem && canAccessTimeline) {
+ return this;
+ }
+ return new SessionPositionInfo(
+ positionInfo.filterByAvailableCommands(canAccessCurrentMediaItem, canAccessTimeline),
+ canAccessCurrentMediaItem && isPlayingAd,
+ eventTimeMs,
+ canAccessCurrentMediaItem ? durationMs : C.TIME_UNSET,
+ canAccessCurrentMediaItem ? bufferedPositionMs : 0,
+ canAccessCurrentMediaItem ? bufferedPercentage : 0,
+ canAccessCurrentMediaItem ? totalBufferedDurationMs : 0,
+ canAccessCurrentMediaItem ? currentLiveOffsetMs : C.TIME_UNSET,
+ canAccessCurrentMediaItem ? contentDurationMs : C.TIME_UNSET,
+ canAccessCurrentMediaItem ? contentBufferedPositionMs : 0);
}
- public Bundle toBundle(boolean canAccessCurrentMediaItem, boolean canAccessTimeline) {
+ @Override
+ public Bundle toBundle() {
Bundle bundle = new Bundle();
- bundle.putBundle(
- FIELD_POSITION_INFO, positionInfo.toBundle(canAccessCurrentMediaItem, canAccessTimeline));
- bundle.putBoolean(FIELD_IS_PLAYING_AD, canAccessCurrentMediaItem && isPlayingAd);
- bundle.putLong(FIELD_EVENT_TIME_MS, eventTimeMs);
- bundle.putLong(FIELD_DURATION_MS, canAccessCurrentMediaItem ? durationMs : C.TIME_UNSET);
- bundle.putLong(FIELD_BUFFERED_POSITION_MS, canAccessCurrentMediaItem ? bufferedPositionMs : 0);
- bundle.putInt(FIELD_BUFFERED_PERCENTAGE, canAccessCurrentMediaItem ? bufferedPercentage : 0);
- bundle.putLong(
- FIELD_TOTAL_BUFFERED_DURATION_MS, canAccessCurrentMediaItem ? totalBufferedDurationMs : 0);
- bundle.putLong(
- FIELD_CURRENT_LIVE_OFFSET_MS,
- canAccessCurrentMediaItem ? currentLiveOffsetMs : C.TIME_UNSET);
- bundle.putLong(
- FIELD_CONTENT_DURATION_MS, canAccessCurrentMediaItem ? contentDurationMs : C.TIME_UNSET);
- bundle.putLong(
- FIELD_CONTENT_BUFFERED_POSITION_MS,
- canAccessCurrentMediaItem ? contentBufferedPositionMs : 0);
+ if (!DEFAULT_POSITION_INFO.equalsForBundling(positionInfo)) {
+ bundle.putBundle(FIELD_POSITION_INFO, positionInfo.toBundle());
+ }
+ if (isPlayingAd) {
+ bundle.putBoolean(FIELD_IS_PLAYING_AD, isPlayingAd);
+ }
+ if (eventTimeMs != C.TIME_UNSET) {
+ bundle.putLong(FIELD_EVENT_TIME_MS, eventTimeMs);
+ }
+ if (durationMs != C.TIME_UNSET) {
+ bundle.putLong(FIELD_DURATION_MS, durationMs);
+ }
+ if (bufferedPositionMs != 0) {
+ bundle.putLong(FIELD_BUFFERED_POSITION_MS, bufferedPositionMs);
+ }
+ if (bufferedPercentage != 0) {
+ bundle.putInt(FIELD_BUFFERED_PERCENTAGE, bufferedPercentage);
+ }
+ if (totalBufferedDurationMs != 0) {
+ bundle.putLong(FIELD_TOTAL_BUFFERED_DURATION_MS, totalBufferedDurationMs);
+ }
+ if (currentLiveOffsetMs != C.TIME_UNSET) {
+ bundle.putLong(FIELD_CURRENT_LIVE_OFFSET_MS, currentLiveOffsetMs);
+ }
+ if (contentDurationMs != C.TIME_UNSET) {
+ bundle.putLong(FIELD_CONTENT_DURATION_MS, contentDurationMs);
+ }
+ if (contentBufferedPositionMs != 0) {
+ bundle.putLong(FIELD_CONTENT_BUFFERED_POSITION_MS, contentBufferedPositionMs);
+ }
return bundle;
}
diff --git a/libraries/session/src/test/java/androidx/media3/session/PlayerInfoTest.java b/libraries/session/src/test/java/androidx/media3/session/PlayerInfoTest.java
index c3e6736ed3..63f672aa85 100644
--- a/libraries/session/src/test/java/androidx/media3/session/PlayerInfoTest.java
+++ b/libraries/session/src/test/java/androidx/media3/session/PlayerInfoTest.java
@@ -71,7 +71,7 @@ public class PlayerInfoTest {
}
@Test
- public void toBundleFromBundle_withAllCommands_restoresAllData() {
+ public void toBundleFromBundle_restoresAllData() {
PlayerInfo playerInfo =
new PlayerInfo.Builder(PlayerInfo.DEFAULT)
.setOldPositionInfo(
@@ -151,7 +151,7 @@ public class PlayerInfoTest {
new PlaybackException(
/* message= */ null, /* cause= */ null, PlaybackException.ERROR_CODE_TIMEOUT))
.setPlayWhenReady(true)
- .setPlayWhenReadyChangeReason(Player.PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST)
+ .setPlayWhenReadyChangeReason(Player.PLAY_WHEN_READY_CHANGE_REASON_AUDIO_FOCUS_LOSS)
.setRepeatMode(Player.REPEAT_MODE_ONE)
.setSeekBackIncrement(7000)
.setSeekForwardIncrement(6000)
@@ -163,12 +163,7 @@ public class PlayerInfoTest {
.setVideoSize(new VideoSize(/* width= */ 1024, /* height= */ 768))
.build();
- PlayerInfo infoAfterBundling =
- PlayerInfo.CREATOR.fromBundle(
- playerInfo.toBundle(
- new Player.Commands.Builder().addAllCommands().build(),
- /* excludeTimeline= */ false,
- /* excludeTracks= */ false));
+ PlayerInfo infoAfterBundling = PlayerInfo.CREATOR.fromBundle(playerInfo.toBundle());
assertThat(infoAfterBundling.oldPositionInfo.mediaItemIndex).isEqualTo(5);
assertThat(infoAfterBundling.oldPositionInfo.periodIndex).isEqualTo(4);
@@ -229,7 +224,7 @@ public class PlayerInfoTest {
.isEqualTo(PlaybackException.ERROR_CODE_TIMEOUT);
assertThat(infoAfterBundling.playWhenReady).isTrue();
assertThat(infoAfterBundling.playWhenReadyChangeReason)
- .isEqualTo(Player.PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST);
+ .isEqualTo(Player.PLAY_WHEN_READY_CHANGE_REASON_AUDIO_FOCUS_LOSS);
assertThat(infoAfterBundling.repeatMode).isEqualTo(Player.REPEAT_MODE_ONE);
assertThat(infoAfterBundling.seekBackIncrementMs).isEqualTo(7000);
assertThat(infoAfterBundling.seekForwardIncrementMs).isEqualTo(6000);
@@ -289,13 +284,15 @@ public class PlayerInfoTest {
PlayerInfo infoAfterBundling =
PlayerInfo.CREATOR.fromBundle(
- playerInfo.toBundle(
- new Player.Commands.Builder()
- .addAllCommands()
- .remove(Player.COMMAND_GET_CURRENT_MEDIA_ITEM)
- .build(),
- /* excludeTimeline= */ false,
- /* excludeTracks= */ false));
+ playerInfo
+ .filterByAvailableCommands(
+ new Player.Commands.Builder()
+ .addAllCommands()
+ .remove(Player.COMMAND_GET_CURRENT_MEDIA_ITEM)
+ .build(),
+ /* excludeTimeline= */ false,
+ /* excludeTracks= */ false)
+ .toBundle());
assertThat(infoAfterBundling.oldPositionInfo.mediaItemIndex).isEqualTo(5);
assertThat(infoAfterBundling.oldPositionInfo.periodIndex).isEqualTo(4);
@@ -408,13 +405,15 @@ public class PlayerInfoTest {
PlayerInfo infoAfterBundling =
PlayerInfo.CREATOR.fromBundle(
- playerInfo.toBundle(
- new Player.Commands.Builder()
- .addAllCommands()
- .remove(Player.COMMAND_GET_TIMELINE)
- .build(),
- /* excludeTimeline= */ true,
- /* excludeTracks= */ false));
+ playerInfo
+ .filterByAvailableCommands(
+ new Player.Commands.Builder()
+ .addAllCommands()
+ .remove(Player.COMMAND_GET_TIMELINE)
+ .build(),
+ /* excludeTimeline= */ true,
+ /* excludeTracks= */ false)
+ .toBundle());
assertThat(infoAfterBundling.oldPositionInfo.mediaItemIndex).isEqualTo(0);
assertThat(infoAfterBundling.oldPositionInfo.periodIndex).isEqualTo(0);
@@ -475,13 +474,15 @@ public class PlayerInfoTest {
PlayerInfo infoAfterBundling =
PlayerInfo.CREATOR.fromBundle(
- playerInfo.toBundle(
- new Player.Commands.Builder()
- .addAllCommands()
- .remove(Player.COMMAND_GET_METADATA)
- .build(),
- /* excludeTimeline= */ false,
- /* excludeTracks= */ false));
+ playerInfo
+ .filterByAvailableCommands(
+ new Player.Commands.Builder()
+ .addAllCommands()
+ .remove(Player.COMMAND_GET_METADATA)
+ .build(),
+ /* excludeTimeline= */ false,
+ /* excludeTracks= */ false)
+ .toBundle());
assertThat(infoAfterBundling.mediaMetadata).isEqualTo(MediaMetadata.EMPTY);
assertThat(infoAfterBundling.playlistMetadata).isEqualTo(MediaMetadata.EMPTY);
@@ -493,13 +494,15 @@ public class PlayerInfoTest {
PlayerInfo infoAfterBundling =
PlayerInfo.CREATOR.fromBundle(
- playerInfo.toBundle(
- new Player.Commands.Builder()
- .addAllCommands()
- .remove(Player.COMMAND_GET_VOLUME)
- .build(),
- /* excludeTimeline= */ false,
- /* excludeTracks= */ false));
+ playerInfo
+ .filterByAvailableCommands(
+ new Player.Commands.Builder()
+ .addAllCommands()
+ .remove(Player.COMMAND_GET_VOLUME)
+ .build(),
+ /* excludeTimeline= */ false,
+ /* excludeTracks= */ false)
+ .toBundle());
assertThat(infoAfterBundling.volume).isEqualTo(1f);
}
@@ -511,13 +514,15 @@ public class PlayerInfoTest {
PlayerInfo infoAfterBundling =
PlayerInfo.CREATOR.fromBundle(
- playerInfo.toBundle(
- new Player.Commands.Builder()
- .addAllCommands()
- .remove(Player.COMMAND_GET_DEVICE_VOLUME)
- .build(),
- /* excludeTimeline= */ false,
- /* excludeTracks= */ false));
+ playerInfo
+ .filterByAvailableCommands(
+ new Player.Commands.Builder()
+ .addAllCommands()
+ .remove(Player.COMMAND_GET_DEVICE_VOLUME)
+ .build(),
+ /* excludeTimeline= */ false,
+ /* excludeTracks= */ false)
+ .toBundle());
assertThat(infoAfterBundling.deviceVolume).isEqualTo(0);
assertThat(infoAfterBundling.deviceMuted).isFalse();
@@ -533,13 +538,15 @@ public class PlayerInfoTest {
PlayerInfo infoAfterBundling =
PlayerInfo.CREATOR.fromBundle(
- playerInfo.toBundle(
- new Player.Commands.Builder()
- .addAllCommands()
- .remove(Player.COMMAND_GET_AUDIO_ATTRIBUTES)
- .build(),
- /* excludeTimeline= */ false,
- /* excludeTracks= */ false));
+ playerInfo
+ .filterByAvailableCommands(
+ new Player.Commands.Builder()
+ .addAllCommands()
+ .remove(Player.COMMAND_GET_AUDIO_ATTRIBUTES)
+ .build(),
+ /* excludeTimeline= */ false,
+ /* excludeTracks= */ false)
+ .toBundle());
assertThat(infoAfterBundling.audioAttributes).isEqualTo(AudioAttributes.DEFAULT);
}
@@ -553,13 +560,15 @@ public class PlayerInfoTest {
PlayerInfo infoAfterBundling =
PlayerInfo.CREATOR.fromBundle(
- playerInfo.toBundle(
- new Player.Commands.Builder()
- .addAllCommands()
- .remove(Player.COMMAND_GET_TEXT)
- .build(),
- /* excludeTimeline= */ false,
- /* excludeTracks= */ false));
+ playerInfo
+ .filterByAvailableCommands(
+ new Player.Commands.Builder()
+ .addAllCommands()
+ .remove(Player.COMMAND_GET_TEXT)
+ .build(),
+ /* excludeTimeline= */ false,
+ /* excludeTracks= */ false)
+ .toBundle());
assertThat(infoAfterBundling.cueGroup).isEqualTo(CueGroup.EMPTY_TIME_ZERO);
}
@@ -581,13 +590,15 @@ public class PlayerInfoTest {
PlayerInfo infoAfterBundling =
PlayerInfo.CREATOR.fromBundle(
- playerInfo.toBundle(
- new Player.Commands.Builder()
- .addAllCommands()
- .remove(Player.COMMAND_GET_TRACKS)
- .build(),
- /* excludeTimeline= */ false,
- /* excludeTracks= */ true));
+ playerInfo
+ .filterByAvailableCommands(
+ new Player.Commands.Builder()
+ .addAllCommands()
+ .remove(Player.COMMAND_GET_TRACKS)
+ .build(),
+ /* excludeTimeline= */ false,
+ /* excludeTracks= */ true)
+ .toBundle());
assertThat(infoAfterBundling.currentTracks).isEqualTo(Tracks.EMPTY);
}