From 4a0f224e1219d732eae3a4a4394d577974a119df Mon Sep 17 00:00:00 2001 From: eguven Date: Wed, 4 Jan 2017 09:12:02 -0800 Subject: [PATCH] Add a new flag to DataSpec which permits content to be cached even if its length can not be resolved ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=143560360 --- .../ext/okhttp/OkHttpDataSource.java | 2 +- .../android/exoplayer2/upstream/DataSpec.java | 19 ++++++++++++++++--- .../upstream/DefaultHttpDataSource.java | 4 ++-- .../upstream/cache/CacheDataSink.java | 14 +++++++++----- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/OkHttpDataSource.java b/extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/OkHttpDataSource.java index 8577d33781..90a4728933 100644 --- a/extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/OkHttpDataSource.java +++ b/extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/OkHttpDataSource.java @@ -261,7 +261,7 @@ public class OkHttpDataSource implements HttpDataSource { private Request makeRequest(DataSpec dataSpec) { long position = dataSpec.position; long length = dataSpec.length; - boolean allowGzip = (dataSpec.flags & DataSpec.FLAG_ALLOW_GZIP) != 0; + boolean allowGzip = dataSpec.isFlagSet(DataSpec.FLAG_ALLOW_GZIP); HttpUrl url = HttpUrl.parse(dataSpec.uri.toString()); Request.Builder builder = new Request.Builder().url(url); diff --git a/library/src/main/java/com/google/android/exoplayer2/upstream/DataSpec.java b/library/src/main/java/com/google/android/exoplayer2/upstream/DataSpec.java index d251446976..133e71f6e2 100644 --- a/library/src/main/java/com/google/android/exoplayer2/upstream/DataSpec.java +++ b/library/src/main/java/com/google/android/exoplayer2/upstream/DataSpec.java @@ -32,7 +32,7 @@ public final class DataSpec { * The flags that apply to any request for data. */ @Retention(RetentionPolicy.SOURCE) - @IntDef(flag = true, value = {FLAG_ALLOW_GZIP}) + @IntDef(flag = true, value = {FLAG_ALLOW_GZIP, FLAG_ALLOW_CACHING_UNKNOWN_LENGTH}) public @interface Flags {} /** * Permits an underlying network stack to request that the server use gzip compression. @@ -45,7 +45,10 @@ public final class DataSpec { * {@link DataSource#open(DataSpec)} will typically be {@link C#LENGTH_UNSET}. The data read from * {@link DataSource#read(byte[], int, int)} will be the decompressed data. */ - public static final int FLAG_ALLOW_GZIP = 1; + public static final int FLAG_ALLOW_GZIP = 1 << 0; + + /** Permits content to be cached even if its length can not be resolved. */ + public static final int FLAG_ALLOW_CACHING_UNKNOWN_LENGTH = 1 << 1; /** * The source from which data should be read. @@ -76,7 +79,8 @@ public final class DataSpec { */ public final String key; /** - * Request flags. Currently {@link #FLAG_ALLOW_GZIP} is the only supported flag. + * Request flags. Currently {@link #FLAG_ALLOW_GZIP} and + * {@link #FLAG_ALLOW_CACHING_UNKNOWN_LENGTH} are the only supported flags. */ @Flags public final int flags; @@ -167,6 +171,15 @@ public final class DataSpec { this.flags = flags; } + /** + * Returns whether the given flag is set. + * + * @param flag Flag to be checked if it is set. + */ + public boolean isFlagSet(@Flags int flag) { + return (this.flags & flag) == flag; + } + @Override public String toString() { return "DataSpec[" + uri + ", " + Arrays.toString(postBody) + ", " + absoluteStreamPosition diff --git a/library/src/main/java/com/google/android/exoplayer2/upstream/DefaultHttpDataSource.java b/library/src/main/java/com/google/android/exoplayer2/upstream/DefaultHttpDataSource.java index b326c41b18..ca0fda9399 100644 --- a/library/src/main/java/com/google/android/exoplayer2/upstream/DefaultHttpDataSource.java +++ b/library/src/main/java/com/google/android/exoplayer2/upstream/DefaultHttpDataSource.java @@ -230,7 +230,7 @@ public class DefaultHttpDataSource implements HttpDataSource { bytesToSkip = responseCode == 200 && dataSpec.position != 0 ? dataSpec.position : 0; // Determine the length of the data to be read, after skipping. - if ((dataSpec.flags & DataSpec.FLAG_ALLOW_GZIP) == 0) { + if (!dataSpec.isFlagSet(DataSpec.FLAG_ALLOW_GZIP)) { if (dataSpec.length != C.LENGTH_UNSET) { bytesToRead = dataSpec.length; } else { @@ -343,7 +343,7 @@ public class DefaultHttpDataSource implements HttpDataSource { byte[] postBody = dataSpec.postBody; long position = dataSpec.position; long length = dataSpec.length; - boolean allowGzip = (dataSpec.flags & DataSpec.FLAG_ALLOW_GZIP) != 0; + boolean allowGzip = dataSpec.isFlagSet(DataSpec.FLAG_ALLOW_GZIP); if (!allowCrossProtocolRedirects) { // HttpURLConnection disallows cross-protocol redirects, but otherwise performs redirection diff --git a/library/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSink.java b/library/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSink.java index d57f3ee140..71397bd403 100644 --- a/library/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSink.java +++ b/library/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSink.java @@ -81,10 +81,12 @@ public final class CacheDataSink implements DataSink { @Override public void open(DataSpec dataSpec) throws CacheDataSinkException { - this.dataSpec = dataSpec; - if (dataSpec.length == C.LENGTH_UNSET) { + if (dataSpec.length == C.LENGTH_UNSET + && !dataSpec.isFlagSet(DataSpec.FLAG_ALLOW_CACHING_UNKNOWN_LENGTH)) { + this.dataSpec = null; return; } + this.dataSpec = dataSpec; dataSpecBytesWritten = 0; try { openNextOutputStream(); @@ -95,7 +97,7 @@ public final class CacheDataSink implements DataSink { @Override public void write(byte[] buffer, int offset, int length) throws CacheDataSinkException { - if (dataSpec.length == C.LENGTH_UNSET) { + if (dataSpec == null) { return; } try { @@ -119,7 +121,7 @@ public final class CacheDataSink implements DataSink { @Override public void close() throws CacheDataSinkException { - if (dataSpec == null || dataSpec.length == C.LENGTH_UNSET) { + if (dataSpec == null) { return; } try { @@ -130,8 +132,10 @@ public final class CacheDataSink implements DataSink { } private void openNextOutputStream() throws IOException { + long maxLength = dataSpec.length == C.LENGTH_UNSET ? maxCacheFileSize + : Math.min(dataSpec.length - dataSpecBytesWritten, maxCacheFileSize); file = cache.startFile(dataSpec.key, dataSpec.absoluteStreamPosition + dataSpecBytesWritten, - Math.min(dataSpec.length - dataSpecBytesWritten, maxCacheFileSize)); + maxLength); underlyingFileOutputStream = new FileOutputStream(file); if (bufferSize > 0) { if (bufferedOutputStream == null) {