mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Exclude tracks if COMMAND_GET_TRACKS is not available
Issue: androidx/media#102 #minor-release PiperOrigin-RevId: 461891031
This commit is contained in:
parent
5adf708b43
commit
5bf9e2fb31
@ -121,7 +121,9 @@ import java.lang.annotation.Target;
|
||||
|| !playerCommandsFromSession.contains(Player.COMMAND_GET_MEDIA_ITEMS_METADATA),
|
||||
/* excludeCues= */ !playerCommandsFromPlayer.contains(Player.COMMAND_GET_TEXT)
|
||||
|| !playerCommandsFromSession.contains(Player.COMMAND_GET_TEXT),
|
||||
/* excludeTimeline= */ false));
|
||||
/* excludeTimeline= */ false,
|
||||
/* excludeTracks= */ !playerCommandsFromPlayer.contains(Player.COMMAND_GET_TRACKS)
|
||||
|| !playerCommandsFromSession.contains(Player.COMMAND_GET_TRACKS)));
|
||||
return bundle;
|
||||
}
|
||||
|
||||
|
@ -2395,9 +2395,9 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
listener.onMediaItemTransition(
|
||||
currentMediaItem, playerInfo.mediaItemTransitionReason));
|
||||
}
|
||||
if (!Util.areEqual(oldPlayerInfo.currentTracks, newPlayerInfo.currentTracks)) {
|
||||
if (!Util.areEqual(oldPlayerInfo.currentTracks, playerInfo.currentTracks)) {
|
||||
listeners.queueEvent(
|
||||
EVENT_TRACKS_CHANGED, listener -> listener.onTracksChanged(newPlayerInfo.currentTracks));
|
||||
EVENT_TRACKS_CHANGED, listener -> listener.onTracksChanged(playerInfo.currentTracks));
|
||||
}
|
||||
if (!Util.areEqual(oldPlayerInfo.playbackParameters, playerInfo.playbackParameters)) {
|
||||
listeners.queueEvent(
|
||||
|
@ -1070,7 +1070,8 @@ public class MediaSession {
|
||||
boolean excludeMediaItems,
|
||||
boolean excludeMediaItemsMetadata,
|
||||
boolean excludeCues,
|
||||
boolean excludeTimeline)
|
||||
boolean excludeTimeline,
|
||||
boolean excludeTracks)
|
||||
throws RemoteException {}
|
||||
|
||||
default void onPeriodicSessionPositionInfoChanged(
|
||||
|
@ -411,7 +411,10 @@ import org.checkerframework.checker.initialization.qual.Initialized;
|
||||
/* excludeCues= */ !sessionStub
|
||||
.getConnectedControllersManager()
|
||||
.isPlayerCommandAvailable(controller, Player.COMMAND_GET_TEXT),
|
||||
excludeTimeline);
|
||||
excludeTimeline,
|
||||
/* excludeTracks= */ !sessionStub
|
||||
.getConnectedControllersManager()
|
||||
.isPlayerCommandAvailable(controller, Player.COMMAND_GET_TRACKS));
|
||||
} catch (DeadObjectException e) {
|
||||
onDeadObjectException(controller);
|
||||
} catch (RemoteException e) {
|
||||
|
@ -1710,12 +1710,17 @@ import java.util.concurrent.ExecutionException;
|
||||
boolean excludeMediaItems,
|
||||
boolean excludeMediaItemsMetadata,
|
||||
boolean excludeCues,
|
||||
boolean excludeTimeline)
|
||||
boolean excludeTimeline,
|
||||
boolean excludeTracks)
|
||||
throws RemoteException {
|
||||
iController.onPlayerInfoChanged(
|
||||
seq,
|
||||
playerInfo.toBundle(
|
||||
excludeMediaItems, excludeMediaItemsMetadata, excludeCues, excludeTimeline),
|
||||
excludeMediaItems,
|
||||
excludeMediaItemsMetadata,
|
||||
excludeCues,
|
||||
excludeTimeline,
|
||||
excludeTracks),
|
||||
/* isTimelineExcluded= */ excludeTimeline);
|
||||
}
|
||||
|
||||
|
@ -754,7 +754,8 @@ import java.lang.annotation.Target;
|
||||
boolean excludeMediaItems,
|
||||
boolean excludeMediaItemsMetadata,
|
||||
boolean excludeCues,
|
||||
boolean excludeTimeline) {
|
||||
boolean excludeTimeline,
|
||||
boolean excludeTracks) {
|
||||
Bundle bundle = new Bundle();
|
||||
if (playerError != null) {
|
||||
bundle.putBundle(keyForField(FIELD_PLAYBACK_ERROR), playerError.toBundle());
|
||||
@ -794,7 +795,9 @@ import java.lang.annotation.Target;
|
||||
bundle.putLong(keyForField(FIELD_SEEK_FORWARD_INCREMENT_MS), seekForwardIncrementMs);
|
||||
bundle.putLong(
|
||||
keyForField(FIELD_MAX_SEEK_TO_PREVIOUS_POSITION_MS), maxSeekToPreviousPositionMs);
|
||||
bundle.putBundle(keyForField(FIELD_CURRENT_TRACKS), currentTracks.toBundle());
|
||||
if (!excludeTracks) {
|
||||
bundle.putBundle(keyForField(FIELD_CURRENT_TRACKS), currentTracks.toBundle());
|
||||
}
|
||||
bundle.putBundle(
|
||||
keyForField(FIELD_TRACK_SELECTION_PARAMETERS), trackSelectionParameters.toBundle());
|
||||
|
||||
@ -807,7 +810,8 @@ import java.lang.annotation.Target;
|
||||
/* excludeMediaItems= */ false,
|
||||
/* excludeMediaItemsMetadata= */ false,
|
||||
/* excludeCues= */ false,
|
||||
/* excludeTimeline= */ false);
|
||||
/* excludeTimeline= */ false,
|
||||
/* excludeTracks= */ false);
|
||||
}
|
||||
|
||||
/** Object that can restore {@link PlayerInfo} from a {@link Bundle}. */
|
||||
|
@ -26,10 +26,12 @@ public class MediaSessionConstants {
|
||||
public static final String TEST_WITH_CUSTOM_COMMANDS = "testWithCustomCommands";
|
||||
public static final String TEST_CONTROLLER_LISTENER_SESSION_REJECTS = "connection_sessionRejects";
|
||||
public static final String TEST_IS_SESSION_COMMAND_AVAILABLE = "testIsSessionCommandAvailable";
|
||||
public static final String TEST_COMMAND_GET_TRACKS = "testCommandGetTracksUnavailable";
|
||||
|
||||
// Bundle keys
|
||||
public static final String KEY_AVAILABLE_SESSION_COMMANDS = "availableSessionCommands";
|
||||
public static final String KEY_CONTROLLER = "controllerKey";
|
||||
public static final String KEY_COMMAND_GET_TASKS_UNAVAILABLE = "commandGetTasksUnavailable";
|
||||
|
||||
private MediaSessionConstants() {}
|
||||
}
|
||||
|
@ -29,7 +29,9 @@ import static androidx.media3.session.SessionResult.RESULT_SUCCESS;
|
||||
import static androidx.media3.test.session.common.CommonConstants.DEFAULT_TEST_NAME;
|
||||
import static androidx.media3.test.session.common.CommonConstants.MOCK_MEDIA3_LIBRARY_SERVICE;
|
||||
import static androidx.media3.test.session.common.CommonConstants.MOCK_MEDIA3_SESSION_SERVICE;
|
||||
import static androidx.media3.test.session.common.MediaSessionConstants.KEY_COMMAND_GET_TASKS_UNAVAILABLE;
|
||||
import static androidx.media3.test.session.common.MediaSessionConstants.KEY_CONTROLLER;
|
||||
import static androidx.media3.test.session.common.MediaSessionConstants.TEST_COMMAND_GET_TRACKS;
|
||||
import static androidx.media3.test.session.common.MediaSessionConstants.TEST_CONTROLLER_LISTENER_SESSION_REJECTS;
|
||||
import static androidx.media3.test.session.common.MediaSessionConstants.TEST_WITH_CUSTOM_COMMANDS;
|
||||
import static androidx.media3.test.session.common.TestUtils.LONG_TIMEOUT_MS;
|
||||
@ -878,6 +880,101 @@ public class MediaControllerListenerTest {
|
||||
assertThat(changedCurrentTracksFromGetterRef.get()).isEqualTo(currentTracks);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCurrentTracks_commandGetTracksUnavailable_currentTracksEmpty() throws Exception {
|
||||
RemoteMediaSession remoteSession = createRemoteMediaSession(TEST_COMMAND_GET_TRACKS);
|
||||
RemoteMediaSession.RemoteMockPlayer player = remoteSession.getMockPlayer();
|
||||
CountDownLatch latch = new CountDownLatch(2);
|
||||
// A controller with the COMMAND_GET_TRACKS unavailable.
|
||||
Bundle connectionHints = new Bundle();
|
||||
connectionHints.putBoolean(KEY_COMMAND_GET_TASKS_UNAVAILABLE, true);
|
||||
MediaController controller =
|
||||
controllerTestRule.createController(
|
||||
remoteSession.getToken(), connectionHints, /* listener= */ null);
|
||||
List<Tracks> capturedCurrentTracks = new ArrayList<>();
|
||||
Player.Listener listener =
|
||||
new Player.Listener() {
|
||||
@Override
|
||||
public void onEvents(Player player, Player.Events events) {
|
||||
capturedCurrentTracks.add(controller.getCurrentTracks());
|
||||
latch.countDown();
|
||||
}
|
||||
};
|
||||
// A controller with the COMMAND_GET_TRACKS available.
|
||||
MediaController controllerWithCommandAvailable =
|
||||
controllerTestRule.createController(remoteSession.getToken());
|
||||
AtomicReference<Tracks> capturedCurrentTracksWithCommandAvailable = new AtomicReference<>();
|
||||
Player.Listener listenerWithCommandAvailable =
|
||||
new Player.Listener() {
|
||||
@Override
|
||||
public void onEvents(Player player, Player.Events events) {
|
||||
capturedCurrentTracksWithCommandAvailable.set(player.getCurrentTracks());
|
||||
latch.countDown();
|
||||
}
|
||||
};
|
||||
AtomicReference<Tracks> initialCurrentTracks = new AtomicReference<>();
|
||||
AtomicReference<Tracks> initialCurrentTracksWithCommandAvailable = new AtomicReference<>();
|
||||
threadTestRule
|
||||
.getHandler()
|
||||
.postAndSync(
|
||||
() -> {
|
||||
initialCurrentTracks.set(controller.getCurrentTracks());
|
||||
initialCurrentTracksWithCommandAvailable.set(
|
||||
controllerWithCommandAvailable.getCurrentTracks());
|
||||
controller.addListener(listener);
|
||||
controllerWithCommandAvailable.addListener(listenerWithCommandAvailable);
|
||||
});
|
||||
|
||||
player.notifyIsLoadingChanged(true);
|
||||
|
||||
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||
assertThat(initialCurrentTracks.get()).isEqualTo(Tracks.EMPTY);
|
||||
assertThat(capturedCurrentTracks).containsExactly(Tracks.EMPTY);
|
||||
assertThat(initialCurrentTracksWithCommandAvailable.get().getGroups()).hasSize(1);
|
||||
assertThat(capturedCurrentTracksWithCommandAvailable.get().getGroups()).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCurrentTracks_commandGetTracksBecomesUnavailable_tracksResetToEmpty()
|
||||
throws Exception {
|
||||
RemoteMediaSession remoteSession = createRemoteMediaSession(TEST_COMMAND_GET_TRACKS);
|
||||
RemoteMediaSession.RemoteMockPlayer player = remoteSession.getMockPlayer();
|
||||
CountDownLatch latch = new CountDownLatch(2);
|
||||
// A controller with the COMMAND_GET_TRACKS available.
|
||||
MediaController controller = controllerTestRule.createController(remoteSession.getToken());
|
||||
List<Tracks> capturedCurrentTracks = new ArrayList<>();
|
||||
Player.Listener listener =
|
||||
new Player.Listener() {
|
||||
@Override
|
||||
public void onAvailableCommandsChanged(Commands availableCommands) {
|
||||
capturedCurrentTracks.add(controller.getCurrentTracks());
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTracksChanged(Tracks tracks) {
|
||||
// The track change as a result of the available command change is notified second.
|
||||
capturedCurrentTracks.add(controller.getCurrentTracks());
|
||||
latch.countDown();
|
||||
}
|
||||
};
|
||||
AtomicReference<Commands> availableCommands = new AtomicReference<>();
|
||||
threadTestRule
|
||||
.getHandler()
|
||||
.postAndSync(
|
||||
() -> {
|
||||
availableCommands.set(controller.getAvailableCommands());
|
||||
controller.addListener(listener);
|
||||
});
|
||||
|
||||
player.notifyAvailableCommandsChanged(
|
||||
availableCommands.get().buildUpon().remove(Player.COMMAND_GET_TRACKS).build());
|
||||
|
||||
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
|
||||
assertThat(capturedCurrentTracks.get(0).getGroups()).hasSize(1);
|
||||
assertThat(capturedCurrentTracks.get(1)).isEqualTo(Tracks.EMPTY);
|
||||
}
|
||||
|
||||
/** This also tests {@link MediaController#getShuffleModeEnabled()}. */
|
||||
@Test
|
||||
public void onShuffleModeEnabledChanged() throws Exception {
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package androidx.media3.session;
|
||||
|
||||
import static androidx.media3.common.Player.COMMAND_GET_TRACKS;
|
||||
import static androidx.media3.test.session.common.CommonConstants.ACTION_MEDIA3_SESSION;
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_AUDIO_ATTRIBUTES;
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_BUFFERED_PERCENTAGE;
|
||||
@ -55,7 +56,9 @@ import static androidx.media3.test.session.common.CommonConstants.KEY_TRACK_SELE
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_VIDEO_SIZE;
|
||||
import static androidx.media3.test.session.common.CommonConstants.KEY_VOLUME;
|
||||
import static androidx.media3.test.session.common.MediaSessionConstants.KEY_AVAILABLE_SESSION_COMMANDS;
|
||||
import static androidx.media3.test.session.common.MediaSessionConstants.KEY_COMMAND_GET_TASKS_UNAVAILABLE;
|
||||
import static androidx.media3.test.session.common.MediaSessionConstants.KEY_CONTROLLER;
|
||||
import static androidx.media3.test.session.common.MediaSessionConstants.TEST_COMMAND_GET_TRACKS;
|
||||
import static androidx.media3.test.session.common.MediaSessionConstants.TEST_CONTROLLER_LISTENER_SESSION_REJECTS;
|
||||
import static androidx.media3.test.session.common.MediaSessionConstants.TEST_GET_SESSION_ACTIVITY;
|
||||
import static androidx.media3.test.session.common.MediaSessionConstants.TEST_IS_SESSION_COMMAND_AVAILABLE;
|
||||
@ -71,6 +74,7 @@ import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.AudioAttributes;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.DeviceInfo;
|
||||
import androidx.media3.common.Format;
|
||||
import androidx.media3.common.MediaItem;
|
||||
import androidx.media3.common.MediaMetadata;
|
||||
import androidx.media3.common.PlaybackException;
|
||||
@ -79,6 +83,7 @@ import androidx.media3.common.Player;
|
||||
import androidx.media3.common.Player.DiscontinuityReason;
|
||||
import androidx.media3.common.Player.PositionInfo;
|
||||
import androidx.media3.common.Timeline;
|
||||
import androidx.media3.common.TrackGroup;
|
||||
import androidx.media3.common.TrackSelectionParameters;
|
||||
import androidx.media3.common.Tracks;
|
||||
import androidx.media3.common.VideoSize;
|
||||
@ -159,11 +164,10 @@ public class MediaSessionProviderService extends Service {
|
||||
|
||||
@Override
|
||||
public void create(String sessionId, Bundle tokenExtras) throws RemoteException {
|
||||
MockPlayer mockPlayer =
|
||||
new MockPlayer.Builder().setApplicationLooper(handler.getLooper()).build();
|
||||
MediaSession.Builder builder =
|
||||
new MediaSession.Builder(
|
||||
MediaSessionProviderService.this,
|
||||
new MockPlayer.Builder().setApplicationLooper(handler.getLooper()).build())
|
||||
.setId(sessionId);
|
||||
new MediaSession.Builder(MediaSessionProviderService.this, mockPlayer).setId(sessionId);
|
||||
|
||||
if (tokenExtras != null) {
|
||||
builder.setExtras(tokenExtras);
|
||||
@ -229,6 +233,34 @@ public class MediaSessionProviderService extends Service {
|
||||
});
|
||||
break;
|
||||
}
|
||||
case TEST_COMMAND_GET_TRACKS:
|
||||
{
|
||||
ImmutableList<Tracks.Group> trackGroups =
|
||||
ImmutableList.of(
|
||||
new Tracks.Group(
|
||||
new TrackGroup(new Format.Builder().setChannelCount(2).build()),
|
||||
/* adaptiveSupported= */ false,
|
||||
/* trackSupport= */ new int[1],
|
||||
/* trackSelected= */ new boolean[1]));
|
||||
mockPlayer.currentTracks = new Tracks(trackGroups);
|
||||
builder.setCallback(
|
||||
new MediaSession.Callback() {
|
||||
@Override
|
||||
public MediaSession.ConnectionResult onConnect(
|
||||
MediaSession session, ControllerInfo controller) {
|
||||
Player.Commands.Builder commandBuilder =
|
||||
new Player.Commands.Builder().addAllCommands();
|
||||
if (controller
|
||||
.getConnectionHints()
|
||||
.getBoolean(KEY_COMMAND_GET_TASKS_UNAVAILABLE, /* defaultValue= */ false)) {
|
||||
commandBuilder.remove(COMMAND_GET_TRACKS);
|
||||
}
|
||||
return MediaSession.ConnectionResult.accept(
|
||||
SessionCommands.EMPTY, commandBuilder.build());
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
default: // fall out
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user