mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Add NonNull annotations to upstream.cache and upstream.crypto
PiperOrigin-RevId: 284548019
This commit is contained in:
parent
0b7f93a5d4
commit
c90c10c981
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.upstream.cache;
|
package com.google.android.exoplayer2.upstream.cache;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.upstream.DataSink;
|
import com.google.android.exoplayer2.upstream.DataSink;
|
||||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||||
@ -27,6 +28,7 @@ import java.io.File;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes data into a cache.
|
* Writes data into a cache.
|
||||||
@ -49,13 +51,13 @@ public final class CacheDataSink implements DataSink {
|
|||||||
private final long fragmentSize;
|
private final long fragmentSize;
|
||||||
private final int bufferSize;
|
private final int bufferSize;
|
||||||
|
|
||||||
private DataSpec dataSpec;
|
@Nullable private DataSpec dataSpec;
|
||||||
private long dataSpecFragmentSize;
|
private long dataSpecFragmentSize;
|
||||||
private File file;
|
@Nullable private File file;
|
||||||
private OutputStream outputStream;
|
@Nullable private OutputStream outputStream;
|
||||||
private long outputStreamBytesWritten;
|
private long outputStreamBytesWritten;
|
||||||
private long dataSpecBytesWritten;
|
private long dataSpecBytesWritten;
|
||||||
private ReusableBufferedOutputStream bufferedOutputStream;
|
@MonotonicNonNull private ReusableBufferedOutputStream bufferedOutputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown when IOException is encountered when writing data into sink.
|
* Thrown when IOException is encountered when writing data into sink.
|
||||||
|
@ -377,7 +377,7 @@ public final class CacheDataSource implements DataSource {
|
|||||||
* reading from {@link #upstreamDataSource}, which is the currently open source.
|
* reading from {@link #upstreamDataSource}, which is the currently open source.
|
||||||
*/
|
*/
|
||||||
private void openNextSource(boolean checkCache) throws IOException {
|
private void openNextSource(boolean checkCache) throws IOException {
|
||||||
CacheSpan nextSpan;
|
@Nullable CacheSpan nextSpan;
|
||||||
if (currentRequestIgnoresCache) {
|
if (currentRequestIgnoresCache) {
|
||||||
nextSpan = null;
|
nextSpan = null;
|
||||||
} else if (blockOnCache) {
|
} else if (blockOnCache) {
|
||||||
@ -487,7 +487,7 @@ public final class CacheDataSource implements DataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Uri getRedirectedUriOrDefault(Cache cache, String key, Uri defaultUri) {
|
private static Uri getRedirectedUriOrDefault(Cache cache, String key, Uri defaultUri) {
|
||||||
Uri redirectedUri = ContentMetadata.getRedirectedUri(cache.getContentMetadata(key));
|
@Nullable Uri redirectedUri = ContentMetadata.getRedirectedUri(cache.getContentMetadata(key));
|
||||||
return redirectedUri != null ? redirectedUri : defaultUri;
|
return redirectedUri != null ? redirectedUri : defaultUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
|
|
||||||
private final DatabaseProvider databaseProvider;
|
private final DatabaseProvider databaseProvider;
|
||||||
|
|
||||||
private @MonotonicNonNull String tableName;
|
@MonotonicNonNull private String tableName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes index data for the specified cache.
|
* Deletes index data for the specified cache.
|
||||||
|
@ -24,6 +24,7 @@ public interface CacheKeyFactory {
|
|||||||
* Returns a cache key for the given {@link DataSpec}.
|
* Returns a cache key for the given {@link DataSpec}.
|
||||||
*
|
*
|
||||||
* @param dataSpec The data being cached.
|
* @param dataSpec The data being cached.
|
||||||
|
* @return The cache key.
|
||||||
*/
|
*/
|
||||||
String buildCacheKey(DataSpec dataSpec);
|
String buildCacheKey(DataSpec dataSpec);
|
||||||
}
|
}
|
||||||
|
@ -183,7 +183,7 @@ public final class CacheUtil {
|
|||||||
|
|
||||||
String key = buildCacheKey(dataSpec, cacheKeyFactory);
|
String key = buildCacheKey(dataSpec, cacheKeyFactory);
|
||||||
long bytesLeft;
|
long bytesLeft;
|
||||||
ProgressNotifier progressNotifier = null;
|
@Nullable ProgressNotifier progressNotifier = null;
|
||||||
if (progressListener != null) {
|
if (progressListener != null) {
|
||||||
progressNotifier = new ProgressNotifier(progressListener);
|
progressNotifier = new ProgressNotifier(progressListener);
|
||||||
Pair<Long, Long> lengthAndBytesAlreadyCached = getCached(dataSpec, cache, cacheKeyFactory);
|
Pair<Long, Long> lengthAndBytesAlreadyCached = getCached(dataSpec, cache, cacheKeyFactory);
|
||||||
@ -373,7 +373,7 @@ public final class CacheUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* package */ static boolean isCausedByPositionOutOfRange(IOException e) {
|
/* package */ static boolean isCausedByPositionOutOfRange(IOException e) {
|
||||||
Throwable cause = e;
|
@Nullable Throwable cause = e;
|
||||||
while (cause != null) {
|
while (cause != null) {
|
||||||
if (cause instanceof DataSourceException) {
|
if (cause instanceof DataSourceException) {
|
||||||
int reason = ((DataSourceException) cause).reason;
|
int reason = ((DataSourceException) cause).reason;
|
||||||
|
@ -229,11 +229,12 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
* @return A new or existing CachedContent instance with the given key.
|
* @return A new or existing CachedContent instance with the given key.
|
||||||
*/
|
*/
|
||||||
public CachedContent getOrAdd(String key) {
|
public CachedContent getOrAdd(String key) {
|
||||||
CachedContent cachedContent = keyToContent.get(key);
|
@Nullable CachedContent cachedContent = keyToContent.get(key);
|
||||||
return cachedContent == null ? addNew(key) : cachedContent;
|
return cachedContent == null ? addNew(key) : cachedContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a CachedContent instance with the given key or null if there isn't one. */
|
/** Returns a CachedContent instance with the given key or null if there isn't one. */
|
||||||
|
@Nullable
|
||||||
public CachedContent get(String key) {
|
public CachedContent get(String key) {
|
||||||
return keyToContent.get(key);
|
return keyToContent.get(key);
|
||||||
}
|
}
|
||||||
@ -254,14 +255,15 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
return getOrAdd(key).id;
|
return getOrAdd(key).id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the key which has the given id assigned. */
|
/** Returns the key which has the given id assigned, or {@code null} if no such key exists. */
|
||||||
|
@Nullable
|
||||||
public String getKeyForId(int id) {
|
public String getKeyForId(int id) {
|
||||||
return idToKey.get(id);
|
return idToKey.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Removes {@link CachedContent} with the given key from index if it's empty and not locked. */
|
/** Removes {@link CachedContent} with the given key from index if it's empty and not locked. */
|
||||||
public void maybeRemove(String key) {
|
public void maybeRemove(String key) {
|
||||||
CachedContent cachedContent = keyToContent.get(key);
|
@Nullable CachedContent cachedContent = keyToContent.get(key);
|
||||||
if (cachedContent != null && cachedContent.isEmpty() && !cachedContent.isLocked()) {
|
if (cachedContent != null && cachedContent.isEmpty() && !cachedContent.isLocked()) {
|
||||||
keyToContent.remove(key);
|
keyToContent.remove(key);
|
||||||
int id = cachedContent.id;
|
int id = cachedContent.id;
|
||||||
@ -626,7 +628,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void writeFile(HashMap<String, CachedContent> content) throws IOException {
|
private void writeFile(HashMap<String, CachedContent> content) throws IOException {
|
||||||
DataOutputStream output = null;
|
@Nullable DataOutputStream output = null;
|
||||||
try {
|
try {
|
||||||
OutputStream outputStream = atomicFile.startWrite();
|
OutputStream outputStream = atomicFile.startWrite();
|
||||||
if (bufferedOutputStream == null) {
|
if (bufferedOutputStream == null) {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
package com.google.android.exoplayer2.upstream.cache;
|
package com.google.android.exoplayer2.upstream.cache;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.extractor.ChunkIndex;
|
import com.google.android.exoplayer2.extractor.ChunkIndex;
|
||||||
import com.google.android.exoplayer2.util.Log;
|
import com.google.android.exoplayer2.util.Log;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
@ -77,7 +78,7 @@ public final class CachedRegionTracker implements Cache.Listener {
|
|||||||
*/
|
*/
|
||||||
public synchronized int getRegionEndTimeMs(long byteOffset) {
|
public synchronized int getRegionEndTimeMs(long byteOffset) {
|
||||||
lookupRegion.startOffset = byteOffset;
|
lookupRegion.startOffset = byteOffset;
|
||||||
Region floorRegion = regions.floor(lookupRegion);
|
@Nullable Region floorRegion = regions.floor(lookupRegion);
|
||||||
if (floorRegion == null || byteOffset > floorRegion.endOffset
|
if (floorRegion == null || byteOffset > floorRegion.endOffset
|
||||||
|| floorRegion.endOffsetIndex == -1) {
|
|| floorRegion.endOffsetIndex == -1) {
|
||||||
return NOT_CACHED;
|
return NOT_CACHED;
|
||||||
@ -102,7 +103,7 @@ public final class CachedRegionTracker implements Cache.Listener {
|
|||||||
Region removedRegion = new Region(span.position, span.position + span.length);
|
Region removedRegion = new Region(span.position, span.position + span.length);
|
||||||
|
|
||||||
// Look up a region this span falls into.
|
// Look up a region this span falls into.
|
||||||
Region floorRegion = regions.floor(removedRegion);
|
@Nullable Region floorRegion = regions.floor(removedRegion);
|
||||||
if (floorRegion == null) {
|
if (floorRegion == null) {
|
||||||
Log.e(TAG, "Removed a span we were not aware of");
|
Log.e(TAG, "Removed a span we were not aware of");
|
||||||
return;
|
return;
|
||||||
@ -134,8 +135,8 @@ public final class CachedRegionTracker implements Cache.Listener {
|
|||||||
|
|
||||||
private void mergeSpan(CacheSpan span) {
|
private void mergeSpan(CacheSpan span) {
|
||||||
Region newRegion = new Region(span.position, span.position + span.length);
|
Region newRegion = new Region(span.position, span.position + span.length);
|
||||||
Region floorRegion = regions.floor(newRegion);
|
@Nullable Region floorRegion = regions.floor(newRegion);
|
||||||
Region ceilingRegion = regions.ceiling(newRegion);
|
@Nullable Region ceilingRegion = regions.ceiling(newRegion);
|
||||||
boolean floorConnects = regionsConnect(floorRegion, newRegion);
|
boolean floorConnects = regionsConnect(floorRegion, newRegion);
|
||||||
boolean ceilingConnects = regionsConnect(newRegion, ceilingRegion);
|
boolean ceilingConnects = regionsConnect(newRegion, ceilingRegion);
|
||||||
|
|
||||||
@ -168,7 +169,7 @@ public final class CachedRegionTracker implements Cache.Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean regionsConnect(Region lower, Region upper) {
|
private boolean regionsConnect(@Nullable Region lower, @Nullable Region upper) {
|
||||||
return lower != null && upper != null && lower.endOffset == upper.startOffset;
|
return lower != null && upper != null && lower.endOffset == upper.startOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ public interface ContentMetadata {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
static Uri getRedirectedUri(ContentMetadata contentMetadata) {
|
static Uri getRedirectedUri(ContentMetadata contentMetadata) {
|
||||||
String redirectedUri = contentMetadata.get(KEY_REDIRECTED_URI, (String) null);
|
@Nullable String redirectedUri = contentMetadata.get(KEY_REDIRECTED_URI, (String) null);
|
||||||
return redirectedUri == null ? null : Uri.parse(redirectedUri);
|
return redirectedUri == null ? null : Uri.parse(redirectedUri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,8 +73,7 @@ public class ContentMetadataMutations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a mutation to set a metadata value. Passing {@code null} as {@code name} or {@code value}
|
* Adds a mutation to set a metadata value.
|
||||||
* isn't allowed.
|
|
||||||
*
|
*
|
||||||
* @param name The name of the metadata value.
|
* @param name The name of the metadata value.
|
||||||
* @param value The value to be set.
|
* @param value The value to be set.
|
||||||
@ -85,7 +84,7 @@ public class ContentMetadataMutations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a mutation to set a metadata value. Passing {@code null} as {@code name} isn't allowed.
|
* Adds a mutation to set a metadata value.
|
||||||
*
|
*
|
||||||
* @param name The name of the metadata value.
|
* @param name The name of the metadata value.
|
||||||
* @param value The value to be set.
|
* @param value The value to be set.
|
||||||
@ -96,8 +95,7 @@ public class ContentMetadataMutations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a mutation to set a metadata value. Passing {@code null} as {@code name} or {@code value}
|
* Adds a mutation to set a metadata value.
|
||||||
* isn't allowed.
|
|
||||||
*
|
*
|
||||||
* @param name The name of the metadata value.
|
* @param name The name of the metadata value.
|
||||||
* @param value The value to be set.
|
* @param value The value to be set.
|
||||||
|
@ -67,8 +67,8 @@ public final class DefaultContentMetadata implements ContentMetadata {
|
|||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public final byte[] get(String name, @Nullable byte[] defaultValue) {
|
public final byte[] get(String name, @Nullable byte[] defaultValue) {
|
||||||
if (metadata.containsKey(name)) {
|
@Nullable byte[] bytes = metadata.get(name);
|
||||||
byte[] bytes = metadata.get(name);
|
if (bytes != null) {
|
||||||
return Arrays.copyOf(bytes, bytes.length);
|
return Arrays.copyOf(bytes, bytes.length);
|
||||||
} else {
|
} else {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
@ -78,8 +78,8 @@ public final class DefaultContentMetadata implements ContentMetadata {
|
|||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public final String get(String name, @Nullable String defaultValue) {
|
public final String get(String name, @Nullable String defaultValue) {
|
||||||
if (metadata.containsKey(name)) {
|
@Nullable byte[] bytes = metadata.get(name);
|
||||||
byte[] bytes = metadata.get(name);
|
if (bytes != null) {
|
||||||
return new String(bytes, Charset.forName(C.UTF8_NAME));
|
return new String(bytes, Charset.forName(C.UTF8_NAME));
|
||||||
} else {
|
} else {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
@ -88,8 +88,8 @@ public final class DefaultContentMetadata implements ContentMetadata {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final long get(String name, long defaultValue) {
|
public final long get(String name, long defaultValue) {
|
||||||
if (metadata.containsKey(name)) {
|
@Nullable byte[] bytes = metadata.get(name);
|
||||||
byte[] bytes = metadata.get(name);
|
if (bytes != null) {
|
||||||
return ByteBuffer.wrap(bytes).getLong();
|
return ByteBuffer.wrap(bytes).getLong();
|
||||||
} else {
|
} else {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
@ -130,7 +130,7 @@ public final class DefaultContentMetadata implements ContentMetadata {
|
|||||||
}
|
}
|
||||||
for (Entry<String, byte[]> entry : first.entrySet()) {
|
for (Entry<String, byte[]> entry : first.entrySet()) {
|
||||||
byte[] value = entry.getValue();
|
byte[] value = entry.getValue();
|
||||||
byte[] otherValue = second.get(entry.getKey());
|
@Nullable byte[] otherValue = second.get(entry.getKey());
|
||||||
if (!Arrays.equals(value, otherValue)) {
|
if (!Arrays.equals(value, otherValue)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -153,8 +153,8 @@ public final class DefaultContentMetadata implements ContentMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void addValues(HashMap<String, byte[]> metadata, Map<String, Object> values) {
|
private static void addValues(HashMap<String, byte[]> metadata, Map<String, Object> values) {
|
||||||
for (String name : values.keySet()) {
|
for (Entry<String, Object> entry : values.entrySet()) {
|
||||||
metadata.put(name, getBytes(values.get(name)));
|
metadata.put(entry.getKey(), getBytes(entry.getValue()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,8 +465,7 @@ public final class SimpleCache implements Cache {
|
|||||||
@Override
|
@Override
|
||||||
public synchronized void releaseHoleSpan(CacheSpan holeSpan) {
|
public synchronized void releaseHoleSpan(CacheSpan holeSpan) {
|
||||||
Assertions.checkState(!released);
|
Assertions.checkState(!released);
|
||||||
CachedContent cachedContent = contentIndex.get(holeSpan.key);
|
CachedContent cachedContent = Assertions.checkNotNull(contentIndex.get(holeSpan.key));
|
||||||
Assertions.checkNotNull(cachedContent);
|
|
||||||
Assertions.checkState(cachedContent.isLocked());
|
Assertions.checkState(cachedContent.isLocked());
|
||||||
cachedContent.setLocked(false);
|
cachedContent.setLocked(false);
|
||||||
contentIndex.maybeRemove(cachedContent.key);
|
contentIndex.maybeRemove(cachedContent.key);
|
||||||
@ -482,14 +481,14 @@ public final class SimpleCache implements Cache {
|
|||||||
@Override
|
@Override
|
||||||
public synchronized boolean isCached(String key, long position, long length) {
|
public synchronized boolean isCached(String key, long position, long length) {
|
||||||
Assertions.checkState(!released);
|
Assertions.checkState(!released);
|
||||||
CachedContent cachedContent = contentIndex.get(key);
|
@Nullable CachedContent cachedContent = contentIndex.get(key);
|
||||||
return cachedContent != null && cachedContent.getCachedBytesLength(position, length) >= length;
|
return cachedContent != null && cachedContent.getCachedBytesLength(position, length) >= length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized long getCachedLength(String key, long position, long length) {
|
public synchronized long getCachedLength(String key, long position, long length) {
|
||||||
Assertions.checkState(!released);
|
Assertions.checkState(!released);
|
||||||
CachedContent cachedContent = contentIndex.get(key);
|
@Nullable CachedContent cachedContent = contentIndex.get(key);
|
||||||
return cachedContent != null ? cachedContent.getCachedBytesLength(position, length) : -length;
|
return cachedContent != null ? cachedContent.getCachedBytesLength(position, length) : -length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -524,7 +523,7 @@ public final class SimpleCache implements Cache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
File[] files = cacheDir.listFiles();
|
@Nullable File[] files = cacheDir.listFiles();
|
||||||
if (files == null) {
|
if (files == null) {
|
||||||
String message = "Failed to list cache directory files: " + cacheDir;
|
String message = "Failed to list cache directory files: " + cacheDir;
|
||||||
Log.e(TAG, message);
|
Log.e(TAG, message);
|
||||||
@ -605,11 +604,13 @@ public final class SimpleCache implements Cache {
|
|||||||
}
|
}
|
||||||
long length = C.LENGTH_UNSET;
|
long length = C.LENGTH_UNSET;
|
||||||
long lastTouchTimestamp = C.TIME_UNSET;
|
long lastTouchTimestamp = C.TIME_UNSET;
|
||||||
|
@Nullable
|
||||||
CacheFileMetadata metadata = fileMetadata != null ? fileMetadata.remove(fileName) : null;
|
CacheFileMetadata metadata = fileMetadata != null ? fileMetadata.remove(fileName) : null;
|
||||||
if (metadata != null) {
|
if (metadata != null) {
|
||||||
length = metadata.length;
|
length = metadata.length;
|
||||||
lastTouchTimestamp = metadata.lastTouchTimestamp;
|
lastTouchTimestamp = metadata.lastTouchTimestamp;
|
||||||
}
|
}
|
||||||
|
@Nullable
|
||||||
SimpleCacheSpan span =
|
SimpleCacheSpan span =
|
||||||
SimpleCacheSpan.createCacheEntry(file, length, lastTouchTimestamp, contentIndex);
|
SimpleCacheSpan.createCacheEntry(file, length, lastTouchTimestamp, contentIndex);
|
||||||
if (span != null) {
|
if (span != null) {
|
||||||
@ -666,7 +667,7 @@ public final class SimpleCache implements Cache {
|
|||||||
* @return The corresponding cache {@link SimpleCacheSpan}.
|
* @return The corresponding cache {@link SimpleCacheSpan}.
|
||||||
*/
|
*/
|
||||||
private SimpleCacheSpan getSpan(String key, long position) {
|
private SimpleCacheSpan getSpan(String key, long position) {
|
||||||
CachedContent cachedContent = contentIndex.get(key);
|
@Nullable CachedContent cachedContent = contentIndex.get(key);
|
||||||
if (cachedContent == null) {
|
if (cachedContent == null) {
|
||||||
return SimpleCacheSpan.createOpenHole(key, position);
|
return SimpleCacheSpan.createOpenHole(key, position);
|
||||||
}
|
}
|
||||||
@ -694,7 +695,7 @@ public final class SimpleCache implements Cache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void removeSpanInternal(CacheSpan span) {
|
private void removeSpanInternal(CacheSpan span) {
|
||||||
CachedContent cachedContent = contentIndex.get(span.key);
|
@Nullable CachedContent cachedContent = contentIndex.get(span.key);
|
||||||
if (cachedContent == null || !cachedContent.removeSpan(span)) {
|
if (cachedContent == null || !cachedContent.removeSpan(span)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -732,7 +733,7 @@ public final class SimpleCache implements Cache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void notifySpanRemoved(CacheSpan span) {
|
private void notifySpanRemoved(CacheSpan span) {
|
||||||
ArrayList<Listener> keyListeners = listeners.get(span.key);
|
@Nullable ArrayList<Listener> keyListeners = listeners.get(span.key);
|
||||||
if (keyListeners != null) {
|
if (keyListeners != null) {
|
||||||
for (int i = keyListeners.size() - 1; i >= 0; i--) {
|
for (int i = keyListeners.size() - 1; i >= 0; i--) {
|
||||||
keyListeners.get(i).onSpanRemoved(this, span);
|
keyListeners.get(i).onSpanRemoved(this, span);
|
||||||
@ -742,7 +743,7 @@ public final class SimpleCache implements Cache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void notifySpanAdded(SimpleCacheSpan span) {
|
private void notifySpanAdded(SimpleCacheSpan span) {
|
||||||
ArrayList<Listener> keyListeners = listeners.get(span.key);
|
@Nullable ArrayList<Listener> keyListeners = listeners.get(span.key);
|
||||||
if (keyListeners != null) {
|
if (keyListeners != null) {
|
||||||
for (int i = keyListeners.size() - 1; i >= 0; i--) {
|
for (int i = keyListeners.size() - 1; i >= 0; i--) {
|
||||||
keyListeners.get(i).onSpanAdded(this, span);
|
keyListeners.get(i).onSpanAdded(this, span);
|
||||||
@ -752,7 +753,7 @@ public final class SimpleCache implements Cache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void notifySpanTouched(SimpleCacheSpan oldSpan, CacheSpan newSpan) {
|
private void notifySpanTouched(SimpleCacheSpan oldSpan, CacheSpan newSpan) {
|
||||||
ArrayList<Listener> keyListeners = listeners.get(oldSpan.key);
|
@Nullable ArrayList<Listener> keyListeners = listeners.get(oldSpan.key);
|
||||||
if (keyListeners != null) {
|
if (keyListeners != null) {
|
||||||
for (int i = keyListeners.size() - 1; i >= 0; i--) {
|
for (int i = keyListeners.size() - 1; i >= 0; i--) {
|
||||||
keyListeners.get(i).onSpanTouched(this, oldSpan, newSpan);
|
keyListeners.get(i).onSpanTouched(this, oldSpan, newSpan);
|
||||||
|
@ -91,6 +91,7 @@ import java.util.regex.Pattern;
|
|||||||
* @param length The length of the cache file in bytes, or {@link C#LENGTH_UNSET} to query the
|
* @param length The length of the cache file in bytes, or {@link C#LENGTH_UNSET} to query the
|
||||||
* underlying file system. Querying the underlying file system can be expensive, so callers
|
* underlying file system. Querying the underlying file system can be expensive, so callers
|
||||||
* that already know the length of the file should pass it explicitly.
|
* that already know the length of the file should pass it explicitly.
|
||||||
|
* @param index The cached content index.
|
||||||
* @return The span, or null if the file name is not correctly formatted, or if the id is not
|
* @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.
|
* present in the content index, or if the length is 0.
|
||||||
*/
|
*/
|
||||||
@ -108,6 +109,7 @@ import java.util.regex.Pattern;
|
|||||||
* that already know the length of the file should pass it explicitly.
|
* that already know the length of the file should pass it explicitly.
|
||||||
* @param lastTouchTimestamp The last touch timestamp, or {@link C#TIME_UNSET} to use the file
|
* @param lastTouchTimestamp The last touch timestamp, or {@link C#TIME_UNSET} to use the file
|
||||||
* timestamp.
|
* timestamp.
|
||||||
|
* @param index The cached content index.
|
||||||
* @return The span, or null if the file name is not correctly formatted, or if the id is not
|
* @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.
|
* present in the content index, or if the length is 0.
|
||||||
*/
|
*/
|
||||||
@ -130,7 +132,7 @@ import java.util.regex.Pattern;
|
|||||||
}
|
}
|
||||||
|
|
||||||
int id = Integer.parseInt(matcher.group(1));
|
int id = Integer.parseInt(matcher.group(1));
|
||||||
String key = index.getKeyForId(id);
|
@Nullable String key = index.getKeyForId(id);
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -153,26 +155,26 @@ import java.util.regex.Pattern;
|
|||||||
* Upgrades the cache file if it is created by an earlier version of {@link SimpleCache}.
|
* Upgrades the cache file if it is created by an earlier version of {@link SimpleCache}.
|
||||||
*
|
*
|
||||||
* @param file The cache file.
|
* @param file The cache file.
|
||||||
* @param index Cached content index.
|
* @param index The cached content index.
|
||||||
* @return Upgraded cache file or {@code null} if the file name is not correctly formatted or the
|
* @return Upgraded cache file or {@code null} if the file name is not correctly formatted or the
|
||||||
* file can not be renamed.
|
* file can not be renamed.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
private static File upgradeFile(File file, CachedContentIndex index) {
|
private static File upgradeFile(File file, CachedContentIndex index) {
|
||||||
String key;
|
@Nullable String key = null;
|
||||||
String filename = file.getName();
|
String filename = file.getName();
|
||||||
Matcher matcher = CACHE_FILE_PATTERN_V2.matcher(filename);
|
Matcher matcher = CACHE_FILE_PATTERN_V2.matcher(filename);
|
||||||
if (matcher.matches()) {
|
if (matcher.matches()) {
|
||||||
key = Util.unescapeFileName(matcher.group(1));
|
key = Util.unescapeFileName(matcher.group(1));
|
||||||
if (key == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
matcher = CACHE_FILE_PATTERN_V1.matcher(filename);
|
matcher = CACHE_FILE_PATTERN_V1.matcher(filename);
|
||||||
if (!matcher.matches()) {
|
if (matcher.matches()) {
|
||||||
return null;
|
key = matcher.group(1); // Keys were not escaped in version 1.
|
||||||
}
|
}
|
||||||
key = matcher.group(1); // Keys were not escaped in version 1.
|
}
|
||||||
|
|
||||||
|
if (key == null) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
File newCacheFile =
|
File newCacheFile =
|
||||||
|
19
library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/package-info.java
vendored
Normal file
19
library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/package-info.java
vendored
Normal file
@ -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.upstream.cache;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer2.util.NonNullApi;
|
@ -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.upstream.crypto;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer2.util.NonNullApi;
|
Loading…
x
Reference in New Issue
Block a user