From 074b6f8ebd14371ccfa699fadacb8b15dcdc1b57 Mon Sep 17 00:00:00 2001 From: tonihei Date: Wed, 7 Aug 2019 14:36:57 +0100 Subject: [PATCH] Fix DASH module API nullability issues and add package-level non-null-by-default PiperOrigin-RevId: 262123595 --- library/dash/build.gradle | 1 + .../source/dash/DashMediaPeriod.java | 9 +- .../source/dash/DashMediaSource.java | 30 +++--- .../exoplayer2/source/dash/DashUtil.java | 16 ++-- .../source/dash/DefaultDashChunkSource.java | 6 +- .../source/dash/manifest/DashManifest.java | 16 ++-- .../dash/manifest/DashManifestParser.java | 94 +++++++++++-------- .../source/dash/manifest/Descriptor.java | 12 +-- .../dash/manifest/ProgramInformation.java | 16 ++-- .../source/dash/manifest/RangedUri.java | 2 +- .../source/dash/manifest/Representation.java | 45 +++++---- .../source/dash/manifest/SegmentBase.java | 50 ++++++---- .../source/dash/manifest/package-info.java | 19 ++++ .../source/dash/offline/package-info.java | 19 ++++ .../exoplayer2/source/dash/package-info.java | 19 ++++ 15 files changed, 228 insertions(+), 126 deletions(-) create mode 100644 library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/package-info.java create mode 100644 library/dash/src/main/java/com/google/android/exoplayer2/source/dash/offline/package-info.java create mode 100644 library/dash/src/main/java/com/google/android/exoplayer2/source/dash/package-info.java diff --git a/library/dash/build.gradle b/library/dash/build.gradle index 9f5775d478..c34ed8c907 100644 --- a/library/dash/build.gradle +++ b/library/dash/build.gradle @@ -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') } diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java index 5daa1a8fd5..21fd43da21 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java @@ -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); diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java index 576491b464..890a272c5e 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java @@ -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 manifestParser, + @Nullable DashManifest manifest, + @Nullable Uri manifestUri, + @Nullable DataSource.Factory manifestDataSourceFactory, + @Nullable ParsingLoadable.Parser manifestParser, DashChunkSource.Factory chunkSourceFactory, CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory, DrmSessionManager drmSessionManager, diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashUtil.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashUtil.java index 6a6e08ce1d..c9433b9e41 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashUtil.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashUtil.java @@ -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() {} - } diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSource.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSource.java index bcf0a1766a..cd39c9538a 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSource.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSource.java @@ -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 closedCaptionFormats, - TrackOutput playerEmsgTrackOutput) { + @Nullable TrackOutput playerEmsgTrackOutput) { this( periodDurationUs, representation, @@ -787,7 +787,7 @@ public class DefaultDashChunkSource implements DashChunkSource { Representation representation, boolean enableEventMessageTrack, List closedCaptionFormats, - TrackOutput playerEmsgTrackOutput) { + @Nullable TrackOutput playerEmsgTrackOutput) { String containerMimeType = representation.format.containerMimeType; if (mimeTypeIsRawText(containerMimeType)) { return null; diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifest.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifest.java index 0c3f641cbe..2d8909f8b4 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifest.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifest.java @@ -80,12 +80,10 @@ public class DashManifest implements FilterableManifest { * 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 { long timeShiftBufferDepthMs, long suggestedPresentationDelayMs, long publishTimeMs, - UtcTimingElement utcTiming, - Uri location, + @Nullable UtcTimingElement utcTiming, + @Nullable Uri location, List periods) { this( availabilityStartTimeMs, @@ -134,8 +132,8 @@ public class DashManifest implements FilterableManifest { long suggestedPresentationDelayMs, long publishTimeMs, @Nullable ProgramInformation programInformation, - UtcTimingElement utcTiming, - Uri location, + @Nullable UtcTimingElement utcTiming, + @Nullable Uri location, List periods) { this.availabilityStartTimeMs = availabilityStartTimeMs; this.durationMs = durationMs; diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java index 1419f8198c..8affcb27ce 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java @@ -16,6 +16,7 @@ package com.google.android.exoplayer2.source.dash.manifest; import android.net.Uri; +import androidx.annotation.Nullable; import android.text.TextUtils; import android.util.Base64; import android.util.Pair; @@ -47,6 +48,7 @@ import java.util.List; import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.checkerframework.checker.nullness.compatqual.NullableType; import org.xml.sax.helpers.DefaultHandler; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -189,9 +191,9 @@ public class DashManifestParser extends DefaultHandler long timeShiftBufferDepthMs, long suggestedPresentationDelayMs, long publishTimeMs, - ProgramInformation programInformation, - UtcTimingElement utcTiming, - Uri location, + @Nullable ProgramInformation programInformation, + @Nullable UtcTimingElement utcTiming, + @Nullable Uri location, List periods) { return new DashManifest( availabilityStartTime, @@ -259,8 +261,9 @@ public class DashManifestParser extends DefaultHandler // AdaptationSet parsing. - protected AdaptationSet parseAdaptationSet(XmlPullParser xpp, String baseUrl, - SegmentBase segmentBase) throws XmlPullParserException, IOException { + protected AdaptationSet parseAdaptationSet( + XmlPullParser xpp, String baseUrl, @Nullable SegmentBase segmentBase) + throws XmlPullParserException, IOException { int id = parseInt(xpp, "id", AdaptationSet.ID_UNSET); int contentType = parseContentType(xpp); @@ -394,8 +397,8 @@ public class DashManifestParser extends DefaultHandler * @return The scheme type and/or {@link SchemeData} parsed from the ContentProtection element. * Either or both may be null, depending on the ContentProtection element being parsed. */ - protected Pair parseContentProtection(XmlPullParser xpp) - throws XmlPullParserException, IOException { + protected Pair<@NullableType String, @NullableType SchemeData> parseContentProtection( + XmlPullParser xpp) throws XmlPullParserException, IOException { String schemeType = null; String licenseServerUrl = null; byte[] data = null; @@ -477,19 +480,19 @@ public class DashManifestParser extends DefaultHandler protected RepresentationInfo parseRepresentation( XmlPullParser xpp, String baseUrl, - String label, - String adaptationSetMimeType, - String adaptationSetCodecs, + @Nullable String label, + @Nullable String adaptationSetMimeType, + @Nullable String adaptationSetCodecs, int adaptationSetWidth, int adaptationSetHeight, float adaptationSetFrameRate, int adaptationSetAudioChannels, int adaptationSetAudioSamplingRate, - String adaptationSetLanguage, + @Nullable String adaptationSetLanguage, List adaptationSetRoleDescriptors, List adaptationSetAccessibilityDescriptors, List adaptationSetSupplementalProperties, - SegmentBase segmentBase) + @Nullable SegmentBase segmentBase) throws XmlPullParserException, IOException { String id = xpp.getAttributeValue(null, "id"); int bandwidth = parseInt(xpp, "bandwidth", Format.NO_VALUE); @@ -564,19 +567,19 @@ public class DashManifestParser extends DefaultHandler } protected Format buildFormat( - String id, - String label, - String containerMimeType, + @Nullable String id, + @Nullable String label, + @Nullable String containerMimeType, int width, int height, float frameRate, int audioChannels, int audioSamplingRate, int bitrate, - String language, + @Nullable String language, List roleDescriptors, List accessibilityDescriptors, - String codecs, + @Nullable String codecs, List supplementalProperties) { String sampleMimeType = getSampleMimeType(containerMimeType, codecs); @C.SelectionFlags int selectionFlags = parseSelectionFlagsFromRoleDescriptors(roleDescriptors); @@ -650,7 +653,7 @@ public class DashManifestParser extends DefaultHandler protected Representation buildRepresentation( RepresentationInfo representationInfo, - String extraDrmSchemeType, + @Nullable String extraDrmSchemeType, ArrayList extraDrmSchemeDatas, ArrayList extraInbandEventStreams) { Format format = representationInfo.format; @@ -675,7 +678,8 @@ public class DashManifestParser extends DefaultHandler // SegmentBase, SegmentList and SegmentTemplate parsing. - protected SingleSegmentBase parseSegmentBase(XmlPullParser xpp, SingleSegmentBase parent) + protected SingleSegmentBase parseSegmentBase( + XmlPullParser xpp, @Nullable SingleSegmentBase parent) throws XmlPullParserException, IOException { long timescale = parseLong(xpp, "timescale", parent != null ? parent.timescale : 1); @@ -711,7 +715,7 @@ public class DashManifestParser extends DefaultHandler indexLength); } - protected SegmentList parseSegmentList(XmlPullParser xpp, SegmentList parent) + protected SegmentList parseSegmentList(XmlPullParser xpp, @Nullable SegmentList parent) throws XmlPullParserException, IOException { long timescale = parseLong(xpp, "timescale", parent != null ? parent.timescale : 1); @@ -756,15 +760,15 @@ public class DashManifestParser extends DefaultHandler long presentationTimeOffset, long startNumber, long duration, - List timeline, - List segments) { + @Nullable List timeline, + @Nullable List segments) { return new SegmentList(initialization, timescale, presentationTimeOffset, startNumber, duration, timeline, segments); } protected SegmentTemplate parseSegmentTemplate( XmlPullParser xpp, - SegmentTemplate parent, + @Nullable SegmentTemplate parent, List adaptationSetSupplementalProperties) throws XmlPullParserException, IOException { long timescale = parseLong(xpp, "timescale", parent != null ? parent.timescale : 1); @@ -819,8 +823,8 @@ public class DashManifestParser extends DefaultHandler long endNumber, long duration, List timeline, - UrlTemplate initializationTemplate, - UrlTemplate mediaTemplate) { + @Nullable UrlTemplate initializationTemplate, + @Nullable UrlTemplate mediaTemplate) { return new SegmentTemplate( initialization, timescale, @@ -1008,8 +1012,9 @@ public class DashManifestParser extends DefaultHandler return new SegmentTimelineElement(elapsedTime, duration); } - protected UrlTemplate parseUrlTemplate(XmlPullParser xpp, String name, - UrlTemplate defaultValue) { + @Nullable + protected UrlTemplate parseUrlTemplate( + XmlPullParser xpp, String name, @Nullable UrlTemplate defaultValue) { String valueString = xpp.getAttributeValue(null, name); if (valueString != null) { return UrlTemplate.compile(valueString); @@ -1126,7 +1131,7 @@ public class DashManifestParser extends DefaultHandler } @C.RoleFlags - protected int parseDashRoleSchemeValue(String value) { + protected int parseDashRoleSchemeValue(@Nullable String value) { if (value == null) { return 0; } @@ -1159,7 +1164,7 @@ public class DashManifestParser extends DefaultHandler } @C.RoleFlags - protected int parseTvaAudioPurposeCsValue(String value) { + protected int parseTvaAudioPurposeCsValue(@Nullable String value) { if (value == null) { return 0; } @@ -1230,7 +1235,9 @@ public class DashManifestParser extends DefaultHandler * @param codecs The codecs attribute. * @return The derived sample mimeType, or null if it could not be derived. */ - private static String getSampleMimeType(String containerMimeType, String codecs) { + @Nullable + private static String getSampleMimeType( + @Nullable String containerMimeType, @Nullable String codecs) { if (MimeTypes.isAudio(containerMimeType)) { return MimeTypes.getAudioMediaMimeType(codecs); } else if (MimeTypes.isVideo(containerMimeType)) { @@ -1264,7 +1271,7 @@ public class DashManifestParser extends DefaultHandler * @param mimeType The mimeType. * @return Whether the mimeType is a text sample mimeType. */ - private static boolean mimeTypeIsRawText(String mimeType) { + private static boolean mimeTypeIsRawText(@Nullable String mimeType) { return MimeTypes.isText(mimeType) || MimeTypes.APPLICATION_TTML.equals(mimeType) || MimeTypes.APPLICATION_MP4VTT.equals(mimeType) @@ -1273,16 +1280,18 @@ public class DashManifestParser extends DefaultHandler } /** - * Checks two languages for consistency, returning the consistent language, or throwing an - * {@link IllegalStateException} if the languages are inconsistent. - *

