Commit b8b6ddf3 by tonihei Committed by christosts

Correctly filter PlayerInfo by available getter commands.

When bundling PlayerInfo, we need to remove information if the
controller is not allowed to access it. This was only partially
done at the moment.

PiperOrigin-RevId: 502852798
(cherry picked from commit 69cfba7c)
parent 0606ab0c
......@@ -286,16 +286,31 @@ 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, mediaItemIndex);
if (mediaItem != null) {
bundle.putInt(FIELD_MEDIA_ITEM_INDEX, canAccessTimeline ? mediaItemIndex : 0);
if (mediaItem != null && canAccessCurrentMediaItem) {
bundle.putBundle(FIELD_MEDIA_ITEM, mediaItem.toBundle());
}
bundle.putInt(FIELD_PERIOD_INDEX, periodIndex);
bundle.putLong(FIELD_POSITION_MS, positionMs);
bundle.putLong(FIELD_CONTENT_POSITION_MS, contentPositionMs);
bundle.putInt(FIELD_AD_GROUP_INDEX, adGroupIndex);
bundle.putInt(FIELD_AD_INDEX_IN_AD_GROUP, adIndexInAdGroup);
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);
return bundle;
}
......@@ -303,15 +318,14 @@ public interface Player {
@UnstableApi public static final Creator<PositionInfo> CREATOR = PositionInfo::fromBundle;
private static PositionInfo fromBundle(Bundle bundle) {
int mediaItemIndex = bundle.getInt(FIELD_MEDIA_ITEM_INDEX, /* defaultValue= */ C.INDEX_UNSET);
int mediaItemIndex = bundle.getInt(FIELD_MEDIA_ITEM_INDEX, /* defaultValue= */ 0);
@Nullable Bundle mediaItemBundle = bundle.getBundle(FIELD_MEDIA_ITEM);
@Nullable
MediaItem mediaItem =
mediaItemBundle == null ? null : MediaItem.CREATOR.fromBundle(mediaItemBundle);
int periodIndex = bundle.getInt(FIELD_PERIOD_INDEX, /* defaultValue= */ C.INDEX_UNSET);
long positionMs = bundle.getLong(FIELD_POSITION_MS, /* defaultValue= */ C.TIME_UNSET);
long contentPositionMs =
bundle.getLong(FIELD_CONTENT_POSITION_MS, /* defaultValue= */ C.TIME_UNSET);
int periodIndex = bundle.getInt(FIELD_PERIOD_INDEX, /* defaultValue= */ 0);
long positionMs = bundle.getLong(FIELD_POSITION_MS, /* defaultValue= */ 0);
long contentPositionMs = bundle.getLong(FIELD_CONTENT_POSITION_MS, /* defaultValue= */ 0);
int adGroupIndex = bundle.getInt(FIELD_AD_GROUP_INDEX, /* defaultValue= */ C.INDEX_UNSET);
int adIndexInAdGroup =
bundle.getInt(FIELD_AD_INDEX_IN_AD_GROUP, /* defaultValue= */ C.INDEX_UNSET);
......@@ -2281,6 +2295,9 @@ public interface Player {
* <p>Note: When the repeat mode is {@link #REPEAT_MODE_ONE}, this method behaves the same as when
* the current repeat mode is {@link #REPEAT_MODE_OFF}. See {@link #REPEAT_MODE_ONE} for more
* details.
*
* <p>This method must only be called if {@link #COMMAND_GET_TIMELINE} is {@linkplain
* #getAvailableCommands() available}.
*/
boolean hasPreviousMediaItem();
......@@ -2367,6 +2384,9 @@ public interface Player {
* <p>Note: When the repeat mode is {@link #REPEAT_MODE_ONE}, this method behaves the same as when
* the current repeat mode is {@link #REPEAT_MODE_OFF}. See {@link #REPEAT_MODE_ONE} for more
* details.
*
* <p>This method must only be called if {@link #COMMAND_GET_TIMELINE} is {@linkplain
* #getAvailableCommands() available}.
*/
boolean hasNextMediaItem();
......
......@@ -1162,7 +1162,11 @@ public class MediaSession {
throws RemoteException {}
default void onPeriodicSessionPositionInfoChanged(
int seq, SessionPositionInfo sessionPositionInfo) throws RemoteException {}
int seq,
SessionPositionInfo sessionPositionInfo,
boolean canAccessCurrentMediaItem,
boolean canAccessTimeline)
throws RemoteException {}
// Mostly matched with MediaController.ControllerCallback
......
......@@ -601,6 +601,38 @@ import org.checkerframework.checker.initialization.qual.Initialized;
}
}
private void dispatchOnPeriodicSessionPositionInfoChanged(
SessionPositionInfo sessionPositionInfo) {
ConnectedControllersManager<IBinder> controllersManager =
sessionStub.getConnectedControllersManager();
List<ControllerInfo> controllers =
sessionStub.getConnectedControllersManager().getConnectedControllers();
for (int i = 0; i < controllers.size(); i++) {
ControllerInfo controller = controllers.get(i);
boolean canAccessCurrentMediaItem =
controllersManager.isPlayerCommandAvailable(
controller, Player.COMMAND_GET_CURRENT_MEDIA_ITEM);
boolean canAccessTimeline =
controllersManager.isPlayerCommandAvailable(controller, Player.COMMAND_GET_TIMELINE);
dispatchRemoteControllerTaskWithoutReturn(
controller,
(controllerCb, seq) ->
controllerCb.onPeriodicSessionPositionInfoChanged(
seq, sessionPositionInfo, canAccessCurrentMediaItem, canAccessTimeline));
}
try {
sessionLegacyStub
.getControllerLegacyCbForBroadcast()
.onPeriodicSessionPositionInfoChanged(
/* seq= */ 0,
sessionPositionInfo,
/* canAccessCurrentMediaItem= */ true,
/* canAccessTimeline= */ true);
} catch (RemoteException e) {
Log.e(TAG, "Exception in using media1 API", e);
}
}
protected void dispatchRemoteControllerTaskWithoutReturn(RemoteControllerTask task) {
List<ControllerInfo> controllers =
sessionStub.getConnectedControllersManager().getConnectedControllers();
......@@ -719,8 +751,7 @@ import org.checkerframework.checker.initialization.qual.Initialized;
}
}
SessionPositionInfo sessionPositionInfo = playerWrapper.createSessionPositionInfoForBundling();
dispatchRemoteControllerTaskWithoutReturn(
(callback, seq) -> callback.onPeriodicSessionPositionInfoChanged(seq, sessionPositionInfo));
dispatchOnPeriodicSessionPositionInfoChanged(sessionPositionInfo);
schedulePeriodicSessionPositionInfoChanges();
}
......
......@@ -1175,7 +1175,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
@Override
public void onPeriodicSessionPositionInfoChanged(
int unusedSeq, SessionPositionInfo unusedSessionPositionInfo) throws RemoteException {
int unusedSeq,
SessionPositionInfo unusedSessionPositionInfo,
boolean unusedCanAccessCurrentMediaItem,
boolean unusedCanAccessTimeline)
throws RemoteException {
sessionImpl
.getSessionCompat()
.setPlaybackState(sessionImpl.getPlayerWrapper().createPlaybackStateCompat());
......
......@@ -1684,9 +1684,14 @@ import java.util.concurrent.ExecutionException;
@Override
public void onPeriodicSessionPositionInfoChanged(
int sequenceNumber, SessionPositionInfo sessionPositionInfo) throws RemoteException {
int sequenceNumber,
SessionPositionInfo sessionPositionInfo,
boolean canAccessCurrentMediaItem,
boolean canAccessTimeline)
throws RemoteException {
iController.onPeriodicSessionPositionInfoChanged(
sequenceNumber, sessionPositionInfo.toBundle());
sequenceNumber,
sessionPositionInfo.toBundle(canAccessCurrentMediaItem, canAccessTimeline));
}
@Override
......
......@@ -801,38 +801,53 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
public Bundle toBundle(
Player.Commands availableCommands, boolean excludeTimeline, boolean excludeTracks) {
Bundle bundle = new Bundle();
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());
}
bundle.putInt(FIELD_MEDIA_ITEM_TRANSITION_REASON, mediaItemTransitionReason);
bundle.putBundle(FIELD_SESSION_POSITION_INFO, sessionPositionInfo.toBundle());
bundle.putBundle(FIELD_OLD_POSITION_INFO, oldPositionInfo.toBundle());
bundle.putBundle(FIELD_NEW_POSITION_INFO, newPositionInfo.toBundle());
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 && availableCommands.contains(Player.COMMAND_GET_TIMELINE)) {
if (!excludeTimeline && canAccessTimeline) {
bundle.putBundle(FIELD_TIMELINE, timeline.toBundle());
}
bundle.putBundle(FIELD_VIDEO_SIZE, videoSize.toBundle());
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 (availableCommands.contains(Player.COMMAND_GET_VOLUME)) {
bundle.putFloat(FIELD_VOLUME, volume);
}
if (availableCommands.contains(Player.COMMAND_GET_AUDIO_ATTRIBUTES)) {
bundle.putBundle(FIELD_AUDIO_ATTRIBUTES, audioAttributes.toBundle());
}
if (availableCommands.contains(Player.COMMAND_GET_TEXT)) {
bundle.putBundle(FIELD_CUE_GROUP, cueGroup.toBundle());
}
bundle.putBundle(FIELD_DEVICE_INFO, deviceInfo.toBundle());
bundle.putInt(FIELD_DEVICE_VOLUME, deviceVolume);
bundle.putBoolean(FIELD_DEVICE_MUTED, deviceMuted);
if (availableCommands.contains(Player.COMMAND_GET_DEVICE_VOLUME)) {
bundle.putInt(FIELD_DEVICE_VOLUME, deviceVolume);
bundle.putBoolean(FIELD_DEVICE_MUTED, deviceMuted);
}
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_TIMELINE)) {
if (availableCommands.contains(Player.COMMAND_GET_MEDIA_ITEMS_METADATA)) {
bundle.putBundle(FIELD_MEDIA_METADATA, mediaMetadata.toBundle());
}
bundle.putLong(FIELD_SEEK_BACK_INCREMENT_MS, seekBackIncrementMs);
......@@ -842,7 +857,6 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
bundle.putBundle(FIELD_CURRENT_TRACKS, currentTracks.toBundle());
}
bundle.putBundle(FIELD_TRACK_SELECTION_PARAMETERS, trackSelectionParameters.toBundle());
return bundle;
}
......
......@@ -1031,19 +1031,18 @@ import java.util.List;
* <p>This excludes window uid and period uid that wouldn't be preserved when bundling.
*/
public PositionInfo createPositionInfoForBundling() {
if (!isCommandAvailable(COMMAND_GET_CURRENT_MEDIA_ITEM)) {
return SessionPositionInfo.DEFAULT_POSITION_INFO;
}
boolean canAccessCurrentMediaItem = isCommandAvailable(COMMAND_GET_CURRENT_MEDIA_ITEM);
boolean canAccessTimeline = isCommandAvailable(COMMAND_GET_TIMELINE);
return new PositionInfo(
/* windowUid= */ null,
getCurrentMediaItemIndex(),
getCurrentMediaItem(),
canAccessTimeline ? getCurrentMediaItemIndex() : 0,
canAccessCurrentMediaItem ? getCurrentMediaItem() : null,
/* periodUid= */ null,
getCurrentPeriodIndex(),
getCurrentPosition(),
getContentPosition(),
getCurrentAdGroupIndex(),
getCurrentAdIndexInAdGroup());
canAccessTimeline ? getCurrentPeriodIndex() : 0,
canAccessCurrentMediaItem ? getCurrentPosition() : 0,
canAccessCurrentMediaItem ? getContentPosition() : 0,
canAccessCurrentMediaItem ? getCurrentAdGroupIndex() : C.INDEX_UNSET,
canAccessCurrentMediaItem ? getCurrentAdIndexInAdGroup() : C.INDEX_UNSET);
}
/**
......@@ -1052,20 +1051,18 @@ import java.util.List;
* <p>This excludes window uid and period uid that wouldn't be preserved when bundling.
*/
public SessionPositionInfo createSessionPositionInfoForBundling() {
if (!isCommandAvailable(COMMAND_GET_CURRENT_MEDIA_ITEM)) {
return SessionPositionInfo.DEFAULT;
}
boolean canAccessCurrentMediaItem = isCommandAvailable(COMMAND_GET_CURRENT_MEDIA_ITEM);
return new SessionPositionInfo(
createPositionInfoForBundling(),
isPlayingAd(),
canAccessCurrentMediaItem && isPlayingAd(),
/* eventTimeMs= */ SystemClock.elapsedRealtime(),
getDuration(),
getBufferedPosition(),
getBufferedPercentage(),
getTotalBufferedDuration(),
getCurrentLiveOffset(),
getContentDuration(),
getContentBufferedPosition());
canAccessCurrentMediaItem ? getDuration() : C.TIME_UNSET,
canAccessCurrentMediaItem ? getBufferedPosition() : 0,
canAccessCurrentMediaItem ? getBufferedPercentage() : 0,
canAccessCurrentMediaItem ? getTotalBufferedDuration() : 0,
canAccessCurrentMediaItem ? getCurrentLiveOffset() : C.TIME_UNSET,
canAccessCurrentMediaItem ? getContentDuration() : C.TIME_UNSET,
canAccessCurrentMediaItem ? getContentBufferedPosition() : 0);
}
public PlayerInfo createPlayerInfoForBundling() {
......
......@@ -170,17 +170,28 @@ import com.google.common.base.Objects;
@Override
public Bundle toBundle() {
return toBundle(/* canAccessCurrentMediaItem= */ true, /* canAccessTimeline= */ true);
}
public Bundle toBundle(boolean canAccessCurrentMediaItem, boolean canAccessTimeline) {
Bundle bundle = new Bundle();
bundle.putBundle(FIELD_POSITION_INFO, positionInfo.toBundle());
bundle.putBoolean(FIELD_IS_PLAYING_AD, isPlayingAd);
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, durationMs);
bundle.putLong(FIELD_BUFFERED_POSITION_MS, bufferedPositionMs);
bundle.putInt(FIELD_BUFFERED_PERCENTAGE, bufferedPercentage);
bundle.putLong(FIELD_TOTAL_BUFFERED_DURATION_MS, totalBufferedDurationMs);
bundle.putLong(FIELD_CURRENT_LIVE_OFFSET_MS, currentLiveOffsetMs);
bundle.putLong(FIELD_CONTENT_DURATION_MS, contentDurationMs);
bundle.putLong(FIELD_CONTENT_BUFFERED_POSITION_MS, contentBufferedPositionMs);
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);
return bundle;
}
......@@ -196,8 +207,7 @@ import com.google.common.base.Objects;
boolean isPlayingAd = bundle.getBoolean(FIELD_IS_PLAYING_AD, /* defaultValue= */ false);
long eventTimeMs = bundle.getLong(FIELD_EVENT_TIME_MS, /* defaultValue= */ C.TIME_UNSET);
long durationMs = bundle.getLong(FIELD_DURATION_MS, /* defaultValue= */ C.TIME_UNSET);
long bufferedPositionMs =
bundle.getLong(FIELD_BUFFERED_POSITION_MS, /* defaultValue= */ C.TIME_UNSET);
long bufferedPositionMs = bundle.getLong(FIELD_BUFFERED_POSITION_MS, /* defaultValue= */ 0);
int bufferedPercentage = bundle.getInt(FIELD_BUFFERED_PERCENTAGE, /* defaultValue= */ 0);
long totalBufferedDurationMs =
bundle.getLong(FIELD_TOTAL_BUFFERED_DURATION_MS, /* defaultValue= */ 0);
......@@ -206,7 +216,7 @@ import com.google.common.base.Objects;
long contentDurationMs =
bundle.getLong(FIELD_CONTENT_DURATION_MS, /* defaultValue= */ C.TIME_UNSET);
long contentBufferedPositionMs =
bundle.getLong(FIELD_CONTENT_BUFFERED_POSITION_MS, /* defaultValue= */ C.TIME_UNSET);
bundle.getLong(FIELD_CONTENT_BUFFERED_POSITION_MS, /* defaultValue= */ 0);
return new SessionPositionInfo(
positionInfo,
......
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