From 9f8c22d7195d55eccca6a1d9b35cef23a3d3dce8 Mon Sep 17 00:00:00 2001 From: eguven Date: Wed, 3 Oct 2018 03:45:00 -0700 Subject: [PATCH] Make it possible to use CacheKeyFactory with CacheDataSourceFactory and DownloaderConstructorHelper ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=215541062 --- .../offline/DownloaderConstructorHelper.java | 137 ++++++++++++------ .../offline/ProgressiveDownloader.java | 2 +- .../exoplayer2/offline/SegmentDownloader.java | 4 +- .../upstream/cache/CacheDataSource.java | 16 +- .../cache/CacheDataSourceFactory.java | 96 ++++++++---- 5 files changed, 175 insertions(+), 80 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloaderConstructorHelper.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloaderConstructorHelper.java index 18387b9d92..28e898216d 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloaderConstructorHelper.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloaderConstructorHelper.java @@ -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(); + } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/ProgressiveDownloader.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/ProgressiveDownloader.java index 8c80a23d67..adb1c80b0e 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/ProgressiveDownloader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/ProgressiveDownloader.java @@ -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(); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/SegmentDownloader.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/SegmentDownloader.java index 625ec4f5e7..2fdaaa4cbd 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/SegmentDownloader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/SegmentDownloader.java @@ -84,8 +84,8 @@ public abstract class SegmentDownloader> 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(); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSource.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSource.java index fa2068b99d..37bc0aca37 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSource.java @@ -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) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSourceFactory.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSourceFactory.java index f0285da274..d9f9470fe3 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSourceFactory.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSourceFactory.java @@ -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); } }