- * Two languages are consistent if they are equal, or if one is null. + * Checks two languages for consistency, returning the consistent language, or throwing an {@link + * IllegalStateException} if the languages are inconsistent. + * + *

Two languages are consistent if they are equal, or if one is null. * * @param firstLanguage The first language. * @param secondLanguage The second language. * @return The consistent language. */ - private static String checkLanguageConsistency(String firstLanguage, String secondLanguage) { + @Nullable + private static String checkLanguageConsistency( + @Nullable String firstLanguage, @Nullable String secondLanguage) { if (firstLanguage == null) { return secondLanguage; } else if (secondLanguage == null) { @@ -1485,14 +1494,19 @@ public class DashManifestParser extends DefaultHandler public final Format format; public final String baseUrl; public final SegmentBase segmentBase; - public final String drmSchemeType; + @Nullable public final String drmSchemeType; public final ArrayList drmSchemeDatas; public final ArrayList inbandEventStreams; public final long revisionId; - public RepresentationInfo(Format format, String baseUrl, SegmentBase segmentBase, - String drmSchemeType, ArrayList drmSchemeDatas, - ArrayList inbandEventStreams, long revisionId) { + public RepresentationInfo( + Format format, + String baseUrl, + SegmentBase segmentBase, + @Nullable String drmSchemeType, + ArrayList drmSchemeDatas, + ArrayList inbandEventStreams, + long revisionId) { this.format = format; this.baseUrl = baseUrl; this.segmentBase = segmentBase; diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/Descriptor.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/Descriptor.java index 493a8da09c..d68690d363 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/Descriptor.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/Descriptor.java @@ -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; } - } diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/ProgramInformation.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/ProgramInformation.java index 62934d7433..ac264bd2b1 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/ProgramInformation.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/ProgramInformation.java @@ -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; diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/RangedUri.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/RangedUri.java index 9ac1257ee2..bcd783f0cb 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/RangedUri.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/RangedUri.java @@ -83,7 +83,7 @@ public final class RangedUri { *

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 diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/Representation.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/Representation.java index 0884bcc65c..80ad15cd8f 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/Representation.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/Representation.java @@ -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 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 inbandEventStreams) { - return newInstance(revisionId, format, baseUrl, segmentBase, inbandEventStreams, null); + @Nullable List 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 inbandEventStreams, - String cacheKey) { + @Nullable List 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 inbandEventStreams) { + @Nullable List 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 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 inbandEventStreams, - String cacheKey, + @Nullable List 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 inbandEventStreams) { + @Nullable List 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; } diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/SegmentBase.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/SegmentBase.java index ba4faafd95..a31e0329af 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/SegmentBase.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/SegmentBase.java @@ -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 segmentTimeline; + /* package */ @Nullable final List 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 segmentTimeline) { + @Nullable List 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 mediaSegments; + /* package */ @Nullable final List 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 segmentTimeline, - List mediaSegments) { + @Nullable List segmentTimeline, + @Nullable List 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 segmentTimeline, - UrlTemplate initializationTemplate, - UrlTemplate mediaTemplate) { + @Nullable List 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, diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/package-info.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/package-info.java new file mode 100644 index 0000000000..b7c267727c --- /dev/null +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/package-info.java @@ -0,0 +1,19 @@ +/* + * 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; diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/offline/package-info.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/offline/package-info.java new file mode 100644 index 0000000000..4eb0d8436d --- /dev/null +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/offline/package-info.java @@ -0,0 +1,19 @@ +/* + * 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; diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/package-info.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/package-info.java new file mode 100644 index 0000000000..f51ea4369e --- /dev/null +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/package-info.java @@ -0,0 +1,19 @@ +/* + * 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;