diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/Cache.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/Cache.java index b5b5dc64e6..8641746c74 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/Cache.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/Cache.java @@ -62,7 +62,7 @@ public interface Cache { void onSpanTouched(Cache cache, CacheSpan oldSpan, CacheSpan newSpan); } - + /** * Thrown when an error is encountered when writing data. */ @@ -223,25 +223,6 @@ public interface Cache { */ long getCachedLength(String key, long position, long length); - /** - * Sets the content length for the given key. - * - * @param key The cache key for the data. - * @param length The length of the data. - * @throws CacheException If an error is encountered. - */ - void setContentLength(String key, long length) throws CacheException; - - /** - * Returns the content length for the given key if one set, or {@link - * com.google.android.exoplayer2.C#LENGTH_UNSET} otherwise. - * - * @param key The cache key for the data. - * @return The content length for the given key if one set, or {@link - * com.google.android.exoplayer2.C#LENGTH_UNSET} otherwise. - */ - long getContentLength(String key); - /** * Applies {@code mutations} to the {@link ContentMetadata} for the given key. A new {@link * CachedContent} is added if there isn't one already with the given key. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSource.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSource.java index 757f2892ae..1b4b28d67e 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSource.java @@ -299,7 +299,7 @@ public final class CacheDataSource implements DataSource { if (dataSpec.length != C.LENGTH_UNSET || currentRequestIgnoresCache) { bytesRemaining = dataSpec.length; } else { - bytesRemaining = cache.getContentLength(key); + bytesRemaining = ContentMetadata.getContentLength(cache.getContentMetadata(key)); if (bytesRemaining != C.LENGTH_UNSET) { bytesRemaining -= dataSpec.position; if (bytesRemaining <= 0) { @@ -484,16 +484,12 @@ public final class CacheDataSource implements DataSource { ContentMetadataMutations mutations = new ContentMetadataMutations(); if (currentDataSpecLengthUnset && resolvedLength != C.LENGTH_UNSET) { bytesRemaining = resolvedLength; - ContentMetadataInternal.setContentLength(mutations, readPosition + bytesRemaining); + ContentMetadataMutations.setContentLength(mutations, readPosition + bytesRemaining); } if (isReadingFromUpstream()) { actualUri = currentDataSource.getUri(); boolean isRedirected = !uri.equals(actualUri); - if (isRedirected) { - ContentMetadataInternal.setRedirectedUri(mutations, actualUri); - } else { - ContentMetadataInternal.removeRedirectedUri(mutations); - } + ContentMetadataMutations.setRedirectedUri(mutations, isRedirected ? actualUri : null); } if (isWritingToCache()) { cache.applyContentMetadataMutations(key, mutations); @@ -503,14 +499,15 @@ public final class CacheDataSource implements DataSource { private void setNoBytesRemainingAndMaybeStoreLength() throws IOException { bytesRemaining = 0; if (isWritingToCache()) { - cache.setContentLength(key, readPosition); + ContentMetadataMutations mutations = new ContentMetadataMutations(); + ContentMetadataMutations.setContentLength(mutations, readPosition); + cache.applyContentMetadataMutations(key, mutations); } } private static Uri getRedirectedUriOrDefault(Cache cache, String key, Uri defaultUri) { - ContentMetadata contentMetadata = cache.getContentMetadata(key); - Uri redirectedUri = ContentMetadataInternal.getRedirectedUri(contentMetadata); - return redirectedUri == null ? defaultUri : redirectedUri; + Uri redirectedUri = ContentMetadata.getRedirectedUri(cache.getContentMetadata(key)); + return redirectedUri != null ? redirectedUri : defaultUri; } private static boolean isCausedByPositionOutOfRange(IOException e) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheUtil.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheUtil.java index fd4937ef86..9714df6ad0 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheUtil.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheUtil.java @@ -84,7 +84,10 @@ public final class CacheUtil { CachingCounters counters) { String key = buildCacheKey(dataSpec, cacheKeyFactory); long start = dataSpec.absoluteStreamPosition; - long left = dataSpec.length != C.LENGTH_UNSET ? dataSpec.length : cache.getContentLength(key); + long left = + dataSpec.length != C.LENGTH_UNSET + ? dataSpec.length + : ContentMetadata.getContentLength(cache.getContentMetadata(key)); counters.contentLength = left; counters.alreadyCachedBytes = 0; counters.newlyCachedBytes = 0; @@ -188,7 +191,10 @@ public final class CacheUtil { String key = buildCacheKey(dataSpec, cacheKeyFactory); long start = dataSpec.absoluteStreamPosition; - long left = dataSpec.length != C.LENGTH_UNSET ? dataSpec.length : cache.getContentLength(key); + long left = + dataSpec.length != C.LENGTH_UNSET + ? dataSpec.length + : ContentMetadata.getContentLength(cache.getContentMetadata(key)); while (left != 0) { throwExceptionIfInterruptedOrCancelled(isCanceled); long blockLength = diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CachedContent.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CachedContent.java index 4d15de5932..5494454d54 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CachedContent.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CachedContent.java @@ -55,7 +55,7 @@ import java.util.TreeSet; if (version < VERSION_METADATA_INTRODUCED) { long length = input.readLong(); ContentMetadataMutations mutations = new ContentMetadataMutations(); - ContentMetadataInternal.setContentLength(mutations, length); + ContentMetadataMutations.setContentLength(mutations, length); cachedContent.applyMetadataMutations(mutations); } else { cachedContent.metadata = DefaultContentMetadata.readFromStream(input); @@ -216,7 +216,7 @@ import java.util.TreeSet; int result = id; result = 31 * result + key.hashCode(); if (version < VERSION_METADATA_INTRODUCED) { - long length = ContentMetadataInternal.getContentLength(metadata); + long length = ContentMetadata.getContentLength(metadata); result = 31 * result + (int) (length ^ (length >>> 32)); } else { result = 31 * result + metadata.hashCode(); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/ContentMetadata.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/ContentMetadata.java index aacd11f915..f0075343ad 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/ContentMetadata.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/ContentMetadata.java @@ -15,44 +15,73 @@ */ package com.google.android.exoplayer2.upstream.cache; +import android.net.Uri; +import android.support.annotation.Nullable; +import com.google.android.exoplayer2.C; + /** * Interface for an immutable snapshot of keyed metadata. - * - *
Internal metadata names are prefixed with {@value #INTERNAL_METADATA_NAME_PREFIX}. Custom
- * metadata names should avoid this prefix to prevent clashes.
*/
public interface ContentMetadata {
- /** Prefix of internal metadata names. */
- String INTERNAL_METADATA_NAME_PREFIX = "exo_";
+ /**
+ * Prefix for custom metadata keys. Applications can use keys starting with this prefix without
+ * any risk of their keys colliding with ones defined by the ExoPlayer library.
+ */
+ @SuppressWarnings("unused")
+ String KEY_CUSTOM_PREFIX = "custom_";
+ /** Key for redirected uri (type: String). */
+ String KEY_REDIRECTED_URI = "exo_redir";
+ /** Key for content length in bytes (type: long). */
+ String KEY_CONTENT_LENGTH = "exo_len";
/**
* Returns a metadata value.
*
- * @param name Name of the metadata to be returned.
+ * @param key Key of the metadata to be returned.
* @param defaultValue Value to return if the metadata doesn't exist.
* @return The metadata value.
*/
- byte[] get(String name, byte[] defaultValue);
+ @Nullable
+ byte[] get(String key, @Nullable byte[] defaultValue);
/**
* Returns a metadata value.
*
- * @param name Name of the metadata to be returned.
+ * @param key Key of the metadata to be returned.
* @param defaultValue Value to return if the metadata doesn't exist.
* @return The metadata value.
*/
- String get(String name, String defaultValue);
+ @Nullable
+ String get(String key, @Nullable String defaultValue);
/**
* Returns a metadata value.
*
- * @param name Name of the metadata to be returned.
+ * @param key Key of the metadata to be returned.
* @param defaultValue Value to return if the metadata doesn't exist.
* @return The metadata value.
*/
- long get(String name, long defaultValue);
+ long get(String key, long defaultValue);
/** Returns whether the metadata is available. */
- boolean contains(String name);
+ boolean contains(String key);
+
+ /**
+ * Returns the value stored under {@link #KEY_CONTENT_LENGTH}, or {@link C#LENGTH_UNSET} if not
+ * set.
+ */
+ static long getContentLength(ContentMetadata contentMetadata) {
+ return contentMetadata.get(KEY_CONTENT_LENGTH, C.LENGTH_UNSET);
+ }
+
+ /**
+ * Returns the value stored under {@link #KEY_REDIRECTED_URI} as a {@link Uri}, or {code null} if
+ * not set.
+ */
+ @Nullable
+ static Uri getRedirectedUri(ContentMetadata contentMetadata) {
+ String redirectedUri = contentMetadata.get(KEY_REDIRECTED_URI, (String) null);
+ return redirectedUri == null ? null : Uri.parse(redirectedUri);
+ }
}
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/ContentMetadataInternal.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/ContentMetadataInternal.java
deleted file mode 100644
index 0065018260..0000000000
--- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/ContentMetadataInternal.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-package com.google.android.exoplayer2.upstream.cache;
-
-import android.net.Uri;
-import android.support.annotation.Nullable;
-import com.google.android.exoplayer2.C;
-
-/** Helper classes to easily access and modify internal metadata values. */
-/* package */ final class ContentMetadataInternal {
-
- private static final String PREFIX = ContentMetadata.INTERNAL_METADATA_NAME_PREFIX;
- private static final String METADATA_NAME_REDIRECTED_URI = PREFIX + "redir";
- private static final String METADATA_NAME_CONTENT_LENGTH = PREFIX + "len";
-
- /** Returns the content length metadata, or {@link C#LENGTH_UNSET} if not set. */
- public static long getContentLength(ContentMetadata contentMetadata) {
- return contentMetadata.get(METADATA_NAME_CONTENT_LENGTH, C.LENGTH_UNSET);
- }
-
- /** Adds a mutation to set content length metadata value. */
- public static void setContentLength(ContentMetadataMutations mutations, long length) {
- mutations.set(METADATA_NAME_CONTENT_LENGTH, length);
- }
-
- /** Adds a mutation to remove content length metadata value. */
- public static void removeContentLength(ContentMetadataMutations mutations) {
- mutations.remove(METADATA_NAME_CONTENT_LENGTH);
- }
-
- /** Returns the redirected uri metadata, or {@code null} if not set. */
- public @Nullable static Uri getRedirectedUri(ContentMetadata contentMetadata) {
- String redirectedUri = contentMetadata.get(METADATA_NAME_REDIRECTED_URI, (String) null);
- return redirectedUri == null ? null : Uri.parse(redirectedUri);
- }
-
- /**
- * Adds a mutation to set redirected uri metadata value. Passing {@code null} as {@code uri} isn't
- * allowed.
- */
- public static void setRedirectedUri(ContentMetadataMutations mutations, Uri uri) {
- mutations.set(METADATA_NAME_REDIRECTED_URI, uri.toString());
- }
-
- /** Adds a mutation to remove redirected uri metadata value. */
- public static void removeRedirectedUri(ContentMetadataMutations mutations) {
- mutations.remove(METADATA_NAME_REDIRECTED_URI);
- }
-
- private ContentMetadataInternal() {
- // Prevent instantiation.
- }
-}
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/ContentMetadataMutations.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/ContentMetadataMutations.java
index 70154b0308..fb3f6e362d 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/ContentMetadataMutations.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/ContentMetadataMutations.java
@@ -15,6 +15,9 @@
*/
package com.google.android.exoplayer2.upstream.cache;
+import android.net.Uri;
+import android.support.annotation.Nullable;
+import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.Assertions;
import java.util.ArrayList;
import java.util.Arrays;
@@ -30,6 +33,36 @@ import java.util.Map.Entry;
*/
public class ContentMetadataMutations {
+ /**
+ * Adds a mutation to set the {@link ContentMetadata#KEY_CONTENT_LENGTH} value, or to remove any
+ * existing value if {@link C#LENGTH_UNSET} is passed.
+ *
+ * @param mutations The mutations to modify.
+ * @param length The length value, or {@link C#LENGTH_UNSET} to remove any existing entry.
+ * @return The mutations instance, for convenience.
+ */
+ public static ContentMetadataMutations setContentLength(
+ ContentMetadataMutations mutations, long length) {
+ return mutations.set(ContentMetadata.KEY_CONTENT_LENGTH, length);
+ }
+
+ /**
+ * Adds a mutation to set the {@link ContentMetadata#KEY_REDIRECTED_URI} value, or to remove any
+ * existing entry if {@code null} is passed.
+ *
+ * @param mutations The mutations to modify.
+ * @param uri The {@link Uri} value, or {@code null} to remove any existing entry.
+ * @return The mutations instance, for convenience.
+ */
+ public static ContentMetadataMutations setRedirectedUri(
+ ContentMetadataMutations mutations, @Nullable Uri uri) {
+ if (uri == null) {
+ return mutations.remove(ContentMetadata.KEY_REDIRECTED_URI);
+ } else {
+ return mutations.set(ContentMetadata.KEY_REDIRECTED_URI, uri.toString());
+ }
+ }
+
private final Map