From 68c310a94a32eb49498458fd6c424c414b793e34 Mon Sep 17 00:00:00 2001 From: olly Date: Mon, 28 Feb 2022 13:05:17 +0000 Subject: [PATCH] TrackSelectionParameters: Simplify disabling of track types As evidenced by the somewhat awkward logic in PlayerControlView, the previous design wasn't very friendly to expected usage. There will be more usage when the track selection dialog components are migrated, which would be similarly awkward without this change. PiperOrigin-RevId: 431407675 --- .../common/TrackSelectionParameters.java | 47 ++++++++++++++----- .../common/TrackSelectionParametersTest.java | 4 +- .../trackselection/DefaultTrackSelector.java | 8 ++++ .../DefaultTrackSelectorTest.java | 11 +++-- .../androidx/media3/ui/PlayerControlView.java | 41 +++++----------- 5 files changed, 66 insertions(+), 45 deletions(-) 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(); });