diff --git a/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java b/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java index c70376d4fd..232a878f08 100644 --- a/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java +++ b/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java @@ -38,6 +38,7 @@ import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; @@ -99,7 +100,7 @@ public class TrackSelectionParameters implements Bundleable { private boolean forceLowestBitrate; private boolean forceHighestSupportedBitrate; private HashMap overrides; - private ImmutableSet<@C.TrackType Integer> disabledTrackTypes; + private HashSet<@C.TrackType Integer> disabledTrackTypes; /** * @deprecated {@link Context} constraints will not be set using this constructor. Use {@link @@ -132,7 +133,7 @@ public class TrackSelectionParameters implements Bundleable { forceLowestBitrate = false; forceHighestSupportedBitrate = false; overrides = new HashMap<>(); - disabledTrackTypes = ImmutableSet.of(); + disabledTrackTypes = new HashSet<>(); } /** @@ -239,21 +240,22 @@ public class TrackSelectionParameters implements Bundleable { bundle.getBoolean( keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE), DEFAULT_WITHOUT_CONTEXT.forceHighestSupportedBitrate); - overrides = new HashMap<>(); List overrideList = fromBundleNullableList( TrackSelectionOverride.CREATOR, bundle.getParcelableArrayList(keyForField(FIELD_SELECTION_OVERRIDES)), ImmutableList.of()); + overrides = new HashMap<>(); for (int i = 0; i < overrideList.size(); i++) { TrackSelectionOverride override = overrideList.get(i); overrides.put(override.trackGroup, override); } - disabledTrackTypes = - ImmutableSet.copyOf( - Ints.asList( - firstNonNull( - bundle.getIntArray(keyForField(FIELD_DISABLED_TRACK_TYPE)), new int[0]))); + int[] disabledTrackTypeArray = + firstNonNull(bundle.getIntArray(keyForField(FIELD_DISABLED_TRACK_TYPE)), new int[0]); + disabledTrackTypes = new HashSet<>(); + for (@C.TrackType int disabledTrackType : disabledTrackTypeArray) { + disabledTrackTypes.add(disabledTrackType); + } } /** Overrides the value of the builder with the value of {@link TrackSelectionParameters}. */ @@ -293,7 +295,7 @@ public class TrackSelectionParameters implements Bundleable { // General forceLowestBitrate = parameters.forceLowestBitrate; forceHighestSupportedBitrate = parameters.forceHighestSupportedBitrate; - disabledTrackTypes = parameters.disabledTrackTypes; + disabledTrackTypes = new HashSet<>(parameters.disabledTrackTypes); overrides = new HashMap<>(parameters.overrides); } @@ -695,13 +697,34 @@ public class TrackSelectionParameters implements Bundleable { /** * Sets the disabled track types, preventing all tracks of those types from being selected for - * playback. + * playback. Any previously disabled track types are cleared. * * @param disabledTrackTypes The track types to disable. * @return This builder. + * @deprecated Use {@link #setTrackTypeDisabled(int, boolean)}. */ + @Deprecated + @UnstableApi public Builder setDisabledTrackTypes(Set<@C.TrackType Integer> disabledTrackTypes) { - this.disabledTrackTypes = ImmutableSet.copyOf(disabledTrackTypes); + this.disabledTrackTypes.clear(); + this.disabledTrackTypes.addAll(disabledTrackTypes); + return this; + } + + /** + * Sets whether a track type is disabled. If disabled, no tracks of the specified type will be + * selected for playback. + * + * @param trackType The track type. + * @param disabled Whether the track type should be disabled. + * @return This builder. + */ + public Builder setTrackTypeDisabled(@C.TrackType int trackType, boolean disabled) { + if (disabled) { + disabledTrackTypes.add(trackType); + } else { + disabledTrackTypes.remove(trackType); + } return this; } @@ -936,7 +959,7 @@ public class TrackSelectionParameters implements Bundleable { this.forceLowestBitrate = builder.forceLowestBitrate; this.forceHighestSupportedBitrate = builder.forceHighestSupportedBitrate; this.overrides = ImmutableMap.copyOf(builder.overrides); - this.disabledTrackTypes = builder.disabledTrackTypes; + this.disabledTrackTypes = ImmutableSet.copyOf(builder.disabledTrackTypes); } /** Creates a new {@link Builder}, copying the initial values from this instance. */ diff --git a/libraries/common/src/test/java/androidx/media3/common/TrackSelectionParametersTest.java b/libraries/common/src/test/java/androidx/media3/common/TrackSelectionParametersTest.java index d11efe782d..21b90e6253 100644 --- a/libraries/common/src/test/java/androidx/media3/common/TrackSelectionParametersTest.java +++ b/libraries/common/src/test/java/androidx/media3/common/TrackSelectionParametersTest.java @@ -20,7 +20,6 @@ import static com.google.common.truth.Truth.assertThat; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import org.junit.Test; import org.junit.runner.RunWith; @@ -109,7 +108,8 @@ public final class TrackSelectionParametersTest { new Format.Builder().setId(4).build(), new Format.Builder().setId(5).build()), /* trackIndices= */ ImmutableList.of(1))) - .setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_TEXT)) + .setTrackTypeDisabled(C.TRACK_TYPE_AUDIO, /* disabled= */ true) + .setTrackTypeDisabled(C.TRACK_TYPE_TEXT, /* disabled= */ true) .build(); // Video diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelector.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelector.java index 6361c53e45..3f6d673a14 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelector.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelector.java @@ -627,11 +627,19 @@ public class DefaultTrackSelector extends MappingTrackSelector { } @Override + @Deprecated + @SuppressWarnings("deprecation") public ParametersBuilder setDisabledTrackTypes(Set<@C.TrackType Integer> disabledTrackTypes) { super.setDisabledTrackTypes(disabledTrackTypes); return this; } + @Override + public ParametersBuilder setTrackTypeDisabled(@C.TrackType int trackType, boolean disabled) { + super.setTrackTypeDisabled(trackType, disabled); + return this; + } + /** * Sets whether to exceed renderer capabilities when no selection can be made otherwise. * diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelectorTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelectorTest.java index 442725a2f5..504a724cc4 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelectorTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelectorTest.java @@ -392,7 +392,9 @@ public final class DefaultTrackSelectorTest { public void selectVideoAudioTracks_withDisabledAudioType_onlyVideoIsSelected() throws ExoPlaybackException { trackSelector.setParameters( - defaultParameters.buildUpon().setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO))); + defaultParameters + .buildUpon() + .setTrackTypeDisabled(C.TRACK_TYPE_AUDIO, /* disabled= */ true)); TrackSelectorResult result = trackSelector.selectTracks( @@ -407,11 +409,12 @@ public final class DefaultTrackSelectorTest { /** Tests that a disabled track type can be enabled again. */ @Test + @SuppressWarnings("deprecation") public void selectTracks_withClearedDisabledTrackType_selectsAll() throws ExoPlaybackException { trackSelector.setParameters( trackSelector .buildUponParameters() - .setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO)) + .setTrackTypeDisabled(C.TRACK_TYPE_AUDIO, /* disabled= */ true) .setDisabledTrackTypes(ImmutableSet.of())); TrackSelectorResult result = @@ -426,7 +429,9 @@ public final class DefaultTrackSelectorTest { public void selectTracks_withDisabledNoneTracksAndNoSampleRenderer_disablesNoSampleRenderer() throws ExoPlaybackException { trackSelector.setParameters( - defaultParameters.buildUpon().setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_NONE))); + defaultParameters + .buildUpon() + .setTrackTypeDisabled(C.TRACK_TYPE_NONE, /* disabled= */ true)); TrackSelectorResult result = trackSelector.selectTracks( diff --git a/libraries/ui/src/main/java/androidx/media3/ui/PlayerControlView.java b/libraries/ui/src/main/java/androidx/media3/ui/PlayerControlView.java index 35f5cabd5d..42b972c984 100644 --- a/libraries/ui/src/main/java/androidx/media3/ui/PlayerControlView.java +++ b/libraries/ui/src/main/java/androidx/media3/ui/PlayerControlView.java @@ -74,15 +74,12 @@ import androidx.media3.common.util.Util; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Formatter; -import java.util.HashSet; import java.util.List; import java.util.Locale; -import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; /** @@ -1867,11 +1864,7 @@ public class PlayerControlView extends FrameLayout { player.setTrackSelectionParameters( trackSelectionParameters .buildUpon() - .setDisabledTrackTypes( - new ImmutableSet.Builder<@C.TrackType Integer>() - .addAll(trackSelectionParameters.disabledTrackTypes) - .add(C.TRACK_TYPE_TEXT) - .build()) + .setTrackTypeDisabled(C.TRACK_TYPE_TEXT, /* disabled= */ true) .build()); settingsWindow.dismiss(); } @@ -1910,15 +1903,12 @@ public class PlayerControlView extends FrameLayout { } TrackSelectionParameters trackSelectionParameters = player.getTrackSelectionParameters(); - Set<@C.TrackType Integer> disabledTrackTypes = - new HashSet<>(trackSelectionParameters.disabledTrackTypes); - disabledTrackTypes.remove(C.TRACK_TYPE_AUDIO); castNonNull(player) .setTrackSelectionParameters( trackSelectionParameters .buildUpon() .clearOverridesOfType(C.TRACK_TYPE_AUDIO) - .setDisabledTrackTypes(disabledTrackTypes) + .setTrackTypeDisabled(C.TRACK_TYPE_AUDIO, /* disabled= */ false) .build()); settingsAdapter.setSubTextAtPosition( SETTINGS_AUDIO_TRACK_SELECTION_POSITION, @@ -1995,6 +1985,7 @@ public class PlayerControlView extends FrameLayout { @Override public void onBindViewHolder(SubSettingViewHolder holder, int position) { + @Nullable Player player = PlayerControlView.this.player; if (player == null) { return; } @@ -2003,29 +1994,23 @@ public class PlayerControlView extends FrameLayout { } else { TrackInformation track = tracks.get(position - 1); TrackGroup trackGroup = track.trackGroupInfo.getTrackGroup(); - TrackSelectionParameters params = checkNotNull(player).getTrackSelectionParameters(); + TrackSelectionParameters params = player.getTrackSelectionParameters(); boolean explicitlySelected = params.overrides.get(trackGroup) != null && track.isSelected(); holder.textView.setText(track.trackName); holder.checkView.setVisibility(explicitlySelected ? VISIBLE : INVISIBLE); holder.itemView.setOnClickListener( v -> { - if (player == null) { - return; - } TrackSelectionParameters trackSelectionParameters = player.getTrackSelectionParameters(); - Set<@C.TrackType Integer> disabledTrackTypes = - new HashSet<>(trackSelectionParameters.disabledTrackTypes); - disabledTrackTypes.remove(track.trackGroupInfo.getTrackType()); - checkNotNull(player) - .setTrackSelectionParameters( - trackSelectionParameters - .buildUpon() - .setOverrideForType( - new TrackSelectionOverride( - trackGroup, ImmutableList.of(track.trackIndex))) - .setDisabledTrackTypes(disabledTrackTypes) - .build()); + player.setTrackSelectionParameters( + trackSelectionParameters + .buildUpon() + .setOverrideForType( + new TrackSelectionOverride( + trackGroup, ImmutableList.of(track.trackIndex))) + .setTrackTypeDisabled( + track.trackGroupInfo.getTrackType(), /* disabled= */ false) + .build()); onTrackSelection(track.trackName); settingsWindow.dismiss(); });