Make it possible to use CacheKeyFactory with CacheDataSourceFactory and DownloaderConstructorHelper

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=215541062
This commit is contained in:
eguven 2018-10-03 03:45:00 -07:00 committed by Oliver Woodman
parent f0e0a7cf57
commit 9f8c22d719
5 changed files with 175 additions and 80 deletions

View File

@ -19,55 +19,116 @@ import android.support.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.DataSource.Factory;
import com.google.android.exoplayer2.upstream.DummyDataSource;
import com.google.android.exoplayer2.upstream.FileDataSource;
import com.google.android.exoplayer2.upstream.PriorityDataSource;
import com.google.android.exoplayer2.upstream.FileDataSourceFactory;
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.util.Assertions;
import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory;
import com.google.android.exoplayer2.upstream.cache.CacheKeyFactory;
import com.google.android.exoplayer2.util.PriorityTaskManager;
/** A helper class that holds necessary parameters for {@link Downloader} construction. */
public final class DownloaderConstructorHelper {
private final Cache cache;
private final Factory upstreamDataSourceFactory;
private final Factory cacheReadDataSourceFactory;
private final DataSink.Factory cacheWriteDataSinkFactory;
private final PriorityTaskManager priorityTaskManager;
@Nullable private final PriorityTaskManager priorityTaskManager;
private final CacheDataSourceFactory onlineCacheDataSourceFactory;
private final CacheDataSourceFactory offlineCacheDataSourceFactory;
/**
* @param cache Cache instance to be used to store downloaded data.
* @param upstreamDataSourceFactory A {@link Factory} for downloading data.
* @param upstreamFactory A {@link DataSource.Factory} for creating {@link DataSource}s for
* downloading data.
*/
public DownloaderConstructorHelper(Cache cache, Factory upstreamDataSourceFactory) {
this(cache, upstreamDataSourceFactory, null, null, null);
public DownloaderConstructorHelper(Cache cache, DataSource.Factory upstreamFactory) {
this(
cache,
upstreamFactory,
/* cacheReadDataSourceFactory= */ null,
/* cacheWriteDataSinkFactory= */ null,
/* priorityTaskManager= */ null);
}
/**
* @param cache Cache instance to be used to store downloaded data.
* @param upstreamDataSourceFactory A {@link Factory} for downloading data.
* @param cacheReadDataSourceFactory A {@link Factory} for reading data from the cache. If null
* then standard {@link FileDataSource} instances will be used.
* @param cacheWriteDataSinkFactory A {@link DataSink.Factory} for writing data to the cache. If
* null then standard {@link CacheDataSink} instances will be used.
* @param upstreamFactory A {@link DataSource.Factory} for creating {@link DataSource}s for
* downloading data.
* @param cacheReadDataSourceFactory A {@link DataSource.Factory} for creating {@link DataSource}s
* for reading data from the cache. If null then a {@link FileDataSourceFactory} will be used.
* @param cacheWriteDataSinkFactory A {@link DataSink.Factory} for creating {@link DataSource}s
* for writing data to the cache. If null then a {@link CacheDataSinkFactory} will be used.
* @param priorityTaskManager A {@link PriorityTaskManager} to use when downloading. If non-null,
* downloaders will register as tasks with priority {@link C#PRIORITY_DOWNLOAD} whilst
* downloading.
*/
public DownloaderConstructorHelper(
Cache cache,
Factory upstreamDataSourceFactory,
@Nullable Factory cacheReadDataSourceFactory,
DataSource.Factory upstreamFactory,
@Nullable DataSource.Factory cacheReadDataSourceFactory,
@Nullable DataSink.Factory cacheWriteDataSinkFactory,
@Nullable PriorityTaskManager priorityTaskManager) {
Assertions.checkNotNull(upstreamDataSourceFactory);
this(
cache,
upstreamFactory,
cacheReadDataSourceFactory,
cacheWriteDataSinkFactory,
priorityTaskManager,
/* cacheKeyFactory= */ null);
}
/**
* @param cache Cache instance to be used to store downloaded data.
* @param upstreamFactory A {@link DataSource.Factory} for creating {@link DataSource}s for
* downloading data.
* @param cacheReadDataSourceFactory A {@link DataSource.Factory} for creating {@link DataSource}s
* for reading data from the cache. If null then a {@link FileDataSourceFactory} will be used.
* @param cacheWriteDataSinkFactory A {@link DataSink.Factory} for creating {@link DataSource}s
* for writing data to the cache. If null then a {@link CacheDataSinkFactory} will be used.
* @param priorityTaskManager A {@link PriorityTaskManager} to use when downloading. If non-null,
* downloaders will register as tasks with priority {@link C#PRIORITY_DOWNLOAD} whilst
* downloading.
* @param cacheKeyFactory An optional factory for cache keys.
*/
public DownloaderConstructorHelper(
Cache cache,
DataSource.Factory upstreamFactory,
@Nullable DataSource.Factory cacheReadDataSourceFactory,
@Nullable DataSink.Factory cacheWriteDataSinkFactory,
@Nullable PriorityTaskManager priorityTaskManager,
@Nullable CacheKeyFactory cacheKeyFactory) {
if (priorityTaskManager != null) {
upstreamFactory =
new PriorityDataSourceFactory(upstreamFactory, priorityTaskManager, C.PRIORITY_DOWNLOAD);
}
DataSource.Factory readDataSourceFactory =
cacheReadDataSourceFactory != null
? cacheReadDataSourceFactory
: new FileDataSourceFactory();
DataSink.Factory writeDataSinkFactory =
cacheWriteDataSinkFactory != null
? cacheWriteDataSinkFactory
: new CacheDataSinkFactory(cache, CacheDataSource.DEFAULT_MAX_CACHE_FILE_SIZE);
onlineCacheDataSourceFactory =
new CacheDataSourceFactory(
cache,
upstreamFactory,
readDataSourceFactory,
writeDataSinkFactory,
CacheDataSource.FLAG_BLOCK_ON_CACHE,
/* eventListener= */ null,
cacheKeyFactory);
offlineCacheDataSourceFactory =
new CacheDataSourceFactory(
cache,
DummyDataSource.FACTORY,
readDataSourceFactory,
null,
CacheDataSource.FLAG_BLOCK_ON_CACHE,
/* eventListener= */ null,
cacheKeyFactory);
this.cache = cache;
this.upstreamDataSourceFactory = upstreamDataSourceFactory;
this.cacheReadDataSourceFactory = cacheReadDataSourceFactory;
this.cacheWriteDataSinkFactory = cacheWriteDataSinkFactory;
this.priorityTaskManager = priorityTaskManager;
}
@ -83,26 +144,16 @@ public final class DownloaderConstructorHelper {
return priorityTaskManager != null ? priorityTaskManager : new PriorityTaskManager();
}
/**
* Returns a new {@link CacheDataSource} instance. If {@code offline} is true, it can only read
* data from the cache.
*/
public CacheDataSource buildCacheDataSource(boolean offline) {
DataSource cacheReadDataSource = cacheReadDataSourceFactory != null
? cacheReadDataSourceFactory.createDataSource() : new FileDataSource();
if (offline) {
return new CacheDataSource(cache, DummyDataSource.INSTANCE,
cacheReadDataSource, null, CacheDataSource.FLAG_BLOCK_ON_CACHE, null);
} else {
DataSink cacheWriteDataSink = cacheWriteDataSinkFactory != null
? cacheWriteDataSinkFactory.createDataSink()
: new CacheDataSink(cache, CacheDataSource.DEFAULT_MAX_CACHE_FILE_SIZE);
DataSource upstream = upstreamDataSourceFactory.createDataSource();
upstream = priorityTaskManager == null ? upstream
: new PriorityDataSource(upstream, priorityTaskManager, C.PRIORITY_DOWNLOAD);
return new CacheDataSource(cache, upstream, cacheReadDataSource,
cacheWriteDataSink, CacheDataSource.FLAG_BLOCK_ON_CACHE, null);
}
/** Returns a new {@link CacheDataSource} instance. */
public CacheDataSource createCacheDataSource() {
return onlineCacheDataSourceFactory.createDataSource();
}
/**
* Returns a new {@link CacheDataSource} instance which accesses cache read-only and throws an
* exception on cache miss.
*/
public CacheDataSource createOfflineCacheDataSource() {
return offlineCacheDataSourceFactory.createDataSource();
}
}

View File

@ -50,7 +50,7 @@ public final class ProgressiveDownloader implements Downloader {
Uri uri, String customCacheKey, DownloaderConstructorHelper constructorHelper) {
this.dataSpec = new DataSpec(uri, 0, C.LENGTH_UNSET, customCacheKey, 0);
this.cache = constructorHelper.getCache();
this.dataSource = constructorHelper.buildCacheDataSource(false);
this.dataSource = constructorHelper.createCacheDataSource();
this.priorityTaskManager = constructorHelper.getPriorityTaskManager();
cachingCounters = new CachingCounters();
isCanceled = new AtomicBoolean();

View File

@ -84,8 +84,8 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
this.manifestUri = manifestUri;
this.streamKeys = new ArrayList<>(streamKeys);
this.cache = constructorHelper.getCache();
this.dataSource = constructorHelper.buildCacheDataSource(false);
this.offlineDataSource = constructorHelper.buildCacheDataSource(true);
this.dataSource = constructorHelper.createCacheDataSource();
this.offlineDataSource = constructorHelper.createOfflineCacheDataSource();
this.priorityTaskManager = constructorHelper.getPriorityTaskManager();
totalSegments = C.LENGTH_UNSET;
isCanceled = new AtomicBoolean();

View File

@ -57,8 +57,9 @@ public final class CacheDataSource implements DataSource {
public static final long DEFAULT_MAX_CACHE_FILE_SIZE = 2 * 1024 * 1024;
/**
* Flags controlling the cache's behavior. Possible flag values are {@link #FLAG_BLOCK_ON_CACHE},
* {@link #FLAG_IGNORE_CACHE_ON_ERROR} and {@link #FLAG_IGNORE_CACHE_FOR_UNSET_LENGTH_REQUESTS}.
* Flags controlling the CacheDataSource's behavior. Possible flag values are {@link
* #FLAG_BLOCK_ON_CACHE}, {@link #FLAG_IGNORE_CACHE_ON_ERROR} and {@link
* #FLAG_IGNORE_CACHE_FOR_UNSET_LENGTH_REQUESTS}.
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@ -219,8 +220,13 @@ public final class CacheDataSource implements DataSource {
* and {@link #FLAG_IGNORE_CACHE_FOR_UNSET_LENGTH_REQUESTS}, or 0.
* @param eventListener An optional {@link EventListener} to receive events.
*/
public CacheDataSource(Cache cache, DataSource upstream, DataSource cacheReadDataSource,
DataSink cacheWriteDataSink, @Flags int flags, @Nullable EventListener eventListener) {
public CacheDataSource(
Cache cache,
DataSource upstream,
DataSource cacheReadDataSource,
@Nullable DataSink cacheWriteDataSink,
@Flags int flags,
@Nullable EventListener eventListener) {
this(
cache,
upstream,
@ -250,7 +256,7 @@ public final class CacheDataSource implements DataSource {
Cache cache,
DataSource upstream,
DataSource cacheReadDataSource,
DataSink cacheWriteDataSink,
@Nullable DataSink cacheWriteDataSink,
@Flags int flags,
@Nullable EventListener eventListener,
@Nullable CacheKeyFactory cacheKeyFactory) {

View File

@ -15,69 +15,107 @@
*/
package com.google.android.exoplayer2.upstream.cache;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.upstream.DataSink;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSource.Factory;
import com.google.android.exoplayer2.upstream.FileDataSourceFactory;
import com.google.android.exoplayer2.upstream.cache.CacheDataSource.EventListener;
/**
* A {@link DataSource.Factory} that produces {@link CacheDataSource}.
*/
/** A {@link DataSource.Factory} that produces {@link CacheDataSource}. */
public final class CacheDataSourceFactory implements DataSource.Factory {
private final Cache cache;
private final DataSource.Factory upstreamFactory;
private final DataSource.Factory cacheReadDataSourceFactory;
private final DataSink.Factory cacheWriteDataSinkFactory;
private final int flags;
private final EventListener eventListener;
@CacheDataSource.Flags private final int flags;
@Nullable private final DataSink.Factory cacheWriteDataSinkFactory;
@Nullable private final CacheDataSource.EventListener eventListener;
@Nullable private final CacheKeyFactory cacheKeyFactory;
/**
* @see CacheDataSource#CacheDataSource(Cache, DataSource)
* Constructs a factory which creates {@link CacheDataSource} instances with default {@link
* DataSource} and {@link DataSink} instances for reading and writing the cache.
*
* @param cache The cache.
* @param upstreamFactory A {@link DataSource.Factory} for creating upstream {@link DataSource}s
* for reading data not in the cache.
*/
public CacheDataSourceFactory(Cache cache, DataSource.Factory upstreamFactory) {
this(cache, upstreamFactory, 0);
this(cache, upstreamFactory, /* flags= */ 0);
}
/**
* @see CacheDataSource#CacheDataSource(Cache, DataSource, int)
*/
public CacheDataSourceFactory(Cache cache, DataSource.Factory upstreamFactory,
@CacheDataSource.Flags int flags) {
/** @see CacheDataSource#CacheDataSource(Cache, DataSource, int) */
public CacheDataSourceFactory(
Cache cache, DataSource.Factory upstreamFactory, @CacheDataSource.Flags int flags) {
this(cache, upstreamFactory, flags, CacheDataSource.DEFAULT_MAX_CACHE_FILE_SIZE);
}
/**
* @see CacheDataSource#CacheDataSource(Cache, DataSource, int, long)
*/
public CacheDataSourceFactory(Cache cache, DataSource.Factory upstreamFactory,
@CacheDataSource.Flags int flags, long maxCacheFileSize) {
this(cache, upstreamFactory, new FileDataSourceFactory(),
new CacheDataSinkFactory(cache, maxCacheFileSize), flags, null);
/** @see CacheDataSource#CacheDataSource(Cache, DataSource, int, long) */
public CacheDataSourceFactory(
Cache cache,
DataSource.Factory upstreamFactory,
@CacheDataSource.Flags int flags,
long maxCacheFileSize) {
this(
cache,
upstreamFactory,
new FileDataSourceFactory(),
new CacheDataSinkFactory(cache, maxCacheFileSize),
flags,
/* eventListener= */ null);
}
/**
* @see CacheDataSource#CacheDataSource(Cache, DataSource, DataSource, DataSink, int,
* EventListener)
* CacheDataSource.EventListener)
*/
public CacheDataSourceFactory(Cache cache, Factory upstreamFactory,
Factory cacheReadDataSourceFactory, DataSink.Factory cacheWriteDataSinkFactory,
@CacheDataSource.Flags int flags, EventListener eventListener) {
public CacheDataSourceFactory(
Cache cache,
DataSource.Factory upstreamFactory,
DataSource.Factory cacheReadDataSourceFactory,
@Nullable DataSink.Factory cacheWriteDataSinkFactory,
@CacheDataSource.Flags int flags,
@Nullable CacheDataSource.EventListener eventListener) {
this(
cache,
upstreamFactory,
cacheReadDataSourceFactory,
cacheWriteDataSinkFactory,
flags,
eventListener,
/* cacheKeyFactory= */ null);
}
/**
* @see CacheDataSource#CacheDataSource(Cache, DataSource, DataSource, DataSink, int,
* CacheDataSource.EventListener, CacheKeyFactory)
*/
public CacheDataSourceFactory(
Cache cache,
DataSource.Factory upstreamFactory,
DataSource.Factory cacheReadDataSourceFactory,
@Nullable DataSink.Factory cacheWriteDataSinkFactory,
@CacheDataSource.Flags int flags,
@Nullable CacheDataSource.EventListener eventListener,
@Nullable CacheKeyFactory cacheKeyFactory) {
this.cache = cache;
this.upstreamFactory = upstreamFactory;
this.cacheReadDataSourceFactory = cacheReadDataSourceFactory;
this.cacheWriteDataSinkFactory = cacheWriteDataSinkFactory;
this.flags = flags;
this.eventListener = eventListener;
this.cacheKeyFactory = cacheKeyFactory;
}
@Override
public CacheDataSource createDataSource() {
return new CacheDataSource(cache, upstreamFactory.createDataSource(),
return new CacheDataSource(
cache,
upstreamFactory.createDataSource(),
cacheReadDataSourceFactory.createDataSource(),
cacheWriteDataSinkFactory != null ? cacheWriteDataSinkFactory.createDataSink() : null,
flags, eventListener);
cacheWriteDataSinkFactory == null ? null : cacheWriteDataSinkFactory.createDataSink(),
flags,
eventListener,
cacheKeyFactory);
}
}