diff --git a/extensions/cronet/src/main/java/com/google/android/exoplayer2/ext/cronet/CronetDataSource.java b/extensions/cronet/src/main/java/com/google/android/exoplayer2/ext/cronet/CronetDataSource.java index e1201ff3a2..9a2e3e491d 100644 --- a/extensions/cronet/src/main/java/com/google/android/exoplayer2/ext/cronet/CronetDataSource.java +++ b/extensions/cronet/src/main/java/com/google/android/exoplayer2/ext/cronet/CronetDataSource.java @@ -818,10 +818,10 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource { Matcher matcher = CONTENT_RANGE_HEADER_PATTERN.matcher(contentRangeHeader); if (matcher.find()) { try { - // incompatible types in argument. - @SuppressWarnings("nullness:argument.type.incompatible") long contentLengthFromRange = - Long.parseLong(matcher.group(2)) - Long.parseLong(matcher.group(1)) + 1; + Long.parseLong(Assertions.checkNotNull(matcher.group(2))) + - Long.parseLong(Assertions.checkNotNull(matcher.group(1))) + + 1; if (contentLength < 0) { // Some proxy servers strip the Content-Length header. Fall back to the length // calculated here in this case. diff --git a/library/common/src/main/java/com/google/android/exoplayer2/util/Util.java b/library/common/src/main/java/com/google/android/exoplayer2/util/Util.java index 038f7d8418..4141b534cc 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/util/Util.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/util/Util.java @@ -1740,9 +1740,8 @@ public final class Util { Matcher matcher = ESCAPED_CHARACTER_PATTERN.matcher(fileName); int startOfNotEscaped = 0; while (percentCharacterCount > 0 && matcher.find()) { - // incompatible types in argument. - @SuppressWarnings("nullness:argument.type.incompatible") - char unescapedCharacter = (char) Integer.parseInt(matcher.group(1), 16); + char unescapedCharacter = + (char) Integer.parseInt(Assertions.checkNotNull(matcher.group(1)), 16); builder.append(fileName, startOfNotEscaped, matcher.start()).append(unescapedCharacter); startOfNotEscaped = matcher.end(); percentCharacterCount--; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/metadata/icy/IcyDecoder.java b/library/core/src/main/java/com/google/android/exoplayer2/metadata/icy/IcyDecoder.java index 3ee9ff15a4..cd3c1dfb63 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/metadata/icy/IcyDecoder.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/metadata/icy/IcyDecoder.java @@ -44,8 +44,6 @@ public final class IcyDecoder implements MetadataDecoder { iso88591Decoder = Charset.forName(C.ISO88591_NAME).newDecoder(); } - // switching on a possibly-null value (key) - @SuppressWarnings("nullness:switching.nullable") @Override public Metadata decode(MetadataInputBuffer inputBuffer) { ByteBuffer buffer = Assertions.checkNotNull(inputBuffer.data); @@ -66,13 +64,17 @@ public final class IcyDecoder implements MetadataDecoder { while (matcher.find(index)) { @Nullable String key = Util.toLowerInvariant(matcher.group(1)); @Nullable String value = matcher.group(2); - switch (key) { - case STREAM_KEY_NAME: - name = value; - break; - case STREAM_KEY_URL: - url = value; - break; + if (key != null) { + switch (key) { + case STREAM_KEY_NAME: + name = value; + break; + case STREAM_KEY_URL: + url = value; + break; + default: + break; + } } index = matcher.end(); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaStyle.java b/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaStyle.java index adc4e424df..0cba339034 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaStyle.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaStyle.java @@ -227,10 +227,8 @@ import java.util.regex.Pattern; PointF position = null; Matcher matcher = BRACES_PATTERN.matcher(text); while (matcher.find()) { - String braceContents = matcher.group(1); + String braceContents = Assertions.checkNotNull(matcher.group(1)); try { - // incompatible types in argument. - @SuppressWarnings("nullness:argument.type.incompatible") PointF parsedPosition = parsePosition(braceContents); if (parsedPosition != null) { position = parsedPosition; @@ -239,8 +237,6 @@ import java.util.regex.Pattern; // Ignore invalid \pos() or \move() function. } try { - // incompatible types in argument. - @SuppressWarnings("nullness:argument.type.incompatible") @SsaAlignment int parsedAlignment = parseAlignmentOverride(braceContents); if (parsedAlignment != SSA_ALIGNMENT_UNKNOWN) { @@ -297,12 +293,12 @@ import java.util.regex.Pattern; Float.parseFloat(Assertions.checkNotNull(y).trim())); } - // incompatible types in argument. - @SuppressWarnings("nullness:argument.type.incompatible") @SsaAlignment private static int parseAlignmentOverride(String braceContents) { Matcher matcher = ALIGNMENT_OVERRIDE_PATTERN.matcher(braceContents); - return matcher.find() ? parseAlignment(matcher.group(1)) : SSA_ALIGNMENT_UNKNOWN; + return matcher.find() + ? parseAlignment(Assertions.checkNotNull(matcher.group(1))) + : SSA_ALIGNMENT_UNKNOWN; } } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/text/subrip/SubripDecoder.java b/library/core/src/main/java/com/google/android/exoplayer2/text/subrip/SubripDecoder.java index c3cf814869..51f5973261 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/text/subrip/SubripDecoder.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/text/subrip/SubripDecoder.java @@ -22,6 +22,7 @@ import androidx.annotation.Nullable; import com.google.android.exoplayer2.text.Cue; import com.google.android.exoplayer2.text.SimpleSubtitleDecoder; import com.google.android.exoplayer2.text.Subtitle; +import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.LongArray; import com.google.android.exoplayer2.util.ParsableByteArray; @@ -230,13 +231,12 @@ public final class SubripDecoder extends SimpleSubtitleDecoder { Cue.DIMEN_UNSET); } - // incompatible types in argument. - @SuppressWarnings("nullness:argument.type.incompatible") private static long parseTimecode(Matcher matcher, int groupOffset) { @Nullable String hours = matcher.group(groupOffset + 1); long timestampMs = hours != null ? Long.parseLong(hours) * 60 * 60 * 1000 : 0; - timestampMs += Long.parseLong(matcher.group(groupOffset + 2)) * 60 * 1000; - timestampMs += Long.parseLong(matcher.group(groupOffset + 3)) * 1000; + timestampMs += + Long.parseLong(Assertions.checkNotNull(matcher.group(groupOffset + 2))) * 60 * 1000; + timestampMs += Long.parseLong(Assertions.checkNotNull(matcher.group(groupOffset + 3))) * 1000; @Nullable String millis = matcher.group(groupOffset + 4); if (millis != null) { timestampMs += Long.parseLong(millis); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/text/webvtt/CssParser.java b/library/core/src/main/java/com/google/android/exoplayer2/text/webvtt/CssParser.java index 1df923ed0c..5efe378a9b 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/text/webvtt/CssParser.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/text/webvtt/CssParser.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer2.text.webvtt; import android.text.TextUtils; import androidx.annotation.Nullable; +import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.ColorParser; import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.Util; @@ -325,8 +326,6 @@ import java.util.regex.Pattern; * Sets the target of a {@link WebvttCssStyle} by splitting a selector of the form {@code * ::cue(tag#id.class1.class2[voice="someone"]}, where every element is optional. */ - // incompatible types in argument. - @SuppressWarnings("nullness:argument.type.incompatible") private void applySelectorToStyle(WebvttCssStyle style, String selector) { if ("".equals(selector)) { return; // Universal selector. @@ -335,7 +334,7 @@ import java.util.regex.Pattern; if (voiceStartIndex != -1) { Matcher matcher = VOICE_NAME_PATTERN.matcher(selector.substring(voiceStartIndex)); if (matcher.matches()) { - style.setTargetVoice(matcher.group(1)); + style.setTargetVoice(Assertions.checkNotNull(matcher.group(1))); } selector = selector.substring(0, voiceStartIndex); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/text/webvtt/WebvttCueParser.java b/library/core/src/main/java/com/google/android/exoplayer2/text/webvtt/WebvttCueParser.java index b82fd93b03..7bd96b23e9 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/text/webvtt/WebvttCueParser.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/text/webvtt/WebvttCueParser.java @@ -323,8 +323,6 @@ public final class WebvttCueParser { // Internal methods - // incompatible types in argument. - @SuppressWarnings("nullness:argument.type.incompatible") @Nullable private static WebvttCueInfo parseCue( @Nullable String id, @@ -334,14 +332,16 @@ public final class WebvttCueParser { WebvttCueInfoBuilder builder = new WebvttCueInfoBuilder(); try { // Parse the cue start and end times. - builder.startTimeUs = WebvttParserUtil.parseTimestampUs(cueHeaderMatcher.group(1)); - builder.endTimeUs = WebvttParserUtil.parseTimestampUs(cueHeaderMatcher.group(2)); + builder.startTimeUs = + WebvttParserUtil.parseTimestampUs(Assertions.checkNotNull(cueHeaderMatcher.group(1))); + builder.endTimeUs = + WebvttParserUtil.parseTimestampUs(Assertions.checkNotNull(cueHeaderMatcher.group(2))); } catch (NumberFormatException e) { Log.w(TAG, "Skipping cue with bad header: " + cueHeaderMatcher.group()); return null; } - parseCueSettingsList(cueHeaderMatcher.group(3), builder); + parseCueSettingsList(Assertions.checkNotNull(cueHeaderMatcher.group(3)), builder); // Parse the cue text. StringBuilder textBuilder = new StringBuilder(); @@ -357,15 +357,13 @@ public final class WebvttCueParser { return builder.build(); } - // incompatible types in argument. - @SuppressWarnings("nullness:argument.type.incompatible") private static void parseCueSettingsList(String cueSettingsList, WebvttCueInfoBuilder builder) { // Parse the cue settings list. Matcher cueSettingMatcher = CUE_SETTING_PATTERN.matcher(cueSettingsList); while (cueSettingMatcher.find()) { - String name = cueSettingMatcher.group(1); - String value = cueSettingMatcher.group(2); + String name = Assertions.checkNotNull(cueSettingMatcher.group(1)); + String value = Assertions.checkNotNull(cueSettingMatcher.group(2)); try { if ("line".equals(name)) { parseLineAttribute(value, builder); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/SimpleCacheSpan.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/SimpleCacheSpan.java index 683eaeee28..d8a0671469 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/SimpleCacheSpan.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/SimpleCacheSpan.java @@ -113,8 +113,6 @@ import java.util.regex.Pattern; * @return The span, or null if the file name is not correctly formatted, or if the id is not * present in the content index, or if the length is 0. */ - // incompatible types in argument. - @SuppressWarnings("nullness:argument.type.incompatible") @Nullable public static SimpleCacheSpan createCacheEntry( File file, long length, long lastTouchTimestamp, CachedContentIndex index) { @@ -133,9 +131,7 @@ import java.util.regex.Pattern; return null; } - // incompatible types in argument. - @SuppressWarnings("nullness:argument.type.incompatible") - int id = Integer.parseInt(matcher.group(1)); + int id = Integer.parseInt(Assertions.checkNotNull(matcher.group(1))); @Nullable String key = index.getKeyForId(id); if (key == null) { return null; @@ -148,11 +144,9 @@ import java.util.regex.Pattern; return null; } - // incompatible types in argument. - @SuppressWarnings("nullness:argument.type.incompatible") - long position = Long.parseLong(matcher.group(2)); + long position = Long.parseLong(Assertions.checkNotNull(matcher.group(2))); if (lastTouchTimestamp == C.TIME_UNSET) { - lastTouchTimestamp = Long.parseLong(matcher.group(3)); + lastTouchTimestamp = Long.parseLong(Assertions.checkNotNull(matcher.group(3))); } return new SimpleCacheSpan(key, position, length, lastTouchTimestamp, file); } @@ -165,19 +159,17 @@ import java.util.regex.Pattern; * @return Upgraded cache file or {@code null} if the file name is not correctly formatted or the * file can not be renamed. */ - // incompatible types in argument. - @SuppressWarnings("nullness:argument.type.incompatible") @Nullable private static File upgradeFile(File file, CachedContentIndex index) { @Nullable String key = null; String filename = file.getName(); Matcher matcher = CACHE_FILE_PATTERN_V2.matcher(filename); if (matcher.matches()) { - key = Util.unescapeFileName(matcher.group(1)); + key = Util.unescapeFileName(Assertions.checkNotNull(matcher.group(1))); } else { matcher = CACHE_FILE_PATTERN_V1.matcher(filename); if (matcher.matches()) { - key = matcher.group(1); // Keys were not escaped in version 1. + key = Assertions.checkNotNull(matcher.group(1)); // Keys were not escaped in version 1. } } @@ -185,14 +177,12 @@ import java.util.regex.Pattern; return null; } - // incompatible types in argument. - @SuppressWarnings("nullness:argument.type.incompatible") File newCacheFile = getCacheFile( Assertions.checkStateNotNull(file.getParentFile()), index.assignIdForKey(key), - Long.parseLong(matcher.group(2)), - Long.parseLong(matcher.group(3))); + Long.parseLong(Assertions.checkNotNull(matcher.group(2))), + Long.parseLong(Assertions.checkNotNull(matcher.group(3)))); if (!file.renameTo(newCacheFile)) { return null; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/util/ColorParser.java b/library/core/src/main/java/com/google/android/exoplayer2/util/ColorParser.java index c623d26465..808bd77fb8 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/util/ColorParser.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/util/ColorParser.java @@ -63,8 +63,6 @@ public final class ColorParser { return parseColorInternal(colorExpression, true); } - // incompatible types in argument. - @SuppressWarnings("nullness:argument.type.incompatible") private static int parseColorInternal(String colorExpression, boolean alphaHasFloatFormat) { Assertions.checkArgument(!TextUtils.isEmpty(colorExpression)); colorExpression = colorExpression.replace(" ", ""); @@ -86,21 +84,20 @@ public final class ColorParser { .matcher(colorExpression); if (matcher.matches()) { return argb( - alphaHasFloatFormat ? (int) (255 * Float.parseFloat(matcher.group(4))) - : Integer.parseInt(matcher.group(4), 10), - Integer.parseInt(matcher.group(1), 10), - Integer.parseInt(matcher.group(2), 10), - Integer.parseInt(matcher.group(3), 10) - ); + alphaHasFloatFormat + ? (int) (255 * Float.parseFloat(Assertions.checkNotNull(matcher.group(4)))) + : Integer.parseInt(Assertions.checkNotNull(matcher.group(4)), 10), + Integer.parseInt(Assertions.checkNotNull(matcher.group(1)), 10), + Integer.parseInt(Assertions.checkNotNull(matcher.group(2)), 10), + Integer.parseInt(Assertions.checkNotNull(matcher.group(3)), 10)); } } else if (colorExpression.startsWith(RGB)) { Matcher matcher = RGB_PATTERN.matcher(colorExpression); if (matcher.matches()) { return rgb( - Integer.parseInt(matcher.group(1), 10), - Integer.parseInt(matcher.group(2), 10), - Integer.parseInt(matcher.group(3), 10) - ); + Integer.parseInt(Assertions.checkNotNull(matcher.group(1)), 10), + Integer.parseInt(Assertions.checkNotNull(matcher.group(2)), 10), + Integer.parseInt(Assertions.checkNotNull(matcher.group(3)), 10)); } } else { // we use our own color map diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/WebvttExtractor.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/WebvttExtractor.java index 2ff912e88d..6a390001d2 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/WebvttExtractor.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/WebvttExtractor.java @@ -133,8 +133,6 @@ public final class WebvttExtractor implements Extractor { return Extractor.RESULT_END_OF_INPUT; } - // incompatible types in argument. - @SuppressWarnings("nullness:argument.type.incompatible") @RequiresNonNull("output") private void processSample() throws ParserException { ParsableByteArray webvttData = new ParsableByteArray(sampleData); @@ -159,8 +157,12 @@ public final class WebvttExtractor implements Extractor { if (!mediaTimestampMatcher.find()) { throw new ParserException("X-TIMESTAMP-MAP doesn't contain media timestamp: " + line); } - vttTimestampUs = WebvttParserUtil.parseTimestampUs(localTimestampMatcher.group(1)); - tsTimestampUs = TimestampAdjuster.ptsToUs(Long.parseLong(mediaTimestampMatcher.group(1))); + vttTimestampUs = + WebvttParserUtil.parseTimestampUs( + Assertions.checkNotNull(localTimestampMatcher.group(1))); + tsTimestampUs = + TimestampAdjuster.ptsToUs( + Long.parseLong(Assertions.checkNotNull(mediaTimestampMatcher.group(1)))); } } @@ -172,9 +174,8 @@ public final class WebvttExtractor implements Extractor { return; } - // incompatible types in argument. - @SuppressWarnings("nullness:argument.type.incompatible") - long firstCueTimeUs = WebvttParserUtil.parseTimestampUs(cueHeaderMatcher.group(1)); + long firstCueTimeUs = + WebvttParserUtil.parseTimestampUs(Assertions.checkNotNull(cueHeaderMatcher.group(1))); long sampleTimeUs = timestampAdjuster.adjustTsTimestamp( TimestampAdjuster.usToPts(firstCueTimeUs + tsTimestampUs - vttTimestampUs)); long subsampleOffsetUs = sampleTimeUs - firstCueTimeUs; diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java index 14fc420ef3..8a0d190f2e 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java @@ -845,12 +845,10 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser variableDefinitions) { Matcher matcher = pattern.matcher(line); - String value = matcher.find() ? matcher.group(1) : defaultValue; + @PolyNull + String value = matcher.find() ? Assertions.checkNotNull(matcher.group(1)) : defaultValue; return variableDefinitions.isEmpty() || value == null ? value : replaceVariableReferences(value, variableDefinitions); @@ -911,13 +908,11 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser