Commit fab80874 by olly Committed by Ian Baker

Sanitize CacheDataSource/CacheDataSink factories

PiperOrigin-RevId: 307636959
parent 96ccb893
......@@ -73,6 +73,8 @@
* Fix `AdsMediaSource` child `MediaSource`s not being released.
* Parse track titles from Matroska files
([#7247](https://github.com/google/ExoPlayer/pull/7247)).
* Replace `CacheDataSinkFactory` and `CacheDataSourceFactory` with
`CacheDataSink.Factory` and `CacheDataSource.Factory` respectively.
* Text:
* Parse `<ruby>` and `<rt>` tags in WebVTT subtitles (rendering is coming
later).
......
......@@ -19,14 +19,11 @@ import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.upstream.DataSink;
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.PriorityDataSourceFactory;
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.CacheDataSource;
import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory;
import com.google.android.exoplayer2.upstream.cache.CacheKeyFactory;
import com.google.android.exoplayer2.util.PriorityTaskManager;
......@@ -34,8 +31,8 @@ import com.google.android.exoplayer2.util.PriorityTaskManager;
public final class DownloaderConstructorHelper {
@Nullable private final PriorityTaskManager priorityTaskManager;
private final CacheDataSourceFactory onlineCacheDataSourceFactory;
private final CacheDataSourceFactory offlineCacheDataSourceFactory;
private final CacheDataSource.Factory onlineCacheDataSourceFactory;
private final CacheDataSource.Factory offlineCacheDataSourceFactory;
/**
* @param cache Cache instance to be used to store downloaded data.
......@@ -100,37 +97,32 @@ public final class DownloaderConstructorHelper {
@Nullable DataSink.Factory cacheWriteDataSinkFactory,
@Nullable PriorityTaskManager priorityTaskManager,
@Nullable CacheKeyFactory cacheKeyFactory) {
this.priorityTaskManager = priorityTaskManager;
if (priorityTaskManager != null) {
upstreamFactory =
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 =
new CacheDataSourceFactory(
cache,
upstreamFactory,
readDataSourceFactory,
cacheWriteDataSinkFactory,
CacheDataSource.FLAG_BLOCK_ON_CACHE,
/* eventListener= */ null,
cacheKeyFactory);
new CacheDataSource.Factory()
.setCache(cache)
.setUpstreamDataSourceFactory(upstreamFactory)
.setFlags(CacheDataSource.FLAG_BLOCK_ON_CACHE);
offlineCacheDataSourceFactory =
new CacheDataSourceFactory(
cache,
DummyDataSource.FACTORY,
readDataSourceFactory,
null,
CacheDataSource.FLAG_BLOCK_ON_CACHE,
/* eventListener= */ null,
cacheKeyFactory);
this.priorityTaskManager = priorityTaskManager;
new CacheDataSource.Factory()
.setCache(cache)
.setCacheWriteDataSinkFactory(null)
.setFlags(CacheDataSource.FLAG_BLOCK_ON_CACHE);
if (cacheKeyFactory != null) {
onlineCacheDataSourceFactory.setCacheKeyFactory(cacheKeyFactory);
offlineCacheDataSourceFactory.setCacheKeyFactory(cacheKeyFactory);
}
if (cacheReadDataSourceFactory != null) {
onlineCacheDataSourceFactory.setCacheReadDataSourceFactory(cacheReadDataSourceFactory);
offlineCacheDataSourceFactory.setCacheReadDataSourceFactory(cacheReadDataSourceFactory);
}
if (cacheWriteDataSinkFactory != null) {
onlineCacheDataSourceFactory.setCacheWriteDataSinkFactory(cacheWriteDataSinkFactory);
}
}
/** Returns a {@link PriorityTaskManager} instance. */
......
......@@ -39,6 +39,78 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
*/
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. */
public static final long DEFAULT_FRAGMENT_SIZE = 5 * 1024 * 1024;
/** Default buffer size in bytes. */
......@@ -60,17 +132,6 @@ public final class CacheDataSink implements DataSink {
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}.
*
* @param cache The cache into which data should be written.
......
......@@ -17,9 +17,8 @@ package com.google.android.exoplayer2.upstream.cache;
import com.google.android.exoplayer2.upstream.DataSink;
/**
* A {@link DataSink.Factory} that produces {@link CacheDataSink}.
*/
/** @deprecated Use {@link CacheDataSink.Factory}. */
@Deprecated
public final class CacheDataSinkFactory implements DataSink.Factory {
private final Cache cache;
......
......@@ -20,7 +20,8 @@ import com.google.android.exoplayer2.upstream.DataSink;
import com.google.android.exoplayer2.upstream.DataSource;
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 {
private final Cache cache;
......@@ -44,6 +45,7 @@ public final class CacheDataSourceFactory implements DataSource.Factory {
}
/** @see CacheDataSource#CacheDataSource(Cache, DataSource, int) */
@SuppressWarnings("deprecation")
public CacheDataSourceFactory(
Cache cache, DataSource.Factory upstreamFactory, @CacheDataSource.Flags int flags) {
this(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment