diff --git a/libraries/common/src/main/java/androidx/media3/common/TrackSelectionOverride.java b/libraries/common/src/main/java/androidx/media3/common/TrackSelectionOverride.java new file mode 100644 index 0000000000..77b9c2bbf1 --- /dev/null +++ b/libraries/common/src/main/java/androidx/media3/common/TrackSelectionOverride.java @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package androidx.media3.common; + +import static androidx.media3.common.util.Assertions.checkNotNull; +import static java.util.Collections.max; +import static java.util.Collections.min; + +import android.os.Bundle; +import androidx.annotation.IntDef; +import androidx.annotation.Nullable; +import androidx.media3.common.util.UnstableApi; +import com.google.common.collect.ImmutableList; +import com.google.common.primitives.Ints; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.List; + +/** + * Forces the selection of {@link #trackIndices} for a {@link TrackGroup}. + * + *

If multiple tracks in {@link #trackGroup} are overridden, as many as possible will be selected + * depending on the player capabilities. + * + *

If {@link #trackIndices} is empty, no tracks from {@link #trackGroup} will be played. This is + * similar to {@link TrackSelectionParameters#disabledTrackTypes}, except it will only affect the + * playback of the associated {@link TrackGroup}. For example, if the only {@link + * C#TRACK_TYPE_VIDEO} {@link TrackGroup} is associated with no tracks, no video will play until the + * next video starts. + */ +public final class TrackSelectionOverride implements Bundleable { + + /** The {@link TrackGroup} whose {@link #trackIndices} are forced to be selected. */ + public final TrackGroup trackGroup; + /** The indices of tracks in a {@link TrackGroup} to be selected. */ + public final ImmutableList trackIndices; + + @Documented + @Retention(RetentionPolicy.SOURCE) + @IntDef({ + FIELD_TRACK_GROUP, + FIELD_TRACKS, + }) + private @interface FieldNumber {} + + private static final int FIELD_TRACK_GROUP = 0; + private static final int FIELD_TRACKS = 1; + + /** Constructs an instance to force all tracks in {@code trackGroup} to be selected. */ + public TrackSelectionOverride(TrackGroup trackGroup) { + this.trackGroup = trackGroup; + ImmutableList.Builder builder = new ImmutableList.Builder<>(); + for (int i = 0; i < trackGroup.length; i++) { + builder.add(i); + } + this.trackIndices = builder.build(); + } + + /** + * Constructs an instance to force {@code trackIndices} in {@code trackGroup} to be selected. + * + * @param trackGroup The {@link TrackGroup} for which to override the track selection. + * @param trackIndices The indices of the tracks in the {@link TrackGroup} to select. + */ + public TrackSelectionOverride(TrackGroup trackGroup, List trackIndices) { + if (!trackIndices.isEmpty()) { + if (min(trackIndices) < 0 || max(trackIndices) >= trackGroup.length) { + throw new IndexOutOfBoundsException(); + } + } + this.trackGroup = trackGroup; + this.trackIndices = ImmutableList.copyOf(trackIndices); + } + + /** Returns the {@link C.TrackType} of the overridden track group. */ + public @C.TrackType int getTrackType() { + return MimeTypes.getTrackType(trackGroup.getFormat(0).sampleMimeType); + } + + @Override + public boolean equals(@Nullable Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + TrackSelectionOverride that = (TrackSelectionOverride) obj; + return trackGroup.equals(that.trackGroup) && trackIndices.equals(that.trackIndices); + } + + @Override + public int hashCode() { + return trackGroup.hashCode() + 31 * trackIndices.hashCode(); + } + + // Bundleable implementation + + @UnstableApi + @Override + public Bundle toBundle() { + Bundle bundle = new Bundle(); + bundle.putBundle(keyForField(FIELD_TRACK_GROUP), trackGroup.toBundle()); + bundle.putIntArray(keyForField(FIELD_TRACKS), Ints.toArray(trackIndices)); + return bundle; + } + + /** Object that can restore {@code TrackSelectionOverride} from a {@link Bundle}. */ + @UnstableApi + public static final Creator CREATOR = + bundle -> { + @Nullable Bundle trackGroupBundle = bundle.getBundle(keyForField(FIELD_TRACK_GROUP)); + checkNotNull(trackGroupBundle); // Mandatory as there are no reasonable defaults. + TrackGroup trackGroup = TrackGroup.CREATOR.fromBundle(trackGroupBundle); + @Nullable int[] tracks = bundle.getIntArray(keyForField(FIELD_TRACKS)); + if (tracks == null) { + return new TrackSelectionOverride(trackGroup); + } + return new TrackSelectionOverride(trackGroup, Ints.asList(tracks)); + }; + + private static String keyForField(@FieldNumber int field) { + return Integer.toString(field, Character.MAX_RADIX); + } +} diff --git a/libraries/common/src/main/java/androidx/media3/common/TrackSelectionOverrides.java b/libraries/common/src/main/java/androidx/media3/common/TrackSelectionOverrides.java deleted file mode 100644 index 16fffadb49..0000000000 --- a/libraries/common/src/main/java/androidx/media3/common/TrackSelectionOverrides.java +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package androidx.media3.common; - -import static androidx.media3.common.util.Assertions.checkNotNull; -import static androidx.media3.common.util.BundleableUtil.fromBundleNullableList; -import static androidx.media3.common.util.BundleableUtil.toBundleArrayList; -import static java.lang.annotation.ElementType.TYPE_USE; -import static java.util.Collections.max; -import static java.util.Collections.min; - -import android.os.Bundle; -import androidx.annotation.IntDef; -import androidx.annotation.Nullable; -import androidx.media3.common.util.UnstableApi; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.primitives.Ints; -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -/** - * Forces the selection of the specified tracks in {@link TrackGroup TrackGroups}. - * - *

Each {@link TrackSelectionOverride override} only affects the selection of tracks of that - * {@link C.TrackType type}. For example overriding the selection of an {@link C#TRACK_TYPE_AUDIO - * audio} {@link TrackGroup} will not affect the selection of {@link C#TRACK_TYPE_VIDEO video} or - * {@link C#TRACK_TYPE_TEXT text} tracks. - * - *

If multiple {@link TrackGroup TrackGroups} of the same {@link C.TrackType} are overridden, - * which tracks will be selected depend on the player capabilities. For example, by default {@code - * ExoPlayer} doesn't support selecting more than one {@link TrackGroup} per {@link C.TrackType}. - * - *

Overrides of {@link TrackGroup} that are not currently available are ignored. For example, - * when the player transitions to the next {@link MediaItem} in a playlist, any overrides of the - * previous {@link MediaItem} are ignored. - * - * @see TrackSelectionParameters#trackSelectionOverrides - */ -public final class TrackSelectionOverrides implements Bundleable { - - /** Builder for {@link TrackSelectionOverrides}. */ - public static final class Builder { - // Cannot use ImmutableMap.Builder as it doesn't support removing entries. - private final HashMap overrides; - - /** Creates an builder with no {@link TrackSelectionOverride}. */ - public Builder() { - overrides = new HashMap<>(); - } - - private Builder(Map overrides) { - this.overrides = new HashMap<>(overrides); - } - - /** Adds an override for the provided {@link TrackGroup}. */ - @UnstableApi - public Builder addOverride(TrackSelectionOverride override) { - overrides.put(override.trackGroup, override); - return this; - } - - /** Removes the override associated with the provided {@link TrackGroup} if present. */ - @UnstableApi - public Builder clearOverride(TrackGroup trackGroup) { - overrides.remove(trackGroup); - return this; - } - - /** Set the override for the type of the provided {@link TrackGroup}. */ - public Builder setOverrideForType(TrackSelectionOverride override) { - clearOverridesOfType(override.getTrackType()); - overrides.put(override.trackGroup, override); - return this; - } - - /** - * Remove any override associated with {@link TrackGroup TrackGroups} of type {@code trackType}. - */ - public Builder clearOverridesOfType(@C.TrackType int trackType) { - for (Iterator it = overrides.values().iterator(); it.hasNext(); ) { - TrackSelectionOverride trackSelectionOverride = it.next(); - if (trackSelectionOverride.getTrackType() == trackType) { - it.remove(); - } - } - return this; - } - - /** Returns a new {@link TrackSelectionOverrides} instance with the current builder values. */ - public TrackSelectionOverrides build() { - return new TrackSelectionOverrides(overrides); - } - } - - /** - * Forces the selection of {@link #trackIndices} for a {@link TrackGroup}. - * - *

If multiple tracks in {@link #trackGroup} are overridden, as many as possible will be - * selected depending on the player capabilities. - * - *

If {@link #trackIndices} is empty, no tracks from {@link #trackGroup} will be played. This - * is similar to {@link TrackSelectionParameters#disabledTrackTypes}, except it will only affect - * the playback of the associated {@link TrackGroup}. For example, if the only {@link - * C#TRACK_TYPE_VIDEO} {@link TrackGroup} is associated with no tracks, no video will play until - * the next video starts. - */ - public static final class TrackSelectionOverride implements Bundleable { - - /** The {@link TrackGroup} whose {@link #trackIndices} are forced to be selected. */ - public final TrackGroup trackGroup; - /** The indices of tracks in a {@link TrackGroup} to be selected. */ - public final ImmutableList trackIndices; - - /** Constructs an instance to force all tracks in {@code trackGroup} to be selected. */ - public TrackSelectionOverride(TrackGroup trackGroup) { - this.trackGroup = trackGroup; - ImmutableList.Builder builder = new ImmutableList.Builder<>(); - for (int i = 0; i < trackGroup.length; i++) { - builder.add(i); - } - this.trackIndices = builder.build(); - } - - /** - * Constructs an instance to force {@code trackIndices} in {@code trackGroup} to be selected. - * - * @param trackGroup The {@link TrackGroup} for which to override the track selection. - * @param trackIndices The indices of the tracks in the {@link TrackGroup} to select. - */ - public TrackSelectionOverride(TrackGroup trackGroup, List trackIndices) { - if (!trackIndices.isEmpty()) { - if (min(trackIndices) < 0 || max(trackIndices) >= trackGroup.length) { - throw new IndexOutOfBoundsException(); - } - } - this.trackGroup = trackGroup; - this.trackIndices = ImmutableList.copyOf(trackIndices); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - TrackSelectionOverride that = (TrackSelectionOverride) obj; - return trackGroup.equals(that.trackGroup) && trackIndices.equals(that.trackIndices); - } - - @Override - public int hashCode() { - return trackGroup.hashCode() + 31 * trackIndices.hashCode(); - } - - /** Returns the {@link C.TrackType} of the overriden track group. */ - public @C.TrackType int getTrackType() { - return MimeTypes.getTrackType(trackGroup.getFormat(0).sampleMimeType); - } - - // Bundleable implementation - - @Documented - @Retention(RetentionPolicy.SOURCE) - @Target(TYPE_USE) - @IntDef({ - FIELD_TRACK_GROUP, - FIELD_TRACKS, - }) - private @interface FieldNumber {} - - private static final int FIELD_TRACK_GROUP = 0; - private static final int FIELD_TRACKS = 1; - - @UnstableApi - @Override - public Bundle toBundle() { - Bundle bundle = new Bundle(); - bundle.putBundle(keyForField(FIELD_TRACK_GROUP), trackGroup.toBundle()); - bundle.putIntArray(keyForField(FIELD_TRACKS), Ints.toArray(trackIndices)); - return bundle; - } - - /** Object that can restore {@code TrackSelectionOverride} from a {@link Bundle}. */ - @UnstableApi - public static final Creator CREATOR = - bundle -> { - @Nullable Bundle trackGroupBundle = bundle.getBundle(keyForField(FIELD_TRACK_GROUP)); - checkNotNull(trackGroupBundle); // Mandatory as there are no reasonable defaults. - TrackGroup trackGroup = TrackGroup.CREATOR.fromBundle(trackGroupBundle); - @Nullable int[] tracks = bundle.getIntArray(keyForField(FIELD_TRACKS)); - if (tracks == null) { - return new TrackSelectionOverride(trackGroup); - } - return new TrackSelectionOverride(trackGroup, Ints.asList(tracks)); - }; - - private static String keyForField(@FieldNumber int field) { - return Integer.toString(field, Character.MAX_RADIX); - } - } - - /** Empty {@code TrackSelectionOverrides}, where no track selection is overridden. */ - public static final TrackSelectionOverrides EMPTY = - new TrackSelectionOverrides(ImmutableMap.of()); - - private final ImmutableMap overrides; - - private TrackSelectionOverrides(Map overrides) { - this.overrides = ImmutableMap.copyOf(overrides); - } - - /** Returns a {@link Builder} initialized with the values of this instance. */ - public Builder buildUpon() { - return new Builder(overrides); - } - - /** Returns a list of the {@link TrackSelectionOverride overrides}. */ - @UnstableApi - public ImmutableList asList() { - return ImmutableList.copyOf(overrides.values()); - } - - /** - * Returns the {@link TrackSelectionOverride} of the provided {@link TrackGroup} or {@code null} - * if there is none. - */ - @Nullable - public TrackSelectionOverride getOverride(TrackGroup trackGroup) { - return overrides.get(trackGroup); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - TrackSelectionOverrides that = (TrackSelectionOverrides) obj; - return overrides.equals(that.overrides); - } - - @Override - public int hashCode() { - return overrides.hashCode(); - } - - // Bundleable implementation - - @Documented - @Retention(RetentionPolicy.SOURCE) - @Target(TYPE_USE) - @IntDef({ - FIELD_OVERRIDES, - }) - private @interface FieldNumber {} - - private static final int FIELD_OVERRIDES = 0; - - @UnstableApi - @Override - public Bundle toBundle() { - Bundle bundle = new Bundle(); - bundle.putParcelableArrayList( - keyForField(FIELD_OVERRIDES), toBundleArrayList(overrides.values())); - return bundle; - } - - /** Object that can restore {@code TrackSelectionOverrides} from a {@link Bundle}. */ - @UnstableApi - public static final Creator CREATOR = - bundle -> { - List trackSelectionOverrides = - fromBundleNullableList( - TrackSelectionOverride.CREATOR, - bundle.getParcelableArrayList(keyForField(FIELD_OVERRIDES)), - ImmutableList.of()); - ImmutableMap.Builder builder = - new ImmutableMap.Builder<>(); - for (int i = 0; i < trackSelectionOverrides.size(); i++) { - TrackSelectionOverride trackSelectionOverride = trackSelectionOverrides.get(i); - builder.put(trackSelectionOverride.trackGroup, trackSelectionOverride); - } - return new TrackSelectionOverrides(builder.buildOrThrow()); - }; - - private static String keyForField(@FieldNumber int field) { - return Integer.toString(field, Character.MAX_RADIX); - } -} 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 91ac8c3a9d..c70376d4fd 100644 --- a/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java +++ b/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java @@ -16,9 +16,9 @@ package androidx.media3.common; import static androidx.media3.common.util.Assertions.checkNotNull; -import static androidx.media3.common.util.BundleableUtil.fromNullableBundle; +import static androidx.media3.common.util.BundleableUtil.fromBundleNullableList; +import static androidx.media3.common.util.BundleableUtil.toBundleArrayList; import static com.google.common.base.MoreObjects.firstNonNull; -import static java.lang.annotation.ElementType.TYPE_USE; import android.content.Context; import android.graphics.Point; @@ -31,12 +31,15 @@ import androidx.annotation.RequiresApi; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.primitives.Ints; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; import java.util.Locale; import java.util.Set; import org.checkerframework.checker.initialization.qual.UnknownInitialization; @@ -95,7 +98,7 @@ public class TrackSelectionParameters implements Bundleable { // General private boolean forceLowestBitrate; private boolean forceHighestSupportedBitrate; - private TrackSelectionOverrides trackSelectionOverrides; + private HashMap overrides; private ImmutableSet<@C.TrackType Integer> disabledTrackTypes; /** @@ -128,7 +131,7 @@ public class TrackSelectionParameters implements Bundleable { // General forceLowestBitrate = false; forceHighestSupportedBitrate = false; - trackSelectionOverrides = TrackSelectionOverrides.EMPTY; + overrides = new HashMap<>(); disabledTrackTypes = ImmutableSet.of(); } @@ -236,11 +239,16 @@ public class TrackSelectionParameters implements Bundleable { bundle.getBoolean( keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE), DEFAULT_WITHOUT_CONTEXT.forceHighestSupportedBitrate); - trackSelectionOverrides = - fromNullableBundle( - TrackSelectionOverrides.CREATOR, - bundle.getBundle(keyForField(FIELD_SELECTION_OVERRIDE_KEYS)), - TrackSelectionOverrides.EMPTY); + overrides = new HashMap<>(); + List overrideList = + fromBundleNullableList( + TrackSelectionOverride.CREATOR, + bundle.getParcelableArrayList(keyForField(FIELD_SELECTION_OVERRIDES)), + ImmutableList.of()); + for (int i = 0; i < overrideList.size(); i++) { + TrackSelectionOverride override = overrideList.get(i); + overrides.put(override.trackGroup, override); + } disabledTrackTypes = ImmutableSet.copyOf( Ints.asList( @@ -254,7 +262,7 @@ public class TrackSelectionParameters implements Bundleable { "preferredAudioLanguages", "preferredAudioMimeTypes", "preferredTextLanguages", - "trackSelectionOverrides", + "overrides", "disabledTrackTypes", }) private void init(@UnknownInitialization Builder this, TrackSelectionParameters parameters) { @@ -285,8 +293,8 @@ public class TrackSelectionParameters implements Bundleable { // General forceLowestBitrate = parameters.forceLowestBitrate; forceHighestSupportedBitrate = parameters.forceHighestSupportedBitrate; - trackSelectionOverrides = parameters.trackSelectionOverrides; disabledTrackTypes = parameters.disabledTrackTypes; + overrides = new HashMap<>(parameters.overrides); } /** Overrides the value of the builder with the value of {@link TrackSelectionParameters}. */ @@ -646,14 +654,42 @@ public class TrackSelectionParameters implements Bundleable { return this; } + /** Adds an override for the provided {@link TrackGroup}. */ + public Builder addOverride(TrackSelectionOverride override) { + overrides.put(override.trackGroup, override); + return this; + } + + /** Removes the override associated with the provided {@link TrackGroup} if present. */ + public Builder clearOverride(TrackGroup trackGroup) { + overrides.remove(trackGroup); + return this; + } + + /** Set the override for the type of the provided {@link TrackGroup}. */ + public Builder setOverrideForType(TrackSelectionOverride override) { + clearOverridesOfType(override.getTrackType()); + overrides.put(override.trackGroup, override); + return this; + } + /** - * Sets the selection overrides. - * - * @param trackSelectionOverrides The track selection overrides. - * @return This builder. + * Remove any override associated with {@link TrackGroup TrackGroups} of type {@code trackType}. */ - public Builder setTrackSelectionOverrides(TrackSelectionOverrides trackSelectionOverrides) { - this.trackSelectionOverrides = trackSelectionOverrides; + public Builder clearOverridesOfType(@C.TrackType int trackType) { + Iterator it = overrides.values().iterator(); + while (it.hasNext()) { + TrackSelectionOverride override = it.next(); + if (override.getTrackType() == trackType) { + it.remove(); + } + } + return this; + } + + /** Removes all track overrides. */ + public Builder clearOverrides() { + overrides.clear(); return this; } @@ -860,8 +896,9 @@ public class TrackSelectionParameters implements Bundleable { */ public final boolean forceHighestSupportedBitrate; - /** Overrides to force tracks to be selected. */ - public final TrackSelectionOverrides trackSelectionOverrides; + /** Overrides to force selection of specific tracks. */ + public final ImmutableMap overrides; + /** * The track types that are disabled. No track of a disabled type will be selected, thus no track * type contained in the set will be played. The default value is that no track type is disabled @@ -898,7 +935,7 @@ public class TrackSelectionParameters implements Bundleable { // General this.forceLowestBitrate = builder.forceLowestBitrate; this.forceHighestSupportedBitrate = builder.forceHighestSupportedBitrate; - this.trackSelectionOverrides = builder.trackSelectionOverrides; + this.overrides = ImmutableMap.copyOf(builder.overrides); this.disabledTrackTypes = builder.disabledTrackTypes; } @@ -943,7 +980,7 @@ public class TrackSelectionParameters implements Bundleable { // General && forceLowestBitrate == other.forceLowestBitrate && forceHighestSupportedBitrate == other.forceHighestSupportedBitrate - && trackSelectionOverrides.equals(other.trackSelectionOverrides) + && overrides.equals(other.overrides) && disabledTrackTypes.equals(other.disabledTrackTypes); } @@ -977,7 +1014,7 @@ public class TrackSelectionParameters implements Bundleable { // General result = 31 * result + (forceLowestBitrate ? 1 : 0); result = 31 * result + (forceHighestSupportedBitrate ? 1 : 0); - result = 31 * result + trackSelectionOverrides.hashCode(); + result = 31 * result + overrides.hashCode(); result = 31 * result + disabledTrackTypes.hashCode(); return result; } @@ -986,7 +1023,6 @@ public class TrackSelectionParameters implements Bundleable { @Documented @Retention(RetentionPolicy.SOURCE) - @Target(TYPE_USE) @IntDef({ FIELD_PREFERRED_AUDIO_LANGUAGES, FIELD_PREFERRED_AUDIO_ROLE_FLAGS, @@ -1010,8 +1046,7 @@ public class TrackSelectionParameters implements Bundleable { FIELD_PREFERRED_AUDIO_MIME_TYPES, FIELD_FORCE_LOWEST_BITRATE, FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE, - FIELD_SELECTION_OVERRIDE_KEYS, - FIELD_SELECTION_OVERRIDE_VALUES, + FIELD_SELECTION_OVERRIDES, FIELD_DISABLED_TRACK_TYPE, FIELD_PREFERRED_VIDEO_ROLE_FLAGS }) @@ -1039,10 +1074,9 @@ public class TrackSelectionParameters implements Bundleable { private static final int FIELD_PREFERRED_AUDIO_MIME_TYPES = 20; private static final int FIELD_FORCE_LOWEST_BITRATE = 21; private static final int FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE = 22; - private static final int FIELD_SELECTION_OVERRIDE_KEYS = 23; - private static final int FIELD_SELECTION_OVERRIDE_VALUES = 24; - private static final int FIELD_DISABLED_TRACK_TYPE = 25; - private static final int FIELD_PREFERRED_VIDEO_ROLE_FLAGS = 26; + private static final int FIELD_SELECTION_OVERRIDES = 23; + private static final int FIELD_DISABLED_TRACK_TYPE = 24; + private static final int FIELD_PREFERRED_VIDEO_ROLE_FLAGS = 25; @UnstableApi @Override @@ -1086,8 +1120,8 @@ public class TrackSelectionParameters implements Bundleable { bundle.putBoolean(keyForField(FIELD_FORCE_LOWEST_BITRATE), forceLowestBitrate); bundle.putBoolean( keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE), forceHighestSupportedBitrate); - bundle.putBundle( - keyForField(FIELD_SELECTION_OVERRIDE_KEYS), trackSelectionOverrides.toBundle()); + bundle.putParcelableArrayList( + keyForField(FIELD_SELECTION_OVERRIDES), toBundleArrayList(overrides.values())); bundle.putIntArray(keyForField(FIELD_DISABLED_TRACK_TYPE), Ints.toArray(disabledTrackTypes)); return bundle; diff --git a/libraries/common/src/test/java/androidx/media3/common/TrackSelectionOverrideTest.java b/libraries/common/src/test/java/androidx/media3/common/TrackSelectionOverrideTest.java new file mode 100644 index 0000000000..1de9157adb --- /dev/null +++ b/libraries/common/src/test/java/androidx/media3/common/TrackSelectionOverrideTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package androidx.media3.common; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import com.google.common.collect.ImmutableList; +import java.util.Arrays; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** Unit tests for {@link TrackSelectionOverride}. */ +@RunWith(AndroidJUnit4.class) +public final class TrackSelectionOverrideTest { + + @Test + public void newTrackSelectionOverride_withJustTrackGroup_selectsAllTracks() { + TrackSelectionOverride trackSelectionOverride = + new TrackSelectionOverride(newTrackGroupWithIds(1, 2)); + + assertThat(trackSelectionOverride.trackGroup).isEqualTo(newTrackGroupWithIds(1, 2)); + assertThat(trackSelectionOverride.trackIndices).containsExactly(0, 1).inOrder(); + } + + @Test + public void newTrackSelectionOverride_withTracks_selectsOnlySpecifiedTracks() { + TrackSelectionOverride trackSelectionOverride = + new TrackSelectionOverride(newTrackGroupWithIds(1, 2), ImmutableList.of(1)); + + assertThat(trackSelectionOverride.trackGroup).isEqualTo(newTrackGroupWithIds(1, 2)); + assertThat(trackSelectionOverride.trackIndices).containsExactly(1); + } + + @Test + public void newTrackSelectionOverride_with0Tracks_selectsAllSpecifiedTracks() { + TrackSelectionOverride trackSelectionOverride = + new TrackSelectionOverride(newTrackGroupWithIds(1, 2), ImmutableList.of()); + + assertThat(trackSelectionOverride.trackGroup).isEqualTo(newTrackGroupWithIds(1, 2)); + assertThat(trackSelectionOverride.trackIndices).isEmpty(); + } + + @Test + public void newTrackSelectionOverride_withInvalidIndex_throws() { + assertThrows( + IndexOutOfBoundsException.class, + () -> new TrackSelectionOverride(newTrackGroupWithIds(1, 2), ImmutableList.of(2))); + } + + private static TrackGroup newTrackGroupWithIds(int... ids) { + return new TrackGroup( + Arrays.stream(ids) + .mapToObj(id -> new Format.Builder().setId(id).build()) + .toArray(Format[]::new)); + } +} diff --git a/libraries/common/src/test/java/androidx/media3/common/TrackSelectionOverridesTest.java b/libraries/common/src/test/java/androidx/media3/common/TrackSelectionOverridesTest.java deleted file mode 100644 index 19c53614a7..0000000000 --- a/libraries/common/src/test/java/androidx/media3/common/TrackSelectionOverridesTest.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package androidx.media3.common; - -import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.assertThrows; - -import androidx.media3.common.TrackSelectionOverrides.TrackSelectionOverride; -import androidx.test.ext.junit.runners.AndroidJUnit4; -import com.google.common.collect.ImmutableList; -import java.util.Arrays; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** Unit tests for {@link TrackSelectionOverrides}. */ -@RunWith(AndroidJUnit4.class) -public final class TrackSelectionOverridesTest { - - public static final TrackGroup AAC_TRACK_GROUP = - new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_AAC).build()); - - private static TrackGroup newTrackGroupWithIds(int... ids) { - return new TrackGroup( - Arrays.stream(ids) - .mapToObj(id -> new Format.Builder().setId(id).build()) - .toArray(Format[]::new)); - } - - @Test - public void newTrackSelectionOverride_withJustTrackGroup_selectsAllTracks() { - TrackSelectionOverride trackSelectionOverride = - new TrackSelectionOverride(newTrackGroupWithIds(1, 2)); - - assertThat(trackSelectionOverride.trackGroup).isEqualTo(newTrackGroupWithIds(1, 2)); - assertThat(trackSelectionOverride.trackIndices).containsExactly(0, 1).inOrder(); - } - - @Test - public void newTrackSelectionOverride_withTracks_selectsOnlySpecifiedTracks() { - TrackSelectionOverride trackSelectionOverride = - new TrackSelectionOverride(newTrackGroupWithIds(1, 2), ImmutableList.of(1)); - - assertThat(trackSelectionOverride.trackGroup).isEqualTo(newTrackGroupWithIds(1, 2)); - assertThat(trackSelectionOverride.trackIndices).containsExactly(1); - } - - @Test - public void newTrackSelectionOverride_with0Tracks_selectsAllSpecifiedTracks() { - TrackSelectionOverride trackSelectionOverride = - new TrackSelectionOverride(newTrackGroupWithIds(1, 2), ImmutableList.of()); - - assertThat(trackSelectionOverride.trackGroup).isEqualTo(newTrackGroupWithIds(1, 2)); - assertThat(trackSelectionOverride.trackIndices).isEmpty(); - } - - @Test - public void newTrackSelectionOverride_withInvalidIndex_throws() { - assertThrows( - IndexOutOfBoundsException.class, - () -> new TrackSelectionOverride(newTrackGroupWithIds(1, 2), ImmutableList.of(2))); - } - - @Test - public void roundTripViaBundle_withOverrides_yieldsEqualInstance() { - TrackSelectionOverrides trackSelectionOverrides = - new TrackSelectionOverrides.Builder() - .setOverrideForType( - new TrackSelectionOverride(newTrackGroupWithIds(3, 4), ImmutableList.of(1))) - .addOverride(new TrackSelectionOverride(newTrackGroupWithIds(5, 6))) - .build(); - - TrackSelectionOverrides fromBundle = - TrackSelectionOverrides.CREATOR.fromBundle(trackSelectionOverrides.toBundle()); - - assertThat(fromBundle).isEqualTo(trackSelectionOverrides); - assertThat(fromBundle.asList()).isEqualTo(trackSelectionOverrides.asList()); - } - - @Test - public void builder_byDefault_isEmpty() { - TrackSelectionOverrides trackSelectionOverrides = new TrackSelectionOverrides.Builder().build(); - - assertThat(trackSelectionOverrides.asList()).isEmpty(); - assertThat(trackSelectionOverrides).isEqualTo(TrackSelectionOverrides.EMPTY); - } - - @Test - public void addOverride_onDifferentGroups_addsOverride() { - TrackSelectionOverride override1 = new TrackSelectionOverride(newTrackGroupWithIds(1)); - TrackSelectionOverride override2 = new TrackSelectionOverride(newTrackGroupWithIds(2)); - - TrackSelectionOverrides trackSelectionOverrides = - new TrackSelectionOverrides.Builder().addOverride(override1).addOverride(override2).build(); - - assertThat(trackSelectionOverrides.asList()).containsExactly(override1, override2); - assertThat(trackSelectionOverrides.getOverride(override1.trackGroup)).isEqualTo(override1); - assertThat(trackSelectionOverrides.getOverride(override2.trackGroup)).isEqualTo(override2); - } - - @Test - public void addOverride_onSameGroup_replacesOverride() { - TrackGroup trackGroup = newTrackGroupWithIds(1, 2, 3); - TrackSelectionOverride override1 = - new TrackSelectionOverride(trackGroup, /* trackIndices= */ ImmutableList.of(0)); - TrackSelectionOverride override2 = - new TrackSelectionOverride(trackGroup, /* trackIndices= */ ImmutableList.of(1)); - - TrackSelectionOverrides trackSelectionOverrides = - new TrackSelectionOverrides.Builder().addOverride(override1).addOverride(override2).build(); - - assertThat(trackSelectionOverrides.asList()).containsExactly(override2); - assertThat(trackSelectionOverrides.getOverride(override2.trackGroup)).isEqualTo(override2); - } - - @Test - public void setOverrideForType_onSameType_replacesOverride() { - TrackSelectionOverride override1 = new TrackSelectionOverride(newTrackGroupWithIds(1)); - TrackSelectionOverride override2 = new TrackSelectionOverride(newTrackGroupWithIds(2)); - - TrackSelectionOverrides trackSelectionOverrides = - new TrackSelectionOverrides.Builder() - .setOverrideForType(override1) - .setOverrideForType(override2) - .build(); - - assertThat(trackSelectionOverrides.asList()).containsExactly(override2); - assertThat(trackSelectionOverrides.getOverride(override2.trackGroup)).isEqualTo(override2); - } - - @Test - public void clearOverridesOfType_ofTypeAudio_removesAudioOverride() { - TrackSelectionOverride override1 = new TrackSelectionOverride(AAC_TRACK_GROUP); - TrackSelectionOverride override2 = new TrackSelectionOverride(newTrackGroupWithIds(1)); - TrackSelectionOverrides trackSelectionOverrides = - new TrackSelectionOverrides.Builder() - .addOverride(override1) - .addOverride(override2) - .clearOverridesOfType(C.TRACK_TYPE_AUDIO) - .build(); - - assertThat(trackSelectionOverrides.asList()).containsExactly(override2); - assertThat(trackSelectionOverrides.getOverride(override2.trackGroup)).isEqualTo(override2); - } - - @Test - public void clearOverride_ofTypeGroup_removesOverride() { - TrackSelectionOverride override1 = new TrackSelectionOverride(AAC_TRACK_GROUP); - TrackSelectionOverride override2 = new TrackSelectionOverride(newTrackGroupWithIds(1)); - TrackSelectionOverrides trackSelectionOverrides = - new TrackSelectionOverrides.Builder() - .addOverride(override1) - .addOverride(override2) - .clearOverride(override2.trackGroup) - .build(); - - assertThat(trackSelectionOverrides.asList()).containsExactly(override1); - assertThat(trackSelectionOverrides.getOverride(override1.trackGroup)).isEqualTo(override1); - } -} 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 175644edfc..d11efe782d 100644 --- a/libraries/common/src/test/java/androidx/media3/common/TrackSelectionParametersTest.java +++ b/libraries/common/src/test/java/androidx/media3/common/TrackSelectionParametersTest.java @@ -18,7 +18,6 @@ package androidx.media3.common; import static androidx.test.core.app.ApplicationProvider.getApplicationContext; import static com.google.common.truth.Truth.assertThat; -import androidx.media3.common.TrackSelectionOverrides.TrackSelectionOverride; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; @@ -29,6 +28,9 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) public final class TrackSelectionParametersTest { + private static final TrackGroup AAC_TRACK_GROUP = + new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_AAC).build()); + @Test public void defaultValue_withoutChange_isAsExpected() { TrackSelectionParameters parameters = TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT; @@ -59,22 +61,19 @@ public final class TrackSelectionParametersTest { // General assertThat(parameters.forceLowestBitrate).isFalse(); assertThat(parameters.forceHighestSupportedBitrate).isFalse(); - assertThat(parameters.trackSelectionOverrides.asList()).isEmpty(); + assertThat(parameters.overrides).isEmpty(); assertThat(parameters.disabledTrackTypes).isEmpty(); } @Test public void parametersSet_fromDefault_isAsExpected() { - TrackSelectionOverrides trackSelectionOverrides = - new TrackSelectionOverrides.Builder() - .addOverride(new TrackSelectionOverride(new TrackGroup(new Format.Builder().build()))) - .addOverride( - new TrackSelectionOverride( - new TrackGroup( - new Format.Builder().setId(4).build(), - new Format.Builder().setId(5).build()), - /* trackIndices= */ ImmutableList.of(1))) - .build(); + TrackSelectionOverride override1 = + new TrackSelectionOverride(new TrackGroup(new Format.Builder().build())); + TrackSelectionOverride override2 = + new TrackSelectionOverride( + new TrackGroup( + new Format.Builder().setId(4).build(), new Format.Builder().setId(5).build()), + /* trackIndices= */ ImmutableList.of(1)); TrackSelectionParameters parameters = TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT .buildUpon() @@ -103,7 +102,13 @@ public final class TrackSelectionParametersTest { // General .setForceLowestBitrate(false) .setForceHighestSupportedBitrate(true) - .setTrackSelectionOverrides(trackSelectionOverrides) + .addOverride(new TrackSelectionOverride(new TrackGroup(new Format.Builder().build()))) + .addOverride( + new TrackSelectionOverride( + new TrackGroup( + 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)) .build(); @@ -137,7 +142,8 @@ public final class TrackSelectionParametersTest { // General assertThat(parameters.forceLowestBitrate).isFalse(); assertThat(parameters.forceHighestSupportedBitrate).isTrue(); - assertThat(parameters.trackSelectionOverrides).isEqualTo(trackSelectionOverrides); + assertThat(parameters.overrides) + .containsExactly(override1.trackGroup, override1, override2.trackGroup, override2); assertThat(parameters.disabledTrackTypes) .containsExactly(C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_TEXT); } @@ -178,4 +184,101 @@ public final class TrackSelectionParametersTest { assertThat(parameters.viewportHeight).isEqualTo(Integer.MAX_VALUE); assertThat(parameters.viewportOrientationMayChange).isTrue(); } + + @Test + public void roundTripViaBundle_withOverride_yieldsEqualInstance() { + TrackSelectionOverride override = + new TrackSelectionOverride( + newTrackGroupWithIds(3, 4), /* trackIndices= */ ImmutableList.of(1)); + TrackSelectionParameters trackSelectionParameters = + new TrackSelectionParameters.Builder(getApplicationContext()).addOverride(override).build(); + + TrackSelectionParameters fromBundle = + TrackSelectionParameters.CREATOR.fromBundle(trackSelectionParameters.toBundle()); + + assertThat(fromBundle).isEqualTo(trackSelectionParameters); + assertThat(trackSelectionParameters.overrides).containsExactly(override.trackGroup, override); + } + + @Test + public void addOverride_onDifferentGroups_addsOverride() { + TrackSelectionOverride override1 = new TrackSelectionOverride(newTrackGroupWithIds(1)); + TrackSelectionOverride override2 = new TrackSelectionOverride(newTrackGroupWithIds(2)); + + TrackSelectionParameters trackSelectionParameters = + new TrackSelectionParameters.Builder(getApplicationContext()) + .addOverride(override1) + .addOverride(override2) + .build(); + + assertThat(trackSelectionParameters.overrides) + .containsExactly(override1.trackGroup, override1, override2.trackGroup, override2); + } + + @Test + public void addOverride_onSameGroup_replacesOverride() { + TrackGroup trackGroup = newTrackGroupWithIds(1, 2, 3); + TrackSelectionOverride override1 = + new TrackSelectionOverride(trackGroup, /* trackIndices= */ ImmutableList.of(0)); + TrackSelectionOverride override2 = + new TrackSelectionOverride(trackGroup, /* trackIndices= */ ImmutableList.of(1)); + + TrackSelectionParameters trackSelectionParameters = + new TrackSelectionParameters.Builder(getApplicationContext()) + .addOverride(override1) + .addOverride(override2) + .build(); + + assertThat(trackSelectionParameters.overrides).containsExactly(override2.trackGroup, override2); + } + + @Test + public void setOverrideForType_onSameType_replacesOverride() { + TrackSelectionOverride override1 = new TrackSelectionOverride(newTrackGroupWithIds(1)); + TrackSelectionOverride override2 = new TrackSelectionOverride(newTrackGroupWithIds(2)); + + TrackSelectionParameters trackSelectionParameters = + new TrackSelectionParameters.Builder(getApplicationContext()) + .setOverrideForType(override1) + .setOverrideForType(override2) + .build(); + + assertThat(trackSelectionParameters.overrides).containsExactly(override2.trackGroup, override2); + } + + @Test + public void clearOverridesOfType_ofTypeAudio_removesAudioOverride() { + TrackSelectionOverride override1 = new TrackSelectionOverride(AAC_TRACK_GROUP); + TrackSelectionOverride override2 = new TrackSelectionOverride(newTrackGroupWithIds(1)); + TrackSelectionParameters trackSelectionParameters = + new TrackSelectionParameters.Builder(getApplicationContext()) + .addOverride(override1) + .addOverride(override2) + .clearOverridesOfType(C.TRACK_TYPE_AUDIO) + .build(); + + assertThat(trackSelectionParameters.overrides).containsExactly(override2.trackGroup, override2); + } + + @Test + public void clearOverride_ofTypeGroup_removesOverride() { + TrackSelectionOverride override1 = new TrackSelectionOverride(AAC_TRACK_GROUP); + TrackSelectionOverride override2 = new TrackSelectionOverride(newTrackGroupWithIds(1)); + TrackSelectionParameters trackSelectionParameters = + new TrackSelectionParameters.Builder(getApplicationContext()) + .addOverride(override1) + .addOverride(override2) + .clearOverride(override2.trackGroup) + .build(); + + assertThat(trackSelectionParameters.overrides).containsExactly(override1.trackGroup, override1); + } + + private static TrackGroup newTrackGroupWithIds(int... ids) { + Format[] formats = new Format[ids.length]; + for (int i = 0; i < ids.length; i++) { + formats[i] = new Format.Builder().setId(ids[i]).build(); + } + return new TrackGroup(formats); + } } 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 037304cfe2..d59db6a91e 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 @@ -38,8 +38,7 @@ import androidx.media3.common.Timeline; import androidx.media3.common.TrackGroup; import androidx.media3.common.TrackGroupArray; import androidx.media3.common.TrackSelection; -import androidx.media3.common.TrackSelectionOverrides; -import androidx.media3.common.TrackSelectionOverrides.TrackSelectionOverride; +import androidx.media3.common.TrackSelectionOverride; import androidx.media3.common.TrackSelectionParameters; import androidx.media3.common.util.Assertions; import androidx.media3.common.util.BundleableUtil; @@ -598,9 +597,32 @@ public class DefaultTrackSelector extends MappingTrackSelector { } @Override - public ParametersBuilder setTrackSelectionOverrides( - TrackSelectionOverrides trackSelectionOverrides) { - super.setTrackSelectionOverrides(trackSelectionOverrides); + public ParametersBuilder addOverride(TrackSelectionOverride override) { + super.addOverride(override); + return this; + } + + @Override + public ParametersBuilder clearOverride(TrackGroup trackGroup) { + super.clearOverride(trackGroup); + return this; + } + + @Override + public ParametersBuilder setOverrideForType(TrackSelectionOverride override) { + super.setOverrideForType(override); + return this; + } + + @Override + public ParametersBuilder clearOverridesOfType(@C.TrackType int trackType) { + super.clearOverridesOfType(trackType); + return this; + } + + @Override + public ParametersBuilder clearOverrides() { + super.clearOverrides(); return this; } @@ -705,7 +727,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { * @param groups The {@link TrackGroupArray} for which the override should be applied. * @param override The override. * @return This builder. - * @deprecated Use {@link TrackSelectionParameters.Builder#setTrackSelectionOverrides}. + * @deprecated Use {@link TrackSelectionParameters.Builder#addOverride(TrackSelectionOverride)}. */ @Deprecated public final ParametersBuilder setSelectionOverride( @@ -730,7 +752,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { * @param rendererIndex The renderer index. * @param groups The {@link TrackGroupArray} for which the override should be cleared. * @return This builder. - * @deprecated Use {@link TrackSelectionParameters.Builder#setTrackSelectionOverrides}. + * @deprecated Use {@link TrackSelectionParameters.Builder#clearOverride(TrackGroup)}. */ @Deprecated public final ParametersBuilder clearSelectionOverride( @@ -753,7 +775,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { * * @param rendererIndex The renderer index. * @return This builder. - * @deprecated Use {@link TrackSelectionParameters.Builder#setTrackSelectionOverrides}. + * @deprecated Use {@link TrackSelectionParameters.Builder#clearOverridesOfType(int)}. */ @Deprecated public final ParametersBuilder clearSelectionOverrides(int rendererIndex) { @@ -771,7 +793,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { * Clears all track selection overrides for all renderers. * * @return This builder. - * @deprecated Use {@link TrackSelectionParameters.Builder#setTrackSelectionOverrides}. + * @deprecated Use {@link TrackSelectionParameters.Builder#clearOverrides()}. */ @Deprecated public final ParametersBuilder clearSelectionOverrides() { @@ -1022,7 +1044,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { * @return Whether there is an override. * @deprecated Only works to retrieve the overrides set with the deprecated {@link * ParametersBuilder#setSelectionOverride(int, TrackGroupArray, SelectionOverride)}. Use - * {@link TrackSelectionParameters#trackSelectionOverrides} instead. + * {@link TrackSelectionParameters#overrides} instead. */ @Deprecated public final boolean hasSelectionOverride(int rendererIndex, TrackGroupArray groups) { @@ -1039,7 +1061,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { * @return The override, or null if no override exists. * @deprecated Only works to retrieve the overrides set with the deprecated {@link * ParametersBuilder#setSelectionOverride(int, TrackGroupArray, SelectionOverride)}. Use - * {@link TrackSelectionParameters#trackSelectionOverrides} instead. + * {@link TrackSelectionParameters#overrides} instead. */ @Deprecated @Nullable @@ -1661,9 +1683,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { TrackGroupArray rendererTrackGroups = mappedTrackInfo.getTrackGroups(rendererIndex); for (int j = 0; j < rendererTrackGroups.length; j++) { maybeUpdateApplicableOverrides( - applicableOverrides, - params.trackSelectionOverrides.getOverride(rendererTrackGroups.get(j)), - rendererIndex); + applicableOverrides, params.overrides.get(rendererTrackGroups.get(j)), rendererIndex); } } // Also iterate unmapped groups to see if they have overrides. @@ -1671,7 +1691,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { for (int i = 0; i < unmappedGroups.length; i++) { maybeUpdateApplicableOverrides( applicableOverrides, - params.trackSelectionOverrides.getOverride(unmappedGroups.get(i)), + params.overrides.get(unmappedGroups.get(i)), /* rendererIndex= */ C.INDEX_UNSET); } return applicableOverrides; 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 a5514c7068..442725a2f5 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 @@ -42,8 +42,7 @@ import androidx.media3.common.Timeline; import androidx.media3.common.TrackGroup; import androidx.media3.common.TrackGroupArray; import androidx.media3.common.TrackSelection; -import androidx.media3.common.TrackSelectionOverrides; -import androidx.media3.common.TrackSelectionOverrides.TrackSelectionOverride; +import androidx.media3.common.TrackSelectionOverride; import androidx.media3.common.TracksInfo; import androidx.media3.common.util.Util; import androidx.media3.exoplayer.ExoPlaybackException; @@ -171,10 +170,8 @@ public final class DefaultTrackSelectorTest { trackSelector.setParameters( trackSelector .buildUponParameters() - .setTrackSelectionOverrides( - new TrackSelectionOverrides.Builder() - .addOverride(new TrackSelectionOverride(VIDEO_TRACK_GROUP, ImmutableList.of())) - .build())); + .addOverride(new TrackSelectionOverride(VIDEO_TRACK_GROUP, ImmutableList.of())) + .build()); TrackSelectorResult result = trackSelector.selectTracks(RENDERER_CAPABILITIES, TRACK_GROUPS, periodId, TIMELINE); @@ -225,18 +222,16 @@ public final class DefaultTrackSelectorTest { trackSelector.setParameters( trackSelector .buildUponParameters() - .setTrackSelectionOverrides( - new TrackSelectionOverrides.Builder() - .addOverride( - new TrackSelectionOverride( - videoGroupHighBitrate, /* trackIndices= */ ImmutableList.of())) - .addOverride( - new TrackSelectionOverride( - videoGroupMidBitrate, /* trackIndices= */ ImmutableList.of(0))) - .addOverride( - new TrackSelectionOverride( - videoGroupLowBitrate, /* trackIndices= */ ImmutableList.of())) - .build())); + .addOverride( + new TrackSelectionOverride( + videoGroupHighBitrate, /* trackIndices= */ ImmutableList.of())) + .addOverride( + new TrackSelectionOverride( + videoGroupMidBitrate, /* trackIndices= */ ImmutableList.of(0))) + .addOverride( + new TrackSelectionOverride( + videoGroupLowBitrate, /* trackIndices= */ ImmutableList.of())) + .build()); TrackSelectorResult result = trackSelector.selectTracks( @@ -260,12 +255,10 @@ public final class DefaultTrackSelectorTest { trackSelector.setParameters( trackSelector .buildUponParameters() - .setTrackSelectionOverrides( - new TrackSelectionOverrides.Builder() - .setOverrideForType( - new TrackSelectionOverride( - new TrackGroup(VIDEO_FORMAT, VIDEO_FORMAT), ImmutableList.of())) - .build())); + .setOverrideForType( + new TrackSelectionOverride( + new TrackGroup(VIDEO_FORMAT, VIDEO_FORMAT), ImmutableList.of())) + .build()); TrackSelectorResult result = trackSelector.selectTracks( @@ -309,10 +302,8 @@ public final class DefaultTrackSelectorTest { trackSelector.setParameters( trackSelector .buildUponParameters() - .setTrackSelectionOverrides( - new TrackSelectionOverrides.Builder() - .setOverrideForType(new TrackSelectionOverride(videoGroupH264)) - .build())); + .setOverrideForType(new TrackSelectionOverride(videoGroupH264)) + .build()); TrackSelectorResult result = trackSelector.selectTracks( new RendererCapabilities[] {rendererCapabilitiesH264, rendererCapabilitiesAv1}, @@ -328,10 +319,8 @@ public final class DefaultTrackSelectorTest { trackSelector.setParameters( trackSelector .buildUponParameters() - .setTrackSelectionOverrides( - new TrackSelectionOverrides.Builder() - .setOverrideForType(new TrackSelectionOverride(videoGroupAv1)) - .build())); + .setOverrideForType(new TrackSelectionOverride(videoGroupAv1)) + .build()); result = trackSelector.selectTracks( new RendererCapabilities[] {rendererCapabilitiesH264, rendererCapabilitiesAv1}, @@ -361,10 +350,8 @@ public final class DefaultTrackSelectorTest { trackSelector.setParameters( trackSelector .buildUponParameters() - .setTrackSelectionOverrides( - new TrackSelectionOverrides.Builder() - .setOverrideForType(new TrackSelectionOverride(audioGroupUnsupported)) - .build())); + .setOverrideForType(new TrackSelectionOverride(audioGroupUnsupported)) + .build()); TrackSelectorResult result = trackSelector.selectTracks( new RendererCapabilities[] {VIDEO_CAPABILITIES, audioRendererCapabilties}, @@ -2397,13 +2384,10 @@ public final class DefaultTrackSelectorTest { .setRendererDisabled(1, true) .setRendererDisabled(3, true) .setRendererDisabled(5, false) - .setTrackSelectionOverrides( - new TrackSelectionOverrides.Builder() - .setOverrideForType( - new TrackSelectionOverride( - new TrackGroup(AUDIO_FORMAT, AUDIO_FORMAT, AUDIO_FORMAT, AUDIO_FORMAT), - /* trackIndices= */ ImmutableList.of(0, 2, 3))) - .build()) + .setOverrideForType( + new TrackSelectionOverride( + new TrackGroup(AUDIO_FORMAT, AUDIO_FORMAT, AUDIO_FORMAT, AUDIO_FORMAT), + /* trackIndices= */ ImmutableList.of(0, 2, 3))) .setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO)) .build(); } 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 ea16390550..35f5cabd5d 100644 --- a/libraries/ui/src/main/java/androidx/media3/ui/PlayerControlView.java +++ b/libraries/ui/src/main/java/androidx/media3/ui/PlayerControlView.java @@ -63,8 +63,7 @@ import androidx.media3.common.Player.Events; import androidx.media3.common.Player.State; import androidx.media3.common.Timeline; import androidx.media3.common.TrackGroup; -import androidx.media3.common.TrackSelectionOverrides; -import androidx.media3.common.TrackSelectionOverrides.TrackSelectionOverride; +import androidx.media3.common.TrackSelectionOverride; import androidx.media3.common.TrackSelectionParameters; import androidx.media3.common.TracksInfo; import androidx.media3.common.TracksInfo.TrackGroupInfo; @@ -1902,7 +1901,7 @@ public class PlayerControlView extends FrameLayout { holder.textView.setText(R.string.exo_track_selection_auto); // hasSelectionOverride is true means there is an explicit track selection, not "Auto". TrackSelectionParameters parameters = checkNotNull(player).getTrackSelectionParameters(); - boolean hasSelectionOverride = hasSelectionOverride(parameters.trackSelectionOverrides); + boolean hasSelectionOverride = hasSelectionOverride(parameters); holder.checkView.setVisibility(hasSelectionOverride ? INVISIBLE : VISIBLE); holder.itemView.setOnClickListener( v -> { @@ -1911,12 +1910,6 @@ public class PlayerControlView extends FrameLayout { } TrackSelectionParameters trackSelectionParameters = player.getTrackSelectionParameters(); - TrackSelectionOverrides trackSelectionOverrides = - trackSelectionParameters - .trackSelectionOverrides - .buildUpon() - .clearOverridesOfType(C.TRACK_TYPE_AUDIO) - .build(); Set<@C.TrackType Integer> disabledTrackTypes = new HashSet<>(trackSelectionParameters.disabledTrackTypes); disabledTrackTypes.remove(C.TRACK_TYPE_AUDIO); @@ -1924,7 +1917,7 @@ public class PlayerControlView extends FrameLayout { .setTrackSelectionParameters( trackSelectionParameters .buildUpon() - .setTrackSelectionOverrides(trackSelectionOverrides) + .clearOverridesOfType(C.TRACK_TYPE_AUDIO) .setDisabledTrackTypes(disabledTrackTypes) .build()); settingsAdapter.setSubTextAtPosition( @@ -1934,10 +1927,10 @@ public class PlayerControlView extends FrameLayout { }); } - private boolean hasSelectionOverride(TrackSelectionOverrides trackSelectionOverrides) { + private boolean hasSelectionOverride(TrackSelectionParameters trackSelectionParameters) { for (int i = 0; i < tracks.size(); i++) { TrackGroup trackGroup = tracks.get(i).trackGroupInfo.getTrackGroup(); - if (trackSelectionOverrides.getOverride(trackGroup) != null) { + if (trackSelectionParameters.overrides.containsKey(trackGroup)) { return true; } } @@ -1960,7 +1953,7 @@ public class PlayerControlView extends FrameLayout { getResources().getString(R.string.exo_track_selection_none)); // TODO(insun) : Make the audio item in main settings (settingsAdapater) // to be non-clickable. - } else if (!hasSelectionOverride(params.trackSelectionOverrides)) { + } else if (!hasSelectionOverride(params)) { settingsAdapter.setSubTextAtPosition( SETTINGS_AUDIO_TRACK_SELECTION_POSITION, getResources().getString(R.string.exo_track_selection_auto)); @@ -2011,8 +2004,7 @@ public class PlayerControlView extends FrameLayout { TrackInformation track = tracks.get(position - 1); TrackGroup trackGroup = track.trackGroupInfo.getTrackGroup(); TrackSelectionParameters params = checkNotNull(player).getTrackSelectionParameters(); - boolean explicitlySelected = - params.trackSelectionOverrides.getOverride(trackGroup) != null && track.isSelected(); + boolean explicitlySelected = params.overrides.get(trackGroup) != null && track.isSelected(); holder.textView.setText(track.trackName); holder.checkView.setVisibility(explicitlySelected ? VISIBLE : INVISIBLE); holder.itemView.setOnClickListener( @@ -2022,14 +2014,6 @@ public class PlayerControlView extends FrameLayout { } TrackSelectionParameters trackSelectionParameters = player.getTrackSelectionParameters(); - TrackSelectionOverrides overrides = - trackSelectionParameters - .trackSelectionOverrides - .buildUpon() - .setOverrideForType( - new TrackSelectionOverride( - trackGroup, ImmutableList.of(track.trackIndex))) - .build(); Set<@C.TrackType Integer> disabledTrackTypes = new HashSet<>(trackSelectionParameters.disabledTrackTypes); disabledTrackTypes.remove(track.trackGroupInfo.getTrackType()); @@ -2037,7 +2021,9 @@ public class PlayerControlView extends FrameLayout { .setTrackSelectionParameters( trackSelectionParameters .buildUpon() - .setTrackSelectionOverrides(overrides) + .setOverrideForType( + new TrackSelectionOverride( + trackGroup, ImmutableList.of(track.trackIndex))) .setDisabledTrackTypes(disabledTrackTypes) .build()); onTrackSelection(track.trackName);