From 3c6ca19c8567231d9050d76d5152f9f87b9cf7c7 Mon Sep 17 00:00:00 2001 From: tonihei Date: Tue, 5 Jun 2018 02:30:25 -0700 Subject: [PATCH] Fix track selection nullability issues. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=199266768 --- library/core/build.gradle | 1 + .../AdaptiveTrackSelection.java | 7 +- .../trackselection/DefaultTrackSelector.java | 128 +++++++++++------- .../trackselection/FixedTrackSelection.java | 12 +- .../trackselection/MappingTrackSelector.java | 29 ++-- .../trackselection/RandomTrackSelection.java | 4 +- .../trackselection/TrackSelection.java | 7 +- .../trackselection/TrackSelectionArray.java | 17 +-- .../trackselection/TrackSelector.java | 3 +- .../trackselection/TrackSelectorResult.java | 7 +- .../google/android/exoplayer2/util/Util.java | 6 +- .../exoplayer2/ui/TrackSelectionView.java | 5 +- 12 files changed, 130 insertions(+), 96 deletions(-) diff --git a/library/core/build.gradle b/library/core/build.gradle index bb331b615c..aa2e06fb3d 100644 --- a/library/core/build.gradle +++ b/library/core/build.gradle @@ -54,6 +54,7 @@ android { dependencies { implementation 'com.android.support:support-annotations:' + supportLibraryVersion compileOnly 'org.checkerframework:checker-qual:' + checkerframeworkVersion + compileOnly 'org.checkerframework:checker-compat-qual:' + checkerframeworkVersion androidTestImplementation 'com.google.dexmaker:dexmaker:' + dexmakerVersion androidTestImplementation 'com.google.dexmaker:dexmaker-mockito:' + dexmakerVersion androidTestImplementation 'com.google.truth:truth:' + truthVersion diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelection.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelection.java index b28dc6ca6f..0aa6dcffaa 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelection.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelection.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.trackselection; +import android.support.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.source.TrackGroup; @@ -242,9 +243,11 @@ public class AdaptiveTrackSelection extends BaseTrackSelection { this.minTimeBetweenBufferReevaluationMs = minTimeBetweenBufferReevaluationMs; this.clock = clock; playbackSpeed = 1f; - selectedIndex = determineIdealSelectedIndex(Long.MIN_VALUE); reason = C.SELECTION_REASON_INITIAL; lastBufferEvaluationMs = C.TIME_UNSET; + @SuppressWarnings("nullness:method.invocation.invalid") + int selectedIndex = determineIdealSelectedIndex(Long.MIN_VALUE); + this.selectedIndex = selectedIndex; } @Override @@ -301,7 +304,7 @@ public class AdaptiveTrackSelection extends BaseTrackSelection { } @Override - public Object getSelectionData() { + public @Nullable Object getSelectionData() { return null; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java index 71d2544784..10b11044d3 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java @@ -19,7 +19,6 @@ import android.content.Context; import android.graphics.Point; import android.os.Parcel; import android.os.Parcelable; -import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; import android.util.Pair; @@ -44,6 +43,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; +import org.checkerframework.checker.nullness.compatqual.NullableType; /** * A default {@link TrackSelector} suitable for most use cases. Track selections are made according @@ -161,8 +161,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { private final SparseArray> selectionOverrides; private final SparseBooleanArray rendererDisabledFlags; - private String preferredAudioLanguage; - private String preferredTextLanguage; + private @Nullable String preferredAudioLanguage; + private @Nullable String preferredTextLanguage; private boolean selectUndeterminedTextLanguage; private int disabledTextTrackSelectionFlags; private boolean forceLowestBitrate; @@ -572,14 +572,14 @@ public class DefaultTrackSelector extends MappingTrackSelector { * The preferred language for audio, as well as for forced text tracks, as an ISO 639-2/T tag. * {@code null} selects the default track, or the first track if there's no default. */ - public final String preferredAudioLanguage; + public final @Nullable String preferredAudioLanguage; // Text /** * The preferred language for text tracks as an ISO 639-2/T tag. {@code null} selects the * default track if there is one, or no track otherwise. */ - public final String preferredTextLanguage; + public final @Nullable String preferredTextLanguage; /** * Whether a text track with undetermined language should be selected if no track with * {@link #preferredTextLanguage} is available, or if {@link #preferredTextLanguage} is unset. @@ -673,8 +673,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { /* package */ Parameters( SparseArray> selectionOverrides, SparseBooleanArray rendererDisabledFlags, - String preferredAudioLanguage, - String preferredTextLanguage, + @Nullable String preferredAudioLanguage, + @Nullable String preferredTextLanguage, boolean selectUndeterminedTextLanguage, int disabledTextTrackSelectionFlags, boolean forceLowestBitrate, @@ -759,7 +759,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { * @param groups The {@link TrackGroupArray}. * @return The override, or null if no override exists. */ - public final SelectionOverride getSelectionOverride(int rendererIndex, TrackGroupArray groups) { + public final @Nullable SelectionOverride getSelectionOverride( + int rendererIndex, TrackGroupArray groups) { Map overrides = selectionOverrides.get(rendererIndex); return overrides != null ? overrides.get(groups) : null; } @@ -816,8 +817,9 @@ public class DefaultTrackSelector extends MappingTrackSelector { result = 31 * result + viewportHeight; result = 31 * result + maxVideoBitrate; result = 31 * result + tunnelingAudioSessionId; - result = 31 * result + preferredAudioLanguage.hashCode(); - result = 31 * result + preferredTextLanguage.hashCode(); + result = + 31 * result + (preferredAudioLanguage == null ? 0 : preferredAudioLanguage.hashCode()); + result = 31 * result + (preferredTextLanguage == null ? 0 : preferredTextLanguage.hashCode()); return result; } @@ -1042,7 +1044,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { private static final int[] NO_TRACKS = new int[0]; private static final int WITHIN_RENDERER_CAPABILITIES_BONUS = 1000; - private final TrackSelection.Factory adaptiveTrackSelectionFactory; + private final @Nullable TrackSelection.Factory adaptiveTrackSelectionFactory; private final AtomicReference parametersReference; /** @@ -1069,7 +1071,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { * @param adaptiveTrackSelectionFactory A factory for adaptive {@link TrackSelection}s, or null if * the selector should not support adaptive tracks. */ - public DefaultTrackSelector(TrackSelection.Factory adaptiveTrackSelectionFactory) { + public DefaultTrackSelector(@Nullable TrackSelection.Factory adaptiveTrackSelectionFactory) { this.adaptiveTrackSelectionFactory = adaptiveTrackSelectionFactory; parametersReference = new AtomicReference<>(Parameters.DEFAULT); } @@ -1139,7 +1141,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { /** @deprecated Use {@link Parameters#getSelectionOverride(int, TrackGroupArray)}. */ @Deprecated - public final SelectionOverride getSelectionOverride(int rendererIndex, TrackGroupArray groups) { + public final @Nullable SelectionOverride getSelectionOverride( + int rendererIndex, TrackGroupArray groups) { return getParameters().getSelectionOverride(rendererIndex, groups); } @@ -1170,14 +1173,15 @@ public class DefaultTrackSelector extends MappingTrackSelector { // MappingTrackSelector implementation. @Override - protected final Pair selectTracks( - MappedTrackInfo mappedTrackInfo, - int[][][] rendererFormatSupports, - int[] rendererMixedMimeTypeAdaptationSupports) - throws ExoPlaybackException { + protected final Pair<@NullableType RendererConfiguration[], @NullableType TrackSelection[]> + selectTracks( + MappedTrackInfo mappedTrackInfo, + int[][][] rendererFormatSupports, + int[] rendererMixedMimeTypeAdaptationSupports) + throws ExoPlaybackException { Parameters params = parametersReference.get(); int rendererCount = mappedTrackInfo.getRendererCount(); - TrackSelection[] rendererTrackSelections = + @NullableType TrackSelection[] rendererTrackSelections = selectAllTracks( mappedTrackInfo, rendererFormatSupports, @@ -1200,8 +1204,9 @@ public class DefaultTrackSelector extends MappingTrackSelector { rendererTrackGroups.get(override.groupIndex), override.tracks[0]); } else { rendererTrackSelections[i] = - adaptiveTrackSelectionFactory.createTrackSelection( - rendererTrackGroups.get(override.groupIndex), override.tracks); + Assertions.checkNotNull(adaptiveTrackSelectionFactory) + .createTrackSelection( + rendererTrackGroups.get(override.groupIndex), override.tracks); } } } @@ -1209,7 +1214,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { // Initialize the renderer configurations to the default configuration for all renderers with // selections, and null otherwise. - RendererConfiguration[] rendererConfigurations = new RendererConfiguration[rendererCount]; + @NullableType RendererConfiguration[] rendererConfigurations = + new RendererConfiguration[rendererCount]; for (int i = 0; i < rendererCount; i++) { boolean forceRendererDisabled = params.getRendererDisabled(i); boolean rendererEnabled = @@ -1248,14 +1254,14 @@ public class DefaultTrackSelector extends MappingTrackSelector { * disabled, unless RendererCapabilities#getTrackType()} is {@link C#TRACK_TYPE_NONE}. * @throws ExoPlaybackException If an error occurs while selecting the tracks. */ - protected TrackSelection[] selectAllTracks( + protected @NullableType TrackSelection[] selectAllTracks( MappedTrackInfo mappedTrackInfo, int[][][] rendererFormatSupports, int[] rendererMixedMimeTypeAdaptationSupports, Parameters params) throws ExoPlaybackException { int rendererCount = mappedTrackInfo.getRendererCount(); - TrackSelection[] rendererTrackSelections = new TrackSelection[rendererCount]; + @NullableType TrackSelection[] rendererTrackSelections = new TrackSelection[rendererCount]; boolean seenVideoRendererWithMappedTracks = false; boolean selectedVideoTracks = false; @@ -1331,12 +1337,12 @@ public class DefaultTrackSelector extends MappingTrackSelector { * @return The {@link TrackSelection} for the renderer, or null if no selection was made. * @throws ExoPlaybackException If an error occurs while selecting the tracks. */ - protected TrackSelection selectVideoTrack( + protected @Nullable TrackSelection selectVideoTrack( TrackGroupArray groups, int[][] formatSupports, int mixedMimeTypeAdaptationSupports, Parameters params, - TrackSelection.Factory adaptiveTrackSelectionFactory) + @Nullable TrackSelection.Factory adaptiveTrackSelectionFactory) throws ExoPlaybackException { TrackSelection selection = null; if (!params.forceLowestBitrate && adaptiveTrackSelectionFactory != null) { @@ -1354,7 +1360,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { return selection; } - private static TrackSelection selectAdaptiveVideoTrack( + private static @Nullable TrackSelection selectAdaptiveVideoTrack( TrackGroupArray groups, int[][] formatSupport, int mixedMimeTypeAdaptationSupports, @@ -1374,7 +1380,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { params.maxVideoBitrate, params.viewportWidth, params.viewportHeight, params.viewportOrientationMayChange); if (adaptiveTracks.length > 0) { - return adaptiveTrackSelectionFactory.createTrackSelection(group, adaptiveTracks); + return Assertions.checkNotNull(adaptiveTrackSelectionFactory) + .createTrackSelection(group, adaptiveTracks); } } return null; @@ -1397,7 +1404,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { String selectedMimeType = null; if (!allowMixedMimeTypes) { // Select the mime type for which we have the most adaptive tracks. - HashSet seenMimeTypes = new HashSet<>(); + HashSet<@NullableType String> seenMimeTypes = new HashSet<>(); int selectedMimeTypeTrackCount = 0; for (int i = 0; i < selectedTrackIndices.size(); i++) { int trackIndex = selectedTrackIndices.get(i); @@ -1421,9 +1428,15 @@ public class DefaultTrackSelector extends MappingTrackSelector { return selectedTrackIndices.size() < 2 ? NO_TRACKS : Util.toArray(selectedTrackIndices); } - private static int getAdaptiveVideoTrackCountForMimeType(TrackGroup group, int[] formatSupport, - int requiredAdaptiveSupport, String mimeType, int maxVideoWidth, int maxVideoHeight, - int maxVideoBitrate, List selectedTrackIndices) { + private static int getAdaptiveVideoTrackCountForMimeType( + TrackGroup group, + int[] formatSupport, + int requiredAdaptiveSupport, + @Nullable String mimeType, + int maxVideoWidth, + int maxVideoHeight, + int maxVideoBitrate, + List selectedTrackIndices) { int adaptiveTrackCount = 0; for (int i = 0; i < selectedTrackIndices.size(); i++) { int trackIndex = selectedTrackIndices.get(i); @@ -1436,9 +1449,15 @@ public class DefaultTrackSelector extends MappingTrackSelector { return adaptiveTrackCount; } - private static void filterAdaptiveVideoTrackCountForMimeType(TrackGroup group, - int[] formatSupport, int requiredAdaptiveSupport, String mimeType, int maxVideoWidth, - int maxVideoHeight, int maxVideoBitrate, List selectedTrackIndices) { + private static void filterAdaptiveVideoTrackCountForMimeType( + TrackGroup group, + int[] formatSupport, + int requiredAdaptiveSupport, + @Nullable String mimeType, + int maxVideoWidth, + int maxVideoHeight, + int maxVideoBitrate, + List selectedTrackIndices) { for (int i = selectedTrackIndices.size() - 1; i >= 0; i--) { int trackIndex = selectedTrackIndices.get(i); if (!isSupportedAdaptiveVideoTrack(group.getFormat(trackIndex), mimeType, @@ -1449,8 +1468,13 @@ public class DefaultTrackSelector extends MappingTrackSelector { } } - private static boolean isSupportedAdaptiveVideoTrack(Format format, String mimeType, - int formatSupport, int requiredAdaptiveSupport, int maxVideoWidth, int maxVideoHeight, + private static boolean isSupportedAdaptiveVideoTrack( + Format format, + @Nullable String mimeType, + int formatSupport, + int requiredAdaptiveSupport, + int maxVideoWidth, + int maxVideoHeight, int maxVideoBitrate) { return isSupported(formatSupport, false) && ((formatSupport & requiredAdaptiveSupport) != 0) && (mimeType == null || Util.areEqual(format.sampleMimeType, mimeType)) @@ -1459,7 +1483,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { && (format.bitrate == Format.NO_VALUE || format.bitrate <= maxVideoBitrate); } - private static TrackSelection selectFixedVideoTrack( + private static @Nullable TrackSelection selectFixedVideoTrack( TrackGroupArray groups, int[][] formatSupports, Parameters params) { TrackGroup selectedGroup = null; int selectedTrackIndex = 0; @@ -1537,12 +1561,12 @@ public class DefaultTrackSelector extends MappingTrackSelector { * @return The {@link TrackSelection} for the renderer, or null if no selection was made. * @throws ExoPlaybackException If an error occurs while selecting the tracks. */ - protected TrackSelection selectAudioTrack( + protected @Nullable TrackSelection selectAudioTrack( TrackGroupArray groups, int[][] formatSupports, int mixedMimeTypeAdaptationSupports, Parameters params, - TrackSelection.Factory adaptiveTrackSelectionFactory) + @Nullable TrackSelection.Factory adaptiveTrackSelectionFactory) throws ExoPlaybackException { int selectedTrackIndex = C.INDEX_UNSET; int selectedGroupIndex = C.INDEX_UNSET; @@ -1606,8 +1630,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { int[] adaptiveIndices = new int[selectedConfigurationTrackCount]; int index = 0; for (int i = 0; i < group.length; i++) { - if (isSupportedAdaptiveAudioTrack(group.getFormat(i), formatSupport[i], - selectedConfiguration)) { + if (isSupportedAdaptiveAudioTrack( + group.getFormat(i), formatSupport[i], Assertions.checkNotNull(selectedConfiguration))) { adaptiveIndices[index++] = i; } } @@ -1648,7 +1672,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { * @return The {@link TrackSelection} for the renderer, or null if no selection was made. * @throws ExoPlaybackException If an error occurs while selecting the tracks. */ - protected TrackSelection selectTextTrack( + protected @Nullable TrackSelection selectTextTrack( TrackGroupArray groups, int[][] formatSupport, Parameters params) throws ExoPlaybackException { TrackGroup selectedGroup = null; @@ -1721,7 +1745,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { * @return The {@link TrackSelection} for the renderer, or null if no selection was made. * @throws ExoPlaybackException If an error occurs while selecting the tracks. */ - protected TrackSelection selectOtherTrack( + protected @Nullable TrackSelection selectOtherTrack( int trackType, TrackGroupArray groups, int[][] formatSupport, Parameters params) throws ExoPlaybackException { TrackGroup selectedGroup = null; @@ -1768,8 +1792,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { private static void maybeConfigureRenderersForTunneling( MappedTrackInfo mappedTrackInfo, int[][][] renderererFormatSupports, - RendererConfiguration[] rendererConfigurations, - TrackSelection[] trackSelections, + @NullableType RendererConfiguration[] rendererConfigurations, + @NullableType TrackSelection[] trackSelections, int tunnelingAudioSessionId) { if (tunnelingAudioSessionId == C.AUDIO_SESSION_ID_UNSET) { return; @@ -1883,15 +1907,15 @@ public class DefaultTrackSelector extends MappingTrackSelector { } /** - * Returns whether a {@link Format} specifies a particular language, or {@code false} if - * {@code language} is null. + * Returns whether a {@link Format} specifies a particular language, or {@code false} if {@code + * language} is null. * * @param format The {@link Format}. * @param language The language. * @return Whether the format specifies the language, or {@code false} if {@code language} is * null. */ - protected static boolean formatHasLanguage(Format format, String language) { + protected static boolean formatHasLanguage(Format format, @Nullable String language) { return language != null && TextUtils.equals(language, Util.normalizeLanguageCode(format.language)); } @@ -1997,7 +2021,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { * negative integer if this score is worse than the other. */ @Override - public int compareTo(@NonNull AudioTrackScore other) { + public int compareTo(AudioTrackScore other) { if (this.withinRendererCapabilitiesScore != other.withinRendererCapabilitiesScore) { return compareInts(this.withinRendererCapabilitiesScore, other.withinRendererCapabilitiesScore); @@ -2066,9 +2090,9 @@ public class DefaultTrackSelector extends MappingTrackSelector { public final int channelCount; public final int sampleRate; - public final String mimeType; + public final @Nullable String mimeType; - public AudioConfigurationTuple(int channelCount, int sampleRate, String mimeType) { + public AudioConfigurationTuple(int channelCount, int sampleRate, @Nullable String mimeType) { this.channelCount = channelCount; this.sampleRate = sampleRate; this.mimeType = mimeType; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/FixedTrackSelection.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/FixedTrackSelection.java index 50873d372d..2aecf624da 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/FixedTrackSelection.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/FixedTrackSelection.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.trackselection; +import android.support.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.util.Assertions; @@ -30,7 +31,7 @@ public final class FixedTrackSelection extends BaseTrackSelection { public static final class Factory implements TrackSelection.Factory { private final int reason; - private final Object data; + private final @Nullable Object data; public Factory() { this.reason = C.SELECTION_REASON_UNKNOWN; @@ -41,7 +42,7 @@ public final class FixedTrackSelection extends BaseTrackSelection { * @param reason A reason for the track selection. * @param data Optional data associated with the track selection. */ - public Factory(int reason, Object data) { + public Factory(int reason, @Nullable Object data) { this.reason = reason; this.data = data; } @@ -51,11 +52,10 @@ public final class FixedTrackSelection extends BaseTrackSelection { Assertions.checkArgument(tracks.length == 1); return new FixedTrackSelection(group, tracks[0], reason, data); } - } private final int reason; - private final Object data; + private final @Nullable Object data; /** * @param group The {@link TrackGroup}. Must not be null. @@ -71,7 +71,7 @@ public final class FixedTrackSelection extends BaseTrackSelection { * @param reason A reason for the track selection. * @param data Optional data associated with the track selection. */ - public FixedTrackSelection(TrackGroup group, int track, int reason, Object data) { + public FixedTrackSelection(TrackGroup group, int track, int reason, @Nullable Object data) { super(group, track); this.reason = reason; this.data = data; @@ -94,7 +94,7 @@ public final class FixedTrackSelection extends BaseTrackSelection { } @Override - public Object getSelectionData() { + public @Nullable Object getSelectionData() { return data; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/MappingTrackSelector.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/MappingTrackSelector.java index 4af969369e..99e4e58c4a 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/MappingTrackSelector.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/MappingTrackSelector.java @@ -16,6 +16,7 @@ package com.google.android.exoplayer2.trackselection; import android.support.annotation.IntDef; +import android.support.annotation.Nullable; import android.util.Pair; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.ExoPlaybackException; @@ -28,6 +29,7 @@ import com.google.android.exoplayer2.util.Util; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; +import org.checkerframework.checker.nullness.compatqual.NullableType; /** * Base class for {@link TrackSelector}s that first establish a mapping between {@link TrackGroup}s @@ -301,13 +303,13 @@ public abstract class MappingTrackSelector extends TrackSelector { } - private MappedTrackInfo currentMappedTrackInfo; + private @Nullable MappedTrackInfo currentMappedTrackInfo; /** * Returns the mapping information for the currently active track selection, or null if no * selection is currently active. */ - public final MappedTrackInfo getCurrentMappedTrackInfo() { + public final @Nullable MappedTrackInfo getCurrentMappedTrackInfo() { return currentMappedTrackInfo; } @@ -357,9 +359,11 @@ public abstract class MappingTrackSelector extends TrackSelector { int[] rendererTrackTypes = new int[rendererCapabilities.length]; for (int i = 0; i < rendererCapabilities.length; i++) { int rendererTrackGroupCount = rendererTrackGroupCounts[i]; - rendererTrackGroupArrays[i] = new TrackGroupArray( - Arrays.copyOf(rendererTrackGroups[i], rendererTrackGroupCount)); - rendererFormatSupports[i] = Arrays.copyOf(rendererFormatSupports[i], rendererTrackGroupCount); + rendererTrackGroupArrays[i] = + new TrackGroupArray( + Util.nullSafeArrayCopy(rendererTrackGroups[i], rendererTrackGroupCount)); + rendererFormatSupports[i] = + Util.nullSafeArrayCopy(rendererFormatSupports[i], rendererTrackGroupCount); rendererTrackTypes[i] = rendererCapabilities[i].getTrackType(); } @@ -367,7 +371,7 @@ public abstract class MappingTrackSelector extends TrackSelector { int unmappedTrackGroupCount = rendererTrackGroupCounts[rendererCapabilities.length]; TrackGroupArray unmappedTrackGroupArray = new TrackGroupArray( - Arrays.copyOf( + Util.nullSafeArrayCopy( rendererTrackGroups[rendererCapabilities.length], unmappedTrackGroupCount)); // Package up the track information and selections. @@ -379,7 +383,7 @@ public abstract class MappingTrackSelector extends TrackSelector { rendererFormatSupports, unmappedTrackGroupArray); - Pair result = + Pair<@NullableType RendererConfiguration[], @NullableType TrackSelection[]> result = selectTracks( mappedTrackInfo, rendererFormatSupports, rendererMixedMimeTypeAdaptationSupports); return new TrackSelectorResult(result.first, result.second, mappedTrackInfo); @@ -399,11 +403,12 @@ public abstract class MappingTrackSelector extends TrackSelector { * RendererCapabilities#getTrackType()} is {@link C#TRACK_TYPE_NONE}. * @throws ExoPlaybackException If an error occurs while selecting the tracks. */ - protected abstract Pair selectTracks( - MappedTrackInfo mappedTrackInfo, - int[][][] rendererFormatSupports, - int[] rendererMixedMimeTypeAdaptationSupport) - throws ExoPlaybackException; + protected abstract Pair<@NullableType RendererConfiguration[], @NullableType TrackSelection[]> + selectTracks( + MappedTrackInfo mappedTrackInfo, + int[][][] rendererFormatSupports, + int[] rendererMixedMimeTypeAdaptationSupport) + throws ExoPlaybackException; /** * Finds the renderer to which the provided {@link TrackGroup} should be mapped. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/RandomTrackSelection.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/RandomTrackSelection.java index d11344a6f6..e1bdc73986 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/RandomTrackSelection.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/RandomTrackSelection.java @@ -16,6 +16,7 @@ package com.google.android.exoplayer2.trackselection; import android.os.SystemClock; +import android.support.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.source.TrackGroup; import java.util.Random; @@ -47,7 +48,6 @@ public final class RandomTrackSelection extends BaseTrackSelection { public RandomTrackSelection createTrackSelection(TrackGroup group, int... tracks) { return new RandomTrackSelection(group, tracks, random); } - } private final Random random; @@ -123,7 +123,7 @@ public final class RandomTrackSelection extends BaseTrackSelection { } @Override - public Object getSelectionData() { + public @Nullable Object getSelectionData() { return null; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelection.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelection.java index 55e6050622..58616996ff 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelection.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelection.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.trackselection; +import android.support.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.source.TrackGroup; @@ -129,10 +130,8 @@ public interface TrackSelection { */ int getSelectionReason(); - /** - * Returns optional data associated with the current track selection. - */ - Object getSelectionData(); + /** Returns optional data associated with the current track selection. */ + @Nullable Object getSelectionData(); // Adaptation. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionArray.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionArray.java index b37c8cad67..48151002be 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionArray.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionArray.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer2.trackselection; import android.support.annotation.Nullable; import java.util.Arrays; +import org.checkerframework.checker.nullness.compatqual.NullableType; /** An array of {@link TrackSelection}s. */ public final class TrackSelectionArray { @@ -24,15 +25,13 @@ public final class TrackSelectionArray { /** The length of this array. */ public final int length; - private final TrackSelection[] trackSelections; + private final @NullableType TrackSelection[] trackSelections; // Lazily initialized hashcode. private int hashCode; - /** - * @param trackSelections The selections. Must not be null, but may contain null elements. - */ - public TrackSelectionArray(TrackSelection... trackSelections) { + /** @param trackSelections The selections. Must not be null, but may contain null elements. */ + public TrackSelectionArray(@NullableType TrackSelection... trackSelections) { this.trackSelections = trackSelections; this.length = trackSelections.length; } @@ -43,14 +42,12 @@ public final class TrackSelectionArray { * @param index The index of the selection. * @return The selection. */ - public TrackSelection get(int index) { + public @Nullable TrackSelection get(int index) { return trackSelections[index]; } - /** - * Returns the selections in a newly allocated array. - */ - public TrackSelection[] getAll() { + /** Returns the selections in a newly allocated array. */ + public @NullableType TrackSelection[] getAll() { return trackSelections.clone(); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelector.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelector.java index a26fee6f78..0c229527a0 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelector.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelector.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.trackselection; +import android.support.annotation.Nullable; import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Renderer; @@ -89,7 +90,7 @@ public abstract class TrackSelector { } - private InvalidationListener listener; + private @Nullable InvalidationListener listener; /** * Called by the player to initialize the selector. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectorResult.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectorResult.java index 882d98764e..f1136f0be5 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectorResult.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectorResult.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer2.trackselection; import com.google.android.exoplayer2.RendererConfiguration; import com.google.android.exoplayer2.util.Util; +import org.checkerframework.checker.nullness.compatqual.NullableType; /** * The result of a {@link TrackSelector} operation. @@ -29,7 +30,7 @@ public final class TrackSelectorResult { * A {@link RendererConfiguration} for each renderer. A null entry indicates the corresponding * renderer should be disabled. */ - public final RendererConfiguration[] rendererConfigurations; + public final @NullableType RendererConfiguration[] rendererConfigurations; /** * A {@link TrackSelectionArray} containing the track selection for each renderer. */ @@ -48,7 +49,9 @@ public final class TrackSelectorResult { * TrackSelector#onSelectionActivated(Object)} should the selection be activated. */ public TrackSelectorResult( - RendererConfiguration[] rendererConfigurations, TrackSelection[] selections, Object info) { + @NullableType RendererConfiguration[] rendererConfigurations, + @NullableType TrackSelection[] selections, + Object info) { this.rendererConfigurations = rendererConfigurations; this.selections = new TrackSelectionArray(selections); this.info = info; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/util/Util.java b/library/core/src/main/java/com/google/android/exoplayer2/util/Util.java index fe83ce13e6..37e3e119bf 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/util/Util.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/util/Util.java @@ -311,10 +311,10 @@ public final class Util { * Returns a normalized RFC 639-2/T code for {@code language}. * * @param language A case-insensitive ISO 639 alpha-2 or alpha-3 language code. - * @return The all-lowercase normalized code, or null if the input was null, or - * {@code language.toLowerCase()} if the language could not be normalized. + * @return The all-lowercase normalized code, or null if the input was null, or {@code + * language.toLowerCase()} if the language could not be normalized. */ - public static String normalizeLanguageCode(String language) { + public static @Nullable String normalizeLanguageCode(@Nullable String language) { try { return language == null ? null : new Locale(language).getISO3Language(); } catch (MissingResourceException e) { diff --git a/library/ui/src/main/java/com/google/android/exoplayer2/ui/TrackSelectionView.java b/library/ui/src/main/java/com/google/android/exoplayer2/ui/TrackSelectionView.java index be0babf5a8..fe5d5cbbc5 100644 --- a/library/ui/src/main/java/com/google/android/exoplayer2/ui/TrackSelectionView.java +++ b/library/ui/src/main/java/com/google/android/exoplayer2/ui/TrackSelectionView.java @@ -203,7 +203,9 @@ public class TrackSelectionView extends LinearLayout { removeViewAt(i); } - if (trackSelector == null) { + MappingTrackSelector.MappedTrackInfo trackInfo = + trackSelector == null ? null : trackSelector.getCurrentMappedTrackInfo(); + if (trackSelector == null || trackInfo == null) { // The view is not initialized. disableView.setEnabled(false); defaultView.setEnabled(false); @@ -212,7 +214,6 @@ public class TrackSelectionView extends LinearLayout { disableView.setEnabled(true); defaultView.setEnabled(true); - MappingTrackSelector.MappedTrackInfo trackInfo = trackSelector.getCurrentMappedTrackInfo(); trackGroups = trackInfo.getTrackGroups(rendererIndex); DefaultTrackSelector.Parameters parameters = trackSelector.getParameters();