Commit 074b6f8e by tonihei Committed by Oliver Woodman

Fix DASH module API nullability issues and add package-level non-null-by-default

PiperOrigin-RevId: 262123595
parent 79e962c5
......@@ -41,6 +41,7 @@ android {
dependencies {
implementation project(modulePrefix + 'library-core')
compileOnly 'org.checkerframework:checker-qual:' + checkerframeworkVersion
compileOnly 'org.checkerframework:checker-compat-qual:' + checkerframeworkVersion
implementation 'androidx.annotation:annotation:1.1.0'
testImplementation project(modulePrefix + 'testutils-robolectric')
}
......
......@@ -60,6 +60,7 @@ import java.util.IdentityHashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.checkerframework.checker.nullness.compatqual.NullableType;
/** A DASH {@link MediaPeriod}. */
/* package */ final class DashMediaPeriod
......@@ -245,8 +246,12 @@ import java.util.regex.Pattern;
}
@Override
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
public long selectTracks(
@NullableType TrackSelection[] selections,
boolean[] mayRetainStreamFlags,
@NullableType SampleStream[] streams,
boolean[] streamResetFlags,
long positionUs) {
int[] streamIndexToTrackGroupIndex = getStreamIndexToTrackGroupIndex(selections);
releaseDisabledStreams(selections, mayRetainStreamFlags, streams);
releaseOrphanEmbeddedStreams(selections, streams, streamIndexToTrackGroupIndex);
......
......@@ -130,7 +130,7 @@ public final class DashMediaSource extends BaseMediaSource {
* @return This factory, for convenience.
* @throws IllegalStateException If one of the {@code create} methods has already been called.
*/
public Factory setTag(Object tag) {
public Factory setTag(@Nullable Object tag) {
Assertions.checkState(!isCreateCalled);
this.tag = tag;
return this;
......@@ -430,8 +430,8 @@ public final class DashMediaSource extends BaseMediaSource {
public DashMediaSource(
DashManifest manifest,
DashChunkSource.Factory chunkSourceFactory,
Handler eventHandler,
MediaSourceEventListener eventListener) {
@Nullable Handler eventHandler,
@Nullable MediaSourceEventListener eventListener) {
this(
manifest,
chunkSourceFactory,
......@@ -455,8 +455,8 @@ public final class DashMediaSource extends BaseMediaSource {
DashManifest manifest,
DashChunkSource.Factory chunkSourceFactory,
int minLoadableRetryCount,
Handler eventHandler,
MediaSourceEventListener eventListener) {
@Nullable Handler eventHandler,
@Nullable MediaSourceEventListener eventListener) {
this(
manifest,
/* manifestUri= */ null,
......@@ -492,8 +492,8 @@ public final class DashMediaSource extends BaseMediaSource {
Uri manifestUri,
DataSource.Factory manifestDataSourceFactory,
DashChunkSource.Factory chunkSourceFactory,
Handler eventHandler,
MediaSourceEventListener eventListener) {
@Nullable Handler eventHandler,
@Nullable MediaSourceEventListener eventListener) {
this(
manifestUri,
manifestDataSourceFactory,
......@@ -529,8 +529,8 @@ public final class DashMediaSource extends BaseMediaSource {
DashChunkSource.Factory chunkSourceFactory,
int minLoadableRetryCount,
long livePresentationDelayMs,
Handler eventHandler,
MediaSourceEventListener eventListener) {
@Nullable Handler eventHandler,
@Nullable MediaSourceEventListener eventListener) {
this(
manifestUri,
manifestDataSourceFactory,
......@@ -569,8 +569,8 @@ public final class DashMediaSource extends BaseMediaSource {
DashChunkSource.Factory chunkSourceFactory,
int minLoadableRetryCount,
long livePresentationDelayMs,
Handler eventHandler,
MediaSourceEventListener eventListener) {
@Nullable Handler eventHandler,
@Nullable MediaSourceEventListener eventListener) {
this(
/* manifest= */ null,
manifestUri,
......@@ -591,10 +591,10 @@ public final class DashMediaSource extends BaseMediaSource {
}
private DashMediaSource(
DashManifest manifest,
Uri manifestUri,
DataSource.Factory manifestDataSourceFactory,
ParsingLoadable.Parser<? extends DashManifest> manifestParser,
@Nullable DashManifest manifest,
@Nullable Uri manifestUri,
@Nullable DataSource.Factory manifestDataSourceFactory,
@Nullable ParsingLoadable.Parser<? extends DashManifest> manifestParser,
DashChunkSource.Factory chunkSourceFactory,
CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory,
DrmSessionManager<?> drmSessionManager,
......
......@@ -66,7 +66,8 @@ public final class DashUtil {
* @throws IOException Thrown when there is an error while loading.
* @throws InterruptedException Thrown if the thread was interrupted.
*/
public static @Nullable DrmInitData loadDrmInitData(DataSource dataSource, Period period)
@Nullable
public static DrmInitData loadDrmInitData(DataSource dataSource, Period period)
throws IOException, InterruptedException {
int primaryTrackType = C.TRACK_TYPE_VIDEO;
Representation representation = getFirstRepresentation(period, primaryTrackType);
......@@ -95,7 +96,8 @@ public final class DashUtil {
* @throws IOException Thrown when there is an error while loading.
* @throws InterruptedException Thrown if the thread was interrupted.
*/
public static @Nullable Format loadSampleFormat(
@Nullable
public static Format loadSampleFormat(
DataSource dataSource, int trackType, Representation representation)
throws IOException, InterruptedException {
ChunkExtractorWrapper extractorWrapper = loadInitializationData(dataSource, trackType,
......@@ -116,7 +118,8 @@ public final class DashUtil {
* @throws IOException Thrown when there is an error while loading.
* @throws InterruptedException Thrown if the thread was interrupted.
*/
public static @Nullable ChunkIndex loadChunkIndex(
@Nullable
public static ChunkIndex loadChunkIndex(
DataSource dataSource, int trackType, Representation representation)
throws IOException, InterruptedException {
ChunkExtractorWrapper extractorWrapper = loadInitializationData(dataSource, trackType,
......@@ -138,7 +141,8 @@ public final class DashUtil {
* @throws IOException Thrown when there is an error while loading.
* @throws InterruptedException Thrown if the thread was interrupted.
*/
private static @Nullable ChunkExtractorWrapper loadInitializationData(
@Nullable
private static ChunkExtractorWrapper loadInitializationData(
DataSource dataSource, int trackType, Representation representation, boolean loadIndex)
throws IOException, InterruptedException {
RangedUri initializationUri = representation.getInitializationUri();
......@@ -187,7 +191,8 @@ public final class DashUtil {
return new ChunkExtractorWrapper(extractor, trackType, format);
}
private static @Nullable Representation getFirstRepresentation(Period period, int type) {
@Nullable
private static Representation getFirstRepresentation(Period period, int type) {
int index = period.getAdaptationSetIndex(type);
if (index == C.INDEX_UNSET) {
return null;
......@@ -197,5 +202,4 @@ public final class DashUtil {
}
private DashUtil() {}
}
......@@ -67,7 +67,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
private final int maxSegmentsPerLoad;
public Factory(DataSource.Factory dataSourceFactory) {
this(dataSourceFactory, 1);
this(dataSourceFactory, /* maxSegmentsPerLoad= */ 1);
}
public Factory(DataSource.Factory dataSourceFactory, int maxSegmentsPerLoad) {
......@@ -633,7 +633,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
Representation representation,
boolean enableEventMessageTrack,
List<Format> closedCaptionFormats,
TrackOutput playerEmsgTrackOutput) {
@Nullable TrackOutput playerEmsgTrackOutput) {
this(
periodDurationUs,
representation,
......@@ -787,7 +787,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
Representation representation,
boolean enableEventMessageTrack,
List<Format> closedCaptionFormats,
TrackOutput playerEmsgTrackOutput) {
@Nullable TrackOutput playerEmsgTrackOutput) {
String containerMimeType = representation.format.containerMimeType;
if (mimeTypeIsRawText(containerMimeType)) {
return null;
......
......@@ -80,12 +80,10 @@ public class DashManifest implements FilterableManifest<DashManifest> {
* The {@link UtcTimingElement}, or null if not present. Defined in DVB A168:7/2016, Section
* 4.7.2.
*/
public final UtcTimingElement utcTiming;
@Nullable public final UtcTimingElement utcTiming;
/**
* The location of this manifest.
*/
public final Uri location;
/** The location of this manifest, or null if not present. */
@Nullable public final Uri location;
/** The {@link ProgramInformation}, or null if not present. */
@Nullable public final ProgramInformation programInformation;
......@@ -106,8 +104,8 @@ public class DashManifest implements FilterableManifest<DashManifest> {
long timeShiftBufferDepthMs,
long suggestedPresentationDelayMs,
long publishTimeMs,
UtcTimingElement utcTiming,
Uri location,
@Nullable UtcTimingElement utcTiming,
@Nullable Uri location,
List<Period> periods) {
this(
availabilityStartTimeMs,
......@@ -134,8 +132,8 @@ public class DashManifest implements FilterableManifest<DashManifest> {
long suggestedPresentationDelayMs,
long publishTimeMs,
@Nullable ProgramInformation programInformation,
UtcTimingElement utcTiming,
Uri location,
@Nullable UtcTimingElement utcTiming,
@Nullable Uri location,
List<Period> periods) {
this.availabilityStartTimeMs = availabilityStartTimeMs;
this.durationMs = durationMs;
......
......@@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.source.dash.manifest;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.util.Util;
......@@ -24,10 +23,8 @@ import com.google.android.exoplayer2.util.Util;
*/
public final class Descriptor {
/**
* The scheme URI.
*/
@NonNull public final String schemeIdUri;
/** The scheme URI. */
public final String schemeIdUri;
/**
* The value, or null.
*/
......@@ -42,7 +39,7 @@ public final class Descriptor {
* @param value The value, or null.
* @param id The identifier, or null.
*/
public Descriptor(@NonNull String schemeIdUri, @Nullable String value, @Nullable String id) {
public Descriptor(String schemeIdUri, @Nullable String value, @Nullable String id) {
this.schemeIdUri = schemeIdUri;
this.value = value;
this.id = id;
......@@ -63,10 +60,9 @@ public final class Descriptor {
@Override
public int hashCode() {
int result = (schemeIdUri != null ? schemeIdUri.hashCode() : 0);
int result = schemeIdUri.hashCode();
result = 31 * result + (value != null ? value.hashCode() : 0);
result = 31 * result + (id != null ? id.hashCode() : 0);
return result;
}
}
......@@ -21,22 +21,26 @@ import com.google.android.exoplayer2.util.Util;
/** A parsed program information element. */
public class ProgramInformation {
/** The title for the media presentation. */
public final String title;
@Nullable public final String title;
/** Information about the original source of the media presentation. */
public final String source;
@Nullable public final String source;
/** A copyright statement for the media presentation. */
public final String copyright;
@Nullable public final String copyright;
/** A URL that provides more information about the media presentation. */
public final String moreInformationURL;
@Nullable public final String moreInformationURL;
/** Declares the language code(s) for this ProgramInformation. */
public final String lang;
@Nullable public final String lang;
public ProgramInformation(
String title, String source, String copyright, String moreInformationURL, String lang) {
@Nullable String title,
@Nullable String source,
@Nullable String copyright,
@Nullable String moreInformationURL,
@Nullable String lang) {
this.title = title;
this.source = source;
this.copyright = copyright;
......
......@@ -83,7 +83,7 @@ public final class RangedUri {
* <p>If {@code other} is null then the merge is considered unsuccessful, and null is returned.
*
* @param other The {@link RangedUri} to merge.
* @param baseUri The optional base Uri.
* @param baseUri The base Uri.
* @return The merged {@link RangedUri} if the merge was successful. Null otherwise.
*/
@Nullable
......
......@@ -16,6 +16,7 @@
package com.google.android.exoplayer2.source.dash.manifest;
import android.net.Uri;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.source.dash.DashSegmentIndex;
......@@ -53,9 +54,7 @@ public abstract class Representation {
* The offset of the presentation timestamps in the media stream relative to media time.
*/
public final long presentationTimeOffsetUs;
/**
* The in-band event streams in the representation. Never null, but may be empty.
*/
/** The in-band event streams in the representation. May be empty. */
public final List<Descriptor> inbandEventStreams;
private final RangedUri initializationUri;
......@@ -71,7 +70,7 @@ public abstract class Representation {
*/
public static Representation newInstance(
long revisionId, Format format, String baseUrl, SegmentBase segmentBase) {
return newInstance(revisionId, format, baseUrl, segmentBase, null);
return newInstance(revisionId, format, baseUrl, segmentBase, /* inbandEventStreams= */ null);
}
/**
......@@ -89,8 +88,9 @@ public abstract class Representation {
Format format,
String baseUrl,
SegmentBase segmentBase,
List<Descriptor> inbandEventStreams) {
return newInstance(revisionId, format, baseUrl, segmentBase, inbandEventStreams, null);
@Nullable List<Descriptor> inbandEventStreams) {
return newInstance(
revisionId, format, baseUrl, segmentBase, inbandEventStreams, /* cacheKey= */ null);
}
/**
......@@ -110,8 +110,8 @@ public abstract class Representation {
Format format,
String baseUrl,
SegmentBase segmentBase,
List<Descriptor> inbandEventStreams,
String cacheKey) {
@Nullable List<Descriptor> inbandEventStreams,
@Nullable String cacheKey) {
if (segmentBase instanceof SingleSegmentBase) {
return new SingleSegmentRepresentation(
revisionId,
......@@ -135,7 +135,7 @@ public abstract class Representation {
Format format,
String baseUrl,
SegmentBase segmentBase,
List<Descriptor> inbandEventStreams) {
@Nullable List<Descriptor> inbandEventStreams) {
this.revisionId = revisionId;
this.format = format;
this.baseUrl = baseUrl;
......@@ -151,6 +151,7 @@ public abstract class Representation {
* Returns a {@link RangedUri} defining the location of the representation's initialization data,
* or null if no initialization data exists.
*/
@Nullable
public RangedUri getInitializationUri() {
return initializationUri;
}
......@@ -159,14 +160,15 @@ public abstract class Representation {
* Returns a {@link RangedUri} defining the location of the representation's segment index, or
* null if the representation provides an index directly.
*/
@Nullable
public abstract RangedUri getIndexUri();
/**
* Returns an index if the representation provides one directly, or null otherwise.
*/
/** Returns an index if the representation provides one directly, or null otherwise. */
@Nullable
public abstract DashSegmentIndex getIndex();
/** Returns a cache key for the representation if set, or null. */
@Nullable
public abstract String getCacheKey();
/**
......@@ -184,9 +186,9 @@ public abstract class Representation {
*/
public final long contentLength;
private final String cacheKey;
private final RangedUri indexUri;
private final SingleSegmentIndex segmentIndex;
@Nullable private final String cacheKey;
@Nullable private final RangedUri indexUri;
@Nullable private final SingleSegmentIndex segmentIndex;
/**
* @param revisionId Identifies the revision of the content.
......@@ -209,7 +211,7 @@ public abstract class Representation {
long indexStart,
long indexEnd,
List<Descriptor> inbandEventStreams,
String cacheKey,
@Nullable String cacheKey,
long contentLength) {
RangedUri rangedUri = new RangedUri(null, initializationStart,
initializationEnd - initializationStart + 1);
......@@ -233,8 +235,8 @@ public abstract class Representation {
Format format,
String baseUrl,
SingleSegmentBase segmentBase,
List<Descriptor> inbandEventStreams,
String cacheKey,
@Nullable List<Descriptor> inbandEventStreams,
@Nullable String cacheKey,
long contentLength) {
super(revisionId, format, baseUrl, segmentBase, inbandEventStreams);
this.uri = Uri.parse(baseUrl);
......@@ -248,16 +250,19 @@ public abstract class Representation {
}
@Override
@Nullable
public RangedUri getIndexUri() {
return indexUri;
}
@Override
@Nullable
public DashSegmentIndex getIndex() {
return segmentIndex;
}
@Override
@Nullable
public String getCacheKey() {
return cacheKey;
}
......@@ -284,12 +289,13 @@ public abstract class Representation {
Format format,
String baseUrl,
MultiSegmentBase segmentBase,
List<Descriptor> inbandEventStreams) {
@Nullable List<Descriptor> inbandEventStreams) {
super(revisionId, format, baseUrl, segmentBase, inbandEventStreams);
this.segmentBase = segmentBase;
}
@Override
@Nullable
public RangedUri getIndexUri() {
return null;
}
......@@ -300,6 +306,7 @@ public abstract class Representation {
}
@Override
@Nullable
public String getCacheKey() {
return null;
}
......
......@@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.source.dash.manifest;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.source.dash.DashSegmentIndex;
import com.google.android.exoplayer2.util.Util;
......@@ -25,7 +26,7 @@ import java.util.List;
*/
public abstract class SegmentBase {
/* package */ final RangedUri initialization;
/* package */ @Nullable final RangedUri initialization;
/* package */ final long timescale;
/* package */ final long presentationTimeOffset;
......@@ -36,7 +37,8 @@ public abstract class SegmentBase {
* @param presentationTimeOffset The presentation time offset. The value in seconds is the
* division of this value and {@code timescale}.
*/
public SegmentBase(RangedUri initialization, long timescale, long presentationTimeOffset) {
public SegmentBase(
@Nullable RangedUri initialization, long timescale, long presentationTimeOffset) {
this.initialization = initialization;
this.timescale = timescale;
this.presentationTimeOffset = presentationTimeOffset;
......@@ -49,6 +51,7 @@ public abstract class SegmentBase {
* @param representation The {@link Representation} for which initialization data is required.
* @return A {@link RangedUri} defining the location of the initialization data, or null.
*/
@Nullable
public RangedUri getInitialization(Representation representation) {
return initialization;
}
......@@ -77,19 +80,31 @@ public abstract class SegmentBase {
* @param indexStart The byte offset of the index data in the segment.
* @param indexLength The length of the index data in bytes.
*/
public SingleSegmentBase(RangedUri initialization, long timescale, long presentationTimeOffset,
long indexStart, long indexLength) {
public SingleSegmentBase(
@Nullable RangedUri initialization,
long timescale,
long presentationTimeOffset,
long indexStart,
long indexLength) {
super(initialization, timescale, presentationTimeOffset);
this.indexStart = indexStart;
this.indexLength = indexLength;
}
public SingleSegmentBase() {
this(null, 1, 0, 0, 0);
this(
/* initialization= */ null,
/* timescale= */ 1,
/* presentationTimeOffset= */ 0,
/* indexStart= */ 0,
/* indexLength= */ 0);
}
@Nullable
public RangedUri getIndex() {
return indexLength <= 0 ? null : new RangedUri(null, indexStart, indexLength);
return indexLength <= 0
? null
: new RangedUri(/* referenceUri= */ null, indexStart, indexLength);
}
}
......@@ -101,7 +116,7 @@ public abstract class SegmentBase {
/* package */ final long startNumber;
/* package */ final long duration;
/* package */ final List<SegmentTimelineElement> segmentTimeline;
/* package */ @Nullable final List<SegmentTimelineElement> segmentTimeline;
/**
* @param initialization A {@link RangedUri} corresponding to initialization data, if such data
......@@ -118,12 +133,12 @@ public abstract class SegmentBase {
* parameter.
*/
public MultiSegmentBase(
RangedUri initialization,
@Nullable RangedUri initialization,
long timescale,
long presentationTimeOffset,
long startNumber,
long duration,
List<SegmentTimelineElement> segmentTimeline) {
@Nullable List<SegmentTimelineElement> segmentTimeline) {
super(initialization, timescale, presentationTimeOffset);
this.startNumber = startNumber;
this.duration = duration;
......@@ -223,7 +238,7 @@ public abstract class SegmentBase {
*/
public static class SegmentList extends MultiSegmentBase {
/* package */ final List<RangedUri> mediaSegments;
/* package */ @Nullable final List<RangedUri> mediaSegments;
/**
* @param initialization A {@link RangedUri} corresponding to initialization data, if such data
......@@ -246,8 +261,8 @@ public abstract class SegmentBase {
long presentationTimeOffset,
long startNumber,
long duration,
List<SegmentTimelineElement> segmentTimeline,
List<RangedUri> mediaSegments) {
@Nullable List<SegmentTimelineElement> segmentTimeline,
@Nullable List<RangedUri> mediaSegments) {
super(initialization, timescale, presentationTimeOffset, startNumber, duration,
segmentTimeline);
this.mediaSegments = mediaSegments;
......@@ -275,8 +290,8 @@ public abstract class SegmentBase {
*/
public static class SegmentTemplate extends MultiSegmentBase {
/* package */ final UrlTemplate initializationTemplate;
/* package */ final UrlTemplate mediaTemplate;
/* package */ @Nullable final UrlTemplate initializationTemplate;
/* package */ @Nullable final UrlTemplate mediaTemplate;
/* package */ final long endNumber;
/**
......@@ -308,9 +323,9 @@ public abstract class SegmentBase {
long startNumber,
long endNumber,
long duration,
List<SegmentTimelineElement> segmentTimeline,
UrlTemplate initializationTemplate,
UrlTemplate mediaTemplate) {
@Nullable List<SegmentTimelineElement> segmentTimeline,
@Nullable UrlTemplate initializationTemplate,
@Nullable UrlTemplate mediaTemplate) {
super(
initialization,
timescale,
......@@ -324,6 +339,7 @@ public abstract class SegmentBase {
}
@Override
@Nullable
public RangedUri getInitialization(Representation representation) {
if (initializationTemplate != null) {
String urlString = initializationTemplate.buildUri(representation.format.id, 0,
......
/*
* Copyright (C) 2019 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.
*/
@NonNullApi
package com.google.android.exoplayer2.source.dash.manifest;
import com.google.android.exoplayer2.util.NonNullApi;
/*
* Copyright (C) 2019 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.
*/
@NonNullApi
package com.google.android.exoplayer2.source.dash.offline;
import com.google.android.exoplayer2.util.NonNullApi;
/*
* Copyright (C) 2019 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.
*/
@NonNullApi
package com.google.android.exoplayer2.source.dash;
import com.google.android.exoplayer2.util.NonNullApi;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment