mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Sanitize CacheDataSource/CacheDataSink factories
PiperOrigin-RevId: 307636959
This commit is contained in:
parent
96ccb893f2
commit
fab8087472
6 changed files with 286 additions and 80 deletions
|
|
@ -73,6 +73,8 @@
|
||||||
* Fix `AdsMediaSource` child `MediaSource`s not being released.
|
* Fix `AdsMediaSource` child `MediaSource`s not being released.
|
||||||
* Parse track titles from Matroska files
|
* Parse track titles from Matroska files
|
||||||
([#7247](https://github.com/google/ExoPlayer/pull/7247)).
|
([#7247](https://github.com/google/ExoPlayer/pull/7247)).
|
||||||
|
* Replace `CacheDataSinkFactory` and `CacheDataSourceFactory` with
|
||||||
|
`CacheDataSink.Factory` and `CacheDataSource.Factory` respectively.
|
||||||
* Text:
|
* Text:
|
||||||
* Parse `<ruby>` and `<rt>` tags in WebVTT subtitles (rendering is coming
|
* Parse `<ruby>` and `<rt>` tags in WebVTT subtitles (rendering is coming
|
||||||
later).
|
later).
|
||||||
|
|
|
||||||
|
|
@ -19,14 +19,11 @@ 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.DataSource;
|
import com.google.android.exoplayer2.upstream.DataSource;
|
||||||
import com.google.android.exoplayer2.upstream.DummyDataSource;
|
|
||||||
import com.google.android.exoplayer2.upstream.FileDataSource;
|
import com.google.android.exoplayer2.upstream.FileDataSource;
|
||||||
import com.google.android.exoplayer2.upstream.PriorityDataSourceFactory;
|
import com.google.android.exoplayer2.upstream.PriorityDataSourceFactory;
|
||||||
import com.google.android.exoplayer2.upstream.cache.Cache;
|
import com.google.android.exoplayer2.upstream.cache.Cache;
|
||||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSink;
|
|
||||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSinkFactory;
|
import com.google.android.exoplayer2.upstream.cache.CacheDataSinkFactory;
|
||||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
||||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory;
|
|
||||||
import com.google.android.exoplayer2.upstream.cache.CacheKeyFactory;
|
import com.google.android.exoplayer2.upstream.cache.CacheKeyFactory;
|
||||||
import com.google.android.exoplayer2.util.PriorityTaskManager;
|
import com.google.android.exoplayer2.util.PriorityTaskManager;
|
||||||
|
|
||||||
|
|
@ -34,8 +31,8 @@ import com.google.android.exoplayer2.util.PriorityTaskManager;
|
||||||
public final class DownloaderConstructorHelper {
|
public final class DownloaderConstructorHelper {
|
||||||
|
|
||||||
@Nullable private final PriorityTaskManager priorityTaskManager;
|
@Nullable private final PriorityTaskManager priorityTaskManager;
|
||||||
private final CacheDataSourceFactory onlineCacheDataSourceFactory;
|
private final CacheDataSource.Factory onlineCacheDataSourceFactory;
|
||||||
private final CacheDataSourceFactory offlineCacheDataSourceFactory;
|
private final CacheDataSource.Factory offlineCacheDataSourceFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param cache Cache instance to be used to store downloaded data.
|
* @param cache Cache instance to be used to store downloaded data.
|
||||||
|
|
@ -100,37 +97,32 @@ public final class DownloaderConstructorHelper {
|
||||||
@Nullable DataSink.Factory cacheWriteDataSinkFactory,
|
@Nullable DataSink.Factory cacheWriteDataSinkFactory,
|
||||||
@Nullable PriorityTaskManager priorityTaskManager,
|
@Nullable PriorityTaskManager priorityTaskManager,
|
||||||
@Nullable CacheKeyFactory cacheKeyFactory) {
|
@Nullable CacheKeyFactory cacheKeyFactory) {
|
||||||
|
this.priorityTaskManager = priorityTaskManager;
|
||||||
if (priorityTaskManager != null) {
|
if (priorityTaskManager != null) {
|
||||||
upstreamFactory =
|
upstreamFactory =
|
||||||
new PriorityDataSourceFactory(upstreamFactory, priorityTaskManager, C.PRIORITY_DOWNLOAD);
|
new PriorityDataSourceFactory(upstreamFactory, priorityTaskManager, C.PRIORITY_DOWNLOAD);
|
||||||
}
|
}
|
||||||
DataSource.Factory readDataSourceFactory =
|
|
||||||
cacheReadDataSourceFactory != null
|
|
||||||
? cacheReadDataSourceFactory
|
|
||||||
: new FileDataSource.Factory();
|
|
||||||
if (cacheWriteDataSinkFactory == null) {
|
|
||||||
cacheWriteDataSinkFactory =
|
|
||||||
new CacheDataSinkFactory(cache, CacheDataSink.DEFAULT_FRAGMENT_SIZE);
|
|
||||||
}
|
|
||||||
onlineCacheDataSourceFactory =
|
onlineCacheDataSourceFactory =
|
||||||
new CacheDataSourceFactory(
|
new CacheDataSource.Factory()
|
||||||
cache,
|
.setCache(cache)
|
||||||
upstreamFactory,
|
.setUpstreamDataSourceFactory(upstreamFactory)
|
||||||
readDataSourceFactory,
|
.setFlags(CacheDataSource.FLAG_BLOCK_ON_CACHE);
|
||||||
cacheWriteDataSinkFactory,
|
|
||||||
CacheDataSource.FLAG_BLOCK_ON_CACHE,
|
|
||||||
/* eventListener= */ null,
|
|
||||||
cacheKeyFactory);
|
|
||||||
offlineCacheDataSourceFactory =
|
offlineCacheDataSourceFactory =
|
||||||
new CacheDataSourceFactory(
|
new CacheDataSource.Factory()
|
||||||
cache,
|
.setCache(cache)
|
||||||
DummyDataSource.FACTORY,
|
.setCacheWriteDataSinkFactory(null)
|
||||||
readDataSourceFactory,
|
.setFlags(CacheDataSource.FLAG_BLOCK_ON_CACHE);
|
||||||
null,
|
if (cacheKeyFactory != null) {
|
||||||
CacheDataSource.FLAG_BLOCK_ON_CACHE,
|
onlineCacheDataSourceFactory.setCacheKeyFactory(cacheKeyFactory);
|
||||||
/* eventListener= */ null,
|
offlineCacheDataSourceFactory.setCacheKeyFactory(cacheKeyFactory);
|
||||||
cacheKeyFactory);
|
}
|
||||||
this.priorityTaskManager = priorityTaskManager;
|
if (cacheReadDataSourceFactory != null) {
|
||||||
|
onlineCacheDataSourceFactory.setCacheReadDataSourceFactory(cacheReadDataSourceFactory);
|
||||||
|
offlineCacheDataSourceFactory.setCacheReadDataSourceFactory(cacheReadDataSourceFactory);
|
||||||
|
}
|
||||||
|
if (cacheWriteDataSinkFactory != null) {
|
||||||
|
onlineCacheDataSourceFactory.setCacheWriteDataSinkFactory(cacheWriteDataSinkFactory);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a {@link PriorityTaskManager} instance. */
|
/** Returns a {@link PriorityTaskManager} instance. */
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,78 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
*/
|
*/
|
||||||
public final class CacheDataSink implements DataSink {
|
public final class CacheDataSink implements DataSink {
|
||||||
|
|
||||||
|
/** {@link DataSink.Factory} for {@link CacheDataSink} instances. */
|
||||||
|
public static final class Factory implements DataSink.Factory {
|
||||||
|
|
||||||
|
private @MonotonicNonNull Cache cache;
|
||||||
|
private long fragmentSize;
|
||||||
|
private int bufferSize;
|
||||||
|
|
||||||
|
/** Creates an instance. */
|
||||||
|
public Factory() {
|
||||||
|
fragmentSize = CacheDataSink.DEFAULT_FRAGMENT_SIZE;
|
||||||
|
bufferSize = CacheDataSink.DEFAULT_BUFFER_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the cache to which data will be written.
|
||||||
|
*
|
||||||
|
* <p>Must be called before the factory is used.
|
||||||
|
*
|
||||||
|
* @param cache The cache to which data will be written.
|
||||||
|
* @return This factory.
|
||||||
|
*/
|
||||||
|
public Factory setCache(Cache cache) {
|
||||||
|
this.cache = cache;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the cache file fragment size. For requests that should be fragmented into multiple cache
|
||||||
|
* files, this is the maximum size of a cache file in bytes. If set to {@link C#LENGTH_UNSET}
|
||||||
|
* then no fragmentation will occur. Using a small value allows for finer-grained cache eviction
|
||||||
|
* policies, at the cost of increased overhead both on the cache implementation and the file
|
||||||
|
* system. Values under {@code (2 * 1024 * 1024)} are not recommended.
|
||||||
|
*
|
||||||
|
* <p>The default value is {@link CacheDataSink#DEFAULT_FRAGMENT_SIZE}.
|
||||||
|
*
|
||||||
|
* @param fragmentSize The fragment size in bytes, or {@link C#LENGTH_UNSET} to disable
|
||||||
|
* fragmentation.
|
||||||
|
* @return This factory.
|
||||||
|
*/
|
||||||
|
public Factory setFragmentSize(long fragmentSize) {
|
||||||
|
this.fragmentSize = fragmentSize;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the size of an in-memory buffer used when writing to a cache file. A zero or negative
|
||||||
|
* value disables buffering.
|
||||||
|
*
|
||||||
|
* <p>The default value is {@link CacheDataSink#DEFAULT_BUFFER_SIZE}.
|
||||||
|
*
|
||||||
|
* @param bufferSize The buffer size in bytes.
|
||||||
|
* @return This factory.
|
||||||
|
*/
|
||||||
|
public Factory setBufferSize(int bufferSize) {
|
||||||
|
this.bufferSize = bufferSize;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataSink createDataSink() {
|
||||||
|
return new CacheDataSink(Assertions.checkNotNull(cache), fragmentSize, bufferSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Thrown when an {@link IOException} is encountered when writing data to the sink. */
|
||||||
|
public static final class CacheDataSinkException extends CacheException {
|
||||||
|
|
||||||
|
public CacheDataSinkException(IOException cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Default {@code fragmentSize} recommended for caching use cases. */
|
/** Default {@code fragmentSize} recommended for caching use cases. */
|
||||||
public static final long DEFAULT_FRAGMENT_SIZE = 5 * 1024 * 1024;
|
public static final long DEFAULT_FRAGMENT_SIZE = 5 * 1024 * 1024;
|
||||||
/** Default buffer size in bytes. */
|
/** Default buffer size in bytes. */
|
||||||
|
|
@ -59,17 +131,6 @@ public final class CacheDataSink implements DataSink {
|
||||||
private long dataSpecBytesWritten;
|
private long dataSpecBytesWritten;
|
||||||
private @MonotonicNonNull ReusableBufferedOutputStream bufferedOutputStream;
|
private @MonotonicNonNull ReusableBufferedOutputStream bufferedOutputStream;
|
||||||
|
|
||||||
/**
|
|
||||||
* Thrown when IOException is encountered when writing data into sink.
|
|
||||||
*/
|
|
||||||
public static class CacheDataSinkException extends CacheException {
|
|
||||||
|
|
||||||
public CacheDataSinkException(IOException cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance using {@link #DEFAULT_BUFFER_SIZE}.
|
* Constructs an instance using {@link #DEFAULT_BUFFER_SIZE}.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,8 @@ package com.google.android.exoplayer2.upstream.cache;
|
||||||
|
|
||||||
import com.google.android.exoplayer2.upstream.DataSink;
|
import com.google.android.exoplayer2.upstream.DataSink;
|
||||||
|
|
||||||
/**
|
/** @deprecated Use {@link CacheDataSink.Factory}. */
|
||||||
* A {@link DataSink.Factory} that produces {@link CacheDataSink}.
|
@Deprecated
|
||||||
*/
|
|
||||||
public final class CacheDataSinkFactory implements DataSink.Factory {
|
public final class CacheDataSinkFactory implements DataSink.Factory {
|
||||||
|
|
||||||
private final Cache cache;
|
private final Cache cache;
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import com.google.android.exoplayer2.upstream.DataSink;
|
||||||
import com.google.android.exoplayer2.upstream.DataSource;
|
import com.google.android.exoplayer2.upstream.DataSource;
|
||||||
import com.google.android.exoplayer2.upstream.DataSourceException;
|
import com.google.android.exoplayer2.upstream.DataSourceException;
|
||||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||||
|
import com.google.android.exoplayer2.upstream.DummyDataSource;
|
||||||
import com.google.android.exoplayer2.upstream.FileDataSource;
|
import com.google.android.exoplayer2.upstream.FileDataSource;
|
||||||
import com.google.android.exoplayer2.upstream.TeeDataSource;
|
import com.google.android.exoplayer2.upstream.TeeDataSource;
|
||||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||||
|
|
@ -36,6 +37,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link DataSource} that reads and writes a {@link Cache}. Requests are fulfilled from the cache
|
* A {@link DataSource} that reads and writes a {@link Cache}. Requests are fulfilled from the cache
|
||||||
|
|
@ -44,6 +46,167 @@ import java.util.Map;
|
||||||
*/
|
*/
|
||||||
public final class CacheDataSource implements DataSource {
|
public final class CacheDataSource implements DataSource {
|
||||||
|
|
||||||
|
/** {@link DataSource.Factory} for {@link CacheDataSource} instances. */
|
||||||
|
public static final class Factory implements DataSource.Factory {
|
||||||
|
|
||||||
|
private @MonotonicNonNull Cache cache;
|
||||||
|
private DataSource.Factory cacheReadDataSourceFactory;
|
||||||
|
@Nullable private DataSink.Factory cacheWriteDataSinkFactory;
|
||||||
|
private CacheKeyFactory cacheKeyFactory;
|
||||||
|
private boolean cacheIsReadOnly;
|
||||||
|
@Nullable private DataSource.Factory upstreamDataSourceFactory;
|
||||||
|
@CacheDataSource.Flags private int flags;
|
||||||
|
@Nullable private CacheDataSource.EventListener eventListener;
|
||||||
|
|
||||||
|
public Factory() {
|
||||||
|
cacheReadDataSourceFactory = new FileDataSource.Factory();
|
||||||
|
cacheKeyFactory = CacheUtil.DEFAULT_CACHE_KEY_FACTORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the cache that will be used.
|
||||||
|
*
|
||||||
|
* <p>Must be called before the factory is used.
|
||||||
|
*
|
||||||
|
* @param cache The cache that will be used.
|
||||||
|
* @return This factory.
|
||||||
|
*/
|
||||||
|
public Factory setCache(Cache cache) {
|
||||||
|
this.cache = cache;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link DataSource.Factory} for {@link DataSource DataSources} for reading from the
|
||||||
|
* cache.
|
||||||
|
*
|
||||||
|
* <p>The default is a {@link FileDataSource.Factory} in its default configuration.
|
||||||
|
*
|
||||||
|
* @param cacheReadDataSourceFactory The {@link DataSource.Factory} for reading from the cache.
|
||||||
|
* @return This factory.
|
||||||
|
*/
|
||||||
|
public Factory setCacheReadDataSourceFactory(DataSource.Factory cacheReadDataSourceFactory) {
|
||||||
|
this.cacheReadDataSourceFactory = cacheReadDataSourceFactory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link DataSink.Factory} for generating {@link DataSink DataSinks} for writing data
|
||||||
|
* to the cache. Passing {@code null} causes the cache to be read-only.
|
||||||
|
*
|
||||||
|
* <p>The default is a {@link CacheDataSink.Factory} in its default configuration.
|
||||||
|
*
|
||||||
|
* @param cacheWriteDataSinkFactory The {@link DataSink.Factory} for generating {@link DataSink
|
||||||
|
* DataSinks} for writing data to the cache, or {@code null} to disable writing.
|
||||||
|
* @return This factory.
|
||||||
|
*/
|
||||||
|
public Factory setCacheWriteDataSinkFactory(
|
||||||
|
@Nullable DataSink.Factory cacheWriteDataSinkFactory) {
|
||||||
|
this.cacheWriteDataSinkFactory = cacheWriteDataSinkFactory;
|
||||||
|
this.cacheIsReadOnly = cacheWriteDataSinkFactory == null;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link CacheKeyFactory}.
|
||||||
|
*
|
||||||
|
* <p>The default is {@link CacheUtil#DEFAULT_CACHE_KEY_FACTORY}.
|
||||||
|
*
|
||||||
|
* @param cacheKeyFactory The {@link CacheKeyFactory}.
|
||||||
|
* @return This factory.
|
||||||
|
*/
|
||||||
|
public Factory setCacheKeyFactory(CacheKeyFactory cacheKeyFactory) {
|
||||||
|
this.cacheKeyFactory = cacheKeyFactory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link DataSource.Factory} for upstream {@link DataSource DataSources}, which are
|
||||||
|
* used to read data in the case of a cache miss.
|
||||||
|
*
|
||||||
|
* <p>The default is {@code null}, and so this method must be called before the factory is used
|
||||||
|
* in order for data to be read from upstream in the case of a cache miss.
|
||||||
|
*
|
||||||
|
* @param upstreamDataSourceFactory The upstream {@link DataSource} for reading data not in the
|
||||||
|
* cache, or {@code null} to cause failure in the case of a cache miss.
|
||||||
|
* @return This factory.
|
||||||
|
*/
|
||||||
|
public Factory setUpstreamDataSourceFactory(
|
||||||
|
@Nullable DataSource.Factory upstreamDataSourceFactory) {
|
||||||
|
this.upstreamDataSourceFactory = upstreamDataSourceFactory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link CacheDataSource.Flags}.
|
||||||
|
*
|
||||||
|
* <p>The default is {@code 0}.
|
||||||
|
*
|
||||||
|
* @param flags The {@link CacheDataSource.Flags}.
|
||||||
|
* @return This factory.
|
||||||
|
*/
|
||||||
|
public Factory setFlags(@CacheDataSource.Flags int flags) {
|
||||||
|
this.flags = flags;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {link EventListener} to which events are delivered.
|
||||||
|
*
|
||||||
|
* <p>The default is {@code null}.
|
||||||
|
*
|
||||||
|
* @param eventListener The {@link EventListener}.
|
||||||
|
* @return This factory.
|
||||||
|
*/
|
||||||
|
public Factory setEventListener(@Nullable EventListener eventListener) {
|
||||||
|
this.eventListener = eventListener;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CacheDataSource createDataSource() {
|
||||||
|
Cache cache = Assertions.checkNotNull(this.cache);
|
||||||
|
@Nullable
|
||||||
|
DataSource upstreamDataSource =
|
||||||
|
upstreamDataSourceFactory != null ? upstreamDataSourceFactory.createDataSource() : null;
|
||||||
|
@Nullable DataSink cacheWriteDataSink;
|
||||||
|
if (cacheIsReadOnly) {
|
||||||
|
cacheWriteDataSink = null;
|
||||||
|
} else if (cacheWriteDataSinkFactory != null) {
|
||||||
|
cacheWriteDataSink = cacheWriteDataSinkFactory.createDataSink();
|
||||||
|
} else {
|
||||||
|
cacheWriteDataSink = new CacheDataSink.Factory().setCache(cache).createDataSink();
|
||||||
|
}
|
||||||
|
return new CacheDataSource(
|
||||||
|
cache,
|
||||||
|
upstreamDataSource,
|
||||||
|
cacheReadDataSourceFactory.createDataSource(),
|
||||||
|
cacheWriteDataSink,
|
||||||
|
flags,
|
||||||
|
eventListener,
|
||||||
|
cacheKeyFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Listener of {@link CacheDataSource} events. */
|
||||||
|
public interface EventListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when bytes have been read from the cache.
|
||||||
|
*
|
||||||
|
* @param cacheSizeBytes Current cache size in bytes.
|
||||||
|
* @param cachedBytesRead Total bytes read from the cache since this method was last called.
|
||||||
|
*/
|
||||||
|
void onCachedBytesRead(long cacheSizeBytes, long cachedBytesRead);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the current request ignores cache.
|
||||||
|
*
|
||||||
|
* @param reason Reason cache is bypassed.
|
||||||
|
*/
|
||||||
|
void onCacheIgnored(@CacheIgnoredReason int reason);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flags controlling the CacheDataSource's behavior. Possible flag values are {@link
|
* Flags controlling the CacheDataSource's behavior. Possible flag values are {@link
|
||||||
* #FLAG_BLOCK_ON_CACHE}, {@link #FLAG_IGNORE_CACHE_ON_ERROR} and {@link
|
* #FLAG_BLOCK_ON_CACHE}, {@link #FLAG_IGNORE_CACHE_ON_ERROR} and {@link
|
||||||
|
|
@ -96,27 +259,6 @@ public final class CacheDataSource implements DataSource {
|
||||||
/** Cache ignored due to a request with an unset length. */
|
/** Cache ignored due to a request with an unset length. */
|
||||||
public static final int CACHE_IGNORED_REASON_UNSET_LENGTH = 1;
|
public static final int CACHE_IGNORED_REASON_UNSET_LENGTH = 1;
|
||||||
|
|
||||||
/**
|
|
||||||
* Listener of {@link CacheDataSource} events.
|
|
||||||
*/
|
|
||||||
public interface EventListener {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when bytes have been read from the cache.
|
|
||||||
*
|
|
||||||
* @param cacheSizeBytes Current cache size in bytes.
|
|
||||||
* @param cachedBytesRead Total bytes read from the cache since this method was last called.
|
|
||||||
*/
|
|
||||||
void onCachedBytesRead(long cacheSizeBytes, long cachedBytesRead);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the current request ignores cache.
|
|
||||||
*
|
|
||||||
* @param reason Reason cache is bypassed.
|
|
||||||
*/
|
|
||||||
void onCacheIgnored(@CacheIgnoredReason int reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Minimum number of bytes to read before checking cache for availability. */
|
/** Minimum number of bytes to read before checking cache for availability. */
|
||||||
private static final long MIN_READ_BEFORE_CHECKING_CACHE = 100 * 1024;
|
private static final long MIN_READ_BEFORE_CHECKING_CACHE = 100 * 1024;
|
||||||
|
|
||||||
|
|
@ -148,10 +290,11 @@ public final class CacheDataSource implements DataSource {
|
||||||
* reading and writing the cache.
|
* reading and writing the cache.
|
||||||
*
|
*
|
||||||
* @param cache The cache.
|
* @param cache The cache.
|
||||||
* @param upstream A {@link DataSource} for reading data not in the cache.
|
* @param upstreamDataSource A {@link DataSource} for reading data not in the cache. If null,
|
||||||
|
* reading will fail if a cache miss occurs.
|
||||||
*/
|
*/
|
||||||
public CacheDataSource(Cache cache, DataSource upstream) {
|
public CacheDataSource(Cache cache, @Nullable DataSource upstreamDataSource) {
|
||||||
this(cache, upstream, /* flags= */ 0);
|
this(cache, upstreamDataSource, /* flags= */ 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -159,14 +302,15 @@ public final class CacheDataSource implements DataSource {
|
||||||
* reading and writing the cache.
|
* reading and writing the cache.
|
||||||
*
|
*
|
||||||
* @param cache The cache.
|
* @param cache The cache.
|
||||||
* @param upstream A {@link DataSource} for reading data not in the cache.
|
* @param upstreamDataSource A {@link DataSource} for reading data not in the cache. If null,
|
||||||
|
* reading will fail if a cache miss occurs.
|
||||||
* @param flags A combination of {@link #FLAG_BLOCK_ON_CACHE}, {@link #FLAG_IGNORE_CACHE_ON_ERROR}
|
* @param flags A combination of {@link #FLAG_BLOCK_ON_CACHE}, {@link #FLAG_IGNORE_CACHE_ON_ERROR}
|
||||||
* and {@link #FLAG_IGNORE_CACHE_FOR_UNSET_LENGTH_REQUESTS}, or 0.
|
* and {@link #FLAG_IGNORE_CACHE_FOR_UNSET_LENGTH_REQUESTS}, or 0.
|
||||||
*/
|
*/
|
||||||
public CacheDataSource(Cache cache, DataSource upstream, @Flags int flags) {
|
public CacheDataSource(Cache cache, @Nullable DataSource upstreamDataSource, @Flags int flags) {
|
||||||
this(
|
this(
|
||||||
cache,
|
cache,
|
||||||
upstream,
|
upstreamDataSource,
|
||||||
new FileDataSource(),
|
new FileDataSource(),
|
||||||
new CacheDataSink(cache, CacheDataSink.DEFAULT_FRAGMENT_SIZE),
|
new CacheDataSink(cache, CacheDataSink.DEFAULT_FRAGMENT_SIZE),
|
||||||
flags,
|
flags,
|
||||||
|
|
@ -179,7 +323,8 @@ public final class CacheDataSource implements DataSource {
|
||||||
* before it is written to disk.
|
* before it is written to disk.
|
||||||
*
|
*
|
||||||
* @param cache The cache.
|
* @param cache The cache.
|
||||||
* @param upstream A {@link DataSource} for reading data not in the cache.
|
* @param upstreamDataSource A {@link DataSource} for reading data not in the cache. If null,
|
||||||
|
* reading will fail if a cache miss occurs.
|
||||||
* @param cacheReadDataSource A {@link DataSource} for reading data from the cache.
|
* @param cacheReadDataSource A {@link DataSource} for reading data from the cache.
|
||||||
* @param cacheWriteDataSink A {@link DataSink} for writing data to the cache. If null, cache is
|
* @param cacheWriteDataSink A {@link DataSink} for writing data to the cache. If null, cache is
|
||||||
* accessed read-only.
|
* accessed read-only.
|
||||||
|
|
@ -189,14 +334,14 @@ public final class CacheDataSource implements DataSource {
|
||||||
*/
|
*/
|
||||||
public CacheDataSource(
|
public CacheDataSource(
|
||||||
Cache cache,
|
Cache cache,
|
||||||
DataSource upstream,
|
@Nullable DataSource upstreamDataSource,
|
||||||
DataSource cacheReadDataSource,
|
DataSource cacheReadDataSource,
|
||||||
@Nullable DataSink cacheWriteDataSink,
|
@Nullable DataSink cacheWriteDataSink,
|
||||||
@Flags int flags,
|
@Flags int flags,
|
||||||
@Nullable EventListener eventListener) {
|
@Nullable EventListener eventListener) {
|
||||||
this(
|
this(
|
||||||
cache,
|
cache,
|
||||||
upstream,
|
upstreamDataSource,
|
||||||
cacheReadDataSource,
|
cacheReadDataSource,
|
||||||
cacheWriteDataSink,
|
cacheWriteDataSink,
|
||||||
flags,
|
flags,
|
||||||
|
|
@ -210,7 +355,8 @@ public final class CacheDataSource implements DataSource {
|
||||||
* before it is written to disk.
|
* before it is written to disk.
|
||||||
*
|
*
|
||||||
* @param cache The cache.
|
* @param cache The cache.
|
||||||
* @param upstream A {@link DataSource} for reading data not in the cache.
|
* @param upstreamDataSource A {@link DataSource} for reading data not in the cache. If null,
|
||||||
|
* reading will fail if a cache miss occurs.
|
||||||
* @param cacheReadDataSource A {@link DataSource} for reading data from the cache.
|
* @param cacheReadDataSource A {@link DataSource} for reading data from the cache.
|
||||||
* @param cacheWriteDataSink A {@link DataSink} for writing data to the cache. If null, cache is
|
* @param cacheWriteDataSink A {@link DataSink} for writing data to the cache. If null, cache is
|
||||||
* accessed read-only.
|
* accessed read-only.
|
||||||
|
|
@ -221,7 +367,7 @@ public final class CacheDataSource implements DataSource {
|
||||||
*/
|
*/
|
||||||
public CacheDataSource(
|
public CacheDataSource(
|
||||||
Cache cache,
|
Cache cache,
|
||||||
DataSource upstream,
|
@Nullable DataSource upstreamDataSource,
|
||||||
DataSource cacheReadDataSource,
|
DataSource cacheReadDataSource,
|
||||||
@Nullable DataSink cacheWriteDataSink,
|
@Nullable DataSink cacheWriteDataSink,
|
||||||
@Flags int flags,
|
@Flags int flags,
|
||||||
|
|
@ -235,10 +381,14 @@ public final class CacheDataSource implements DataSource {
|
||||||
this.ignoreCacheOnError = (flags & FLAG_IGNORE_CACHE_ON_ERROR) != 0;
|
this.ignoreCacheOnError = (flags & FLAG_IGNORE_CACHE_ON_ERROR) != 0;
|
||||||
this.ignoreCacheForUnsetLengthRequests =
|
this.ignoreCacheForUnsetLengthRequests =
|
||||||
(flags & FLAG_IGNORE_CACHE_FOR_UNSET_LENGTH_REQUESTS) != 0;
|
(flags & FLAG_IGNORE_CACHE_FOR_UNSET_LENGTH_REQUESTS) != 0;
|
||||||
this.upstreamDataSource = upstream;
|
if (upstreamDataSource != null) {
|
||||||
if (cacheWriteDataSink != null) {
|
this.upstreamDataSource = upstreamDataSource;
|
||||||
this.cacheWriteDataSource = new TeeDataSource(upstream, cacheWriteDataSink);
|
this.cacheWriteDataSource =
|
||||||
|
cacheWriteDataSink != null
|
||||||
|
? new TeeDataSource(upstreamDataSource, cacheWriteDataSink)
|
||||||
|
: null;
|
||||||
} else {
|
} else {
|
||||||
|
this.upstreamDataSource = DummyDataSource.INSTANCE;
|
||||||
this.cacheWriteDataSource = null;
|
this.cacheWriteDataSource = null;
|
||||||
}
|
}
|
||||||
this.eventListener = eventListener;
|
this.eventListener = eventListener;
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,8 @@ import com.google.android.exoplayer2.upstream.DataSink;
|
||||||
import com.google.android.exoplayer2.upstream.DataSource;
|
import com.google.android.exoplayer2.upstream.DataSource;
|
||||||
import com.google.android.exoplayer2.upstream.FileDataSource;
|
import com.google.android.exoplayer2.upstream.FileDataSource;
|
||||||
|
|
||||||
/** A {@link DataSource.Factory} that produces {@link CacheDataSource}. */
|
/** @deprecated Use {@link CacheDataSource.Factory}. */
|
||||||
|
@Deprecated
|
||||||
public final class CacheDataSourceFactory implements DataSource.Factory {
|
public final class CacheDataSourceFactory implements DataSource.Factory {
|
||||||
|
|
||||||
private final Cache cache;
|
private final Cache cache;
|
||||||
|
|
@ -44,6 +45,7 @@ public final class CacheDataSourceFactory implements DataSource.Factory {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @see CacheDataSource#CacheDataSource(Cache, DataSource, int) */
|
/** @see CacheDataSource#CacheDataSource(Cache, DataSource, int) */
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public CacheDataSourceFactory(
|
public CacheDataSourceFactory(
|
||||||
Cache cache, DataSource.Factory upstreamFactory, @CacheDataSource.Flags int flags) {
|
Cache cache, DataSource.Factory upstreamFactory, @CacheDataSource.Flags int flags) {
|
||||||
this(
|
this(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue