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.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.DataSource.Factory;
import com.google.android.exoplayer2.upstream.DummyDataSource; import com.google.android.exoplayer2.upstream.DummyDataSource;
import com.google.android.exoplayer2.upstream.FileDataSource; import com.google.android.exoplayer2.upstream.FileDataSourceFactory;
import com.google.android.exoplayer2.upstream.PriorityDataSource; 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.CacheDataSource; 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; import com.google.android.exoplayer2.util.PriorityTaskManager;
/** A helper class that holds necessary parameters for {@link Downloader} construction. */ /** A helper class that holds necessary parameters for {@link Downloader} construction. */
public final class DownloaderConstructorHelper { public final class DownloaderConstructorHelper {
private final Cache cache; private final Cache cache;
private final Factory upstreamDataSourceFactory; @Nullable private final PriorityTaskManager priorityTaskManager;
private final Factory cacheReadDataSourceFactory; private final CacheDataSourceFactory onlineCacheDataSourceFactory;
private final DataSink.Factory cacheWriteDataSinkFactory; private final CacheDataSourceFactory offlineCacheDataSourceFactory;
private final PriorityTaskManager priorityTaskManager;
/** /**
* @param cache Cache instance to be used to store downloaded data. * @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) { public DownloaderConstructorHelper(Cache cache, DataSource.Factory upstreamFactory) {
this(cache, upstreamDataSourceFactory, null, null, null); this(
cache,
upstreamFactory,
/* cacheReadDataSourceFactory= */ null,
/* cacheWriteDataSinkFactory= */ null,
/* priorityTaskManager= */ null);
} }
/** /**
* @param cache Cache instance to be used to store downloaded data. * @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
* @param cacheReadDataSourceFactory A {@link Factory} for reading data from the cache. If null * downloading data.
* then standard {@link FileDataSource} instances will be used. * @param cacheReadDataSourceFactory A {@link DataSource.Factory} for creating {@link DataSource}s
* @param cacheWriteDataSinkFactory A {@link DataSink.Factory} for writing data to the cache. If * for reading data from the cache. If null then a {@link FileDataSourceFactory} will be used.
* null then standard {@link CacheDataSink} instances 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, * @param priorityTaskManager A {@link PriorityTaskManager} to use when downloading. If non-null,
* downloaders will register as tasks with priority {@link C#PRIORITY_DOWNLOAD} whilst * downloaders will register as tasks with priority {@link C#PRIORITY_DOWNLOAD} whilst
* downloading. * downloading.
*/ */
public DownloaderConstructorHelper( public DownloaderConstructorHelper(
Cache cache, Cache cache,
Factory upstreamDataSourceFactory, DataSource.Factory upstreamFactory,
@Nullable Factory cacheReadDataSourceFactory, @Nullable DataSource.Factory cacheReadDataSourceFactory,
@Nullable DataSink.Factory cacheWriteDataSinkFactory, @Nullable DataSink.Factory cacheWriteDataSinkFactory,
@Nullable PriorityTaskManager priorityTaskManager) { @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.cache = cache;
this.upstreamDataSourceFactory = upstreamDataSourceFactory;
this.cacheReadDataSourceFactory = cacheReadDataSourceFactory;
this.cacheWriteDataSinkFactory = cacheWriteDataSinkFactory;
this.priorityTaskManager = priorityTaskManager; this.priorityTaskManager = priorityTaskManager;
} }
@ -83,26 +144,16 @@ public final class DownloaderConstructorHelper {
return priorityTaskManager != null ? priorityTaskManager : new PriorityTaskManager(); return priorityTaskManager != null ? priorityTaskManager : new PriorityTaskManager();
} }
/** /** Returns a new {@link CacheDataSource} instance. */
* Returns a new {@link CacheDataSource} instance. If {@code offline} is true, it can only read public CacheDataSource createCacheDataSource() {
* data from the cache. return onlineCacheDataSourceFactory.createDataSource();
*/
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 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) { Uri uri, String customCacheKey, DownloaderConstructorHelper constructorHelper) {
this.dataSpec = new DataSpec(uri, 0, C.LENGTH_UNSET, customCacheKey, 0); this.dataSpec = new DataSpec(uri, 0, C.LENGTH_UNSET, customCacheKey, 0);
this.cache = constructorHelper.getCache(); this.cache = constructorHelper.getCache();
this.dataSource = constructorHelper.buildCacheDataSource(false); this.dataSource = constructorHelper.createCacheDataSource();
this.priorityTaskManager = constructorHelper.getPriorityTaskManager(); this.priorityTaskManager = constructorHelper.getPriorityTaskManager();
cachingCounters = new CachingCounters(); cachingCounters = new CachingCounters();
isCanceled = new AtomicBoolean(); isCanceled = new AtomicBoolean();

View File

@ -84,8 +84,8 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
this.manifestUri = manifestUri; this.manifestUri = manifestUri;
this.streamKeys = new ArrayList<>(streamKeys); this.streamKeys = new ArrayList<>(streamKeys);
this.cache = constructorHelper.getCache(); this.cache = constructorHelper.getCache();
this.dataSource = constructorHelper.buildCacheDataSource(false); this.dataSource = constructorHelper.createCacheDataSource();
this.offlineDataSource = constructorHelper.buildCacheDataSource(true); this.offlineDataSource = constructorHelper.createOfflineCacheDataSource();
this.priorityTaskManager = constructorHelper.getPriorityTaskManager(); this.priorityTaskManager = constructorHelper.getPriorityTaskManager();
totalSegments = C.LENGTH_UNSET; totalSegments = C.LENGTH_UNSET;
isCanceled = new AtomicBoolean(); 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; 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}, * Flags controlling the CacheDataSource's behavior. Possible flag values are {@link
* {@link #FLAG_IGNORE_CACHE_ON_ERROR} and {@link #FLAG_IGNORE_CACHE_FOR_UNSET_LENGTH_REQUESTS}. * #FLAG_BLOCK_ON_CACHE}, {@link #FLAG_IGNORE_CACHE_ON_ERROR} and {@link
* #FLAG_IGNORE_CACHE_FOR_UNSET_LENGTH_REQUESTS}.
*/ */
@Documented @Documented
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@ -219,8 +220,13 @@ public final class CacheDataSource implements DataSource {
* and {@link #FLAG_IGNORE_CACHE_FOR_UNSET_LENGTH_REQUESTS}, or 0. * and {@link #FLAG_IGNORE_CACHE_FOR_UNSET_LENGTH_REQUESTS}, or 0.
* @param eventListener An optional {@link EventListener} to receive events. * @param eventListener An optional {@link EventListener} to receive events.
*/ */
public CacheDataSource(Cache cache, DataSource upstream, DataSource cacheReadDataSource, public CacheDataSource(
DataSink cacheWriteDataSink, @Flags int flags, @Nullable EventListener eventListener) { Cache cache,
DataSource upstream,
DataSource cacheReadDataSource,
@Nullable DataSink cacheWriteDataSink,
@Flags int flags,
@Nullable EventListener eventListener) {
this( this(
cache, cache,
upstream, upstream,
@ -250,7 +256,7 @@ public final class CacheDataSource implements DataSource {
Cache cache, Cache cache,
DataSource upstream, DataSource upstream,
DataSource cacheReadDataSource, DataSource cacheReadDataSource,
DataSink cacheWriteDataSink, @Nullable DataSink cacheWriteDataSink,
@Flags int flags, @Flags int flags,
@Nullable EventListener eventListener, @Nullable EventListener eventListener,
@Nullable CacheKeyFactory cacheKeyFactory) { @Nullable CacheKeyFactory cacheKeyFactory) {

View File

@ -15,69 +15,107 @@
*/ */
package com.google.android.exoplayer2.upstream.cache; 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.DataSink;
import com.google.android.exoplayer2.upstream.DataSource; 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.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 { public final class CacheDataSourceFactory implements DataSource.Factory {
private final Cache cache; private final Cache cache;
private final DataSource.Factory upstreamFactory; private final DataSource.Factory upstreamFactory;
private final DataSource.Factory cacheReadDataSourceFactory; private final DataSource.Factory cacheReadDataSourceFactory;
private final DataSink.Factory cacheWriteDataSinkFactory; @CacheDataSource.Flags private final int flags;
private final int flags; @Nullable private final DataSink.Factory cacheWriteDataSinkFactory;
private final EventListener eventListener; @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) { public CacheDataSourceFactory(Cache cache, DataSource.Factory upstreamFactory) {
this(cache, upstreamFactory, 0); this(cache, upstreamFactory, /* flags= */ 0);
} }
/** /** @see CacheDataSource#CacheDataSource(Cache, DataSource, int) */
* @see CacheDataSource#CacheDataSource(Cache, DataSource, int) public CacheDataSourceFactory(
*/ Cache cache, DataSource.Factory upstreamFactory, @CacheDataSource.Flags int flags) {
public CacheDataSourceFactory(Cache cache, DataSource.Factory upstreamFactory,
@CacheDataSource.Flags int flags) {
this(cache, upstreamFactory, flags, CacheDataSource.DEFAULT_MAX_CACHE_FILE_SIZE); this(cache, upstreamFactory, flags, CacheDataSource.DEFAULT_MAX_CACHE_FILE_SIZE);
} }
/** /** @see CacheDataSource#CacheDataSource(Cache, DataSource, int, long) */
* @see CacheDataSource#CacheDataSource(Cache, DataSource, int, long) public CacheDataSourceFactory(
*/ Cache cache,
public CacheDataSourceFactory(Cache cache, DataSource.Factory upstreamFactory, DataSource.Factory upstreamFactory,
@CacheDataSource.Flags int flags, long maxCacheFileSize) { @CacheDataSource.Flags int flags,
this(cache, upstreamFactory, new FileDataSourceFactory(), long maxCacheFileSize) {
new CacheDataSinkFactory(cache, maxCacheFileSize), flags, null); this(
cache,
upstreamFactory,
new FileDataSourceFactory(),
new CacheDataSinkFactory(cache, maxCacheFileSize),
flags,
/* eventListener= */ null);
} }
/** /**
* @see CacheDataSource#CacheDataSource(Cache, DataSource, DataSource, DataSink, int, * @see CacheDataSource#CacheDataSource(Cache, DataSource, DataSource, DataSink, int,
* EventListener) * CacheDataSource.EventListener)
*/ */
public CacheDataSourceFactory(Cache cache, Factory upstreamFactory, public CacheDataSourceFactory(
Factory cacheReadDataSourceFactory, DataSink.Factory cacheWriteDataSinkFactory, Cache cache,
@CacheDataSource.Flags int flags, EventListener eventListener) { 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.cache = cache;
this.upstreamFactory = upstreamFactory; this.upstreamFactory = upstreamFactory;
this.cacheReadDataSourceFactory = cacheReadDataSourceFactory; this.cacheReadDataSourceFactory = cacheReadDataSourceFactory;
this.cacheWriteDataSinkFactory = cacheWriteDataSinkFactory; this.cacheWriteDataSinkFactory = cacheWriteDataSinkFactory;
this.flags = flags; this.flags = flags;
this.eventListener = eventListener; this.eventListener = eventListener;
this.cacheKeyFactory = cacheKeyFactory;
} }
@Override @Override
public CacheDataSource createDataSource() { public CacheDataSource createDataSource() {
return new CacheDataSource(cache, upstreamFactory.createDataSource(), return new CacheDataSource(
cache,
upstreamFactory.createDataSource(),
cacheReadDataSourceFactory.createDataSource(), cacheReadDataSourceFactory.createDataSource(),
cacheWriteDataSinkFactory != null ? cacheWriteDataSinkFactory.createDataSink() : null, cacheWriteDataSinkFactory == null ? null : cacheWriteDataSinkFactory.createDataSink(),
flags, eventListener); flags,
eventListener,
cacheKeyFactory);
} }
} }