From 4abaaf138cac9b898ea1efae65c00974d66ed8a1 Mon Sep 17 00:00:00 2001 From: olly Date: Tue, 21 Apr 2020 20:48:04 +0100 Subject: [PATCH] Remove DownloadConstructorHelper Something that helps a constructor always seemed a bit strange. It's now possible to use CacheDataSource.Factory directly instead. PiperOrigin-RevId: 307661930 --- RELEASENOTES.md | 13 +- .../exoplayer2/demo/DemoApplication.java | 22 +-- library/core/proguard-rules.txt | 6 +- .../offline/DefaultDownloaderFactory.java | 26 ++-- .../exoplayer2/offline/DownloadManager.java | 6 +- .../offline/DownloaderConstructorHelper.java | 135 ------------------ .../offline/ProgressiveDownloader.java | 19 +-- .../exoplayer2/offline/SegmentDownloader.java | 15 +- .../upstream/cache/CacheDataSource.java | 50 ++++++- .../offline/DefaultDownloaderFactoryTest.java | 9 +- .../source/dash/offline/DashDownloader.java | 24 ++-- .../dash/offline/DashDownloaderTest.java | 27 ++-- .../dash/offline/DownloadManagerDashTest.java | 12 +- .../dash/offline/DownloadServiceDashTest.java | 12 +- .../source/hls/offline/HlsDownloader.java | 25 ++-- .../source/hls/offline/HlsDownloaderTest.java | 20 +-- .../smoothstreaming/offline/SsDownloader.java | 24 ++-- .../offline/SsDownloaderTest.java | 10 +- .../playbacktests/gts/DashDownloadTest.java | 9 +- 19 files changed, 198 insertions(+), 266 deletions(-) delete mode 100644 library/core/src/main/java/com/google/android/exoplayer2/offline/DownloaderConstructorHelper.java diff --git a/RELEASENOTES.md b/RELEASENOTES.md index df938d8f93..a19275887f 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -60,8 +60,6 @@ `DecoderVideoRenderer` and `DecoderAudioRenderer` respectively, and generalized to work with `Decoder` rather than `SimpleDecoder`. * Add media item based playlist API to Player. - * Update `CachedContentIndex` to use `SecureRandom` for generating the - initialization vector used to encrypt the cache contents. * Remove deprecated members in `DefaultTrackSelector`. * Add `Player.DeviceComponent` and implement it for `SimpleExoPlayer` so that the device volume can be controlled by player. @@ -108,8 +106,15 @@ `OfflineLicenseHelper` ([#7078](https://github.com/google/ExoPlayer/issues/7078)). * Remove generics from DRM components. -* Downloads: Merge downloads in `SegmentDownloader` to improve overall - download speed ([#5978](https://github.com/google/ExoPlayer/issues/5978)). +* Downloads and caching: + * Merge downloads in `SegmentDownloader` to improve overall download + speed ([#5978](https://github.com/google/ExoPlayer/issues/5978)). + * Replace `CacheDataSinkFactory` and `CacheDataSourceFactory` with + `CacheDataSink.Factory` and `CacheDataSource.Factory` respectively. + * Remove `DownloadConstructorHelper` and use `CacheDataSource.Factory` + directly instead. + * Update `CachedContentIndex` to use `SecureRandom` for generating the + initialization vector used to encrypt the cache contents. * DASH: * Merge trick play adaptation sets (i.e., adaptation sets marked with `http://dashif.org/guidelines/trickmode`) into the same `TrackGroup` as diff --git a/demos/main/src/main/java/com/google/android/exoplayer2/demo/DemoApplication.java b/demos/main/src/main/java/com/google/android/exoplayer2/demo/DemoApplication.java index bd74eb5c2c..c36d370992 100644 --- a/demos/main/src/main/java/com/google/android/exoplayer2/demo/DemoApplication.java +++ b/demos/main/src/main/java/com/google/android/exoplayer2/demo/DemoApplication.java @@ -22,18 +22,14 @@ import com.google.android.exoplayer2.database.DatabaseProvider; import com.google.android.exoplayer2.database.ExoDatabaseProvider; import com.google.android.exoplayer2.offline.ActionFileUpgradeUtil; import com.google.android.exoplayer2.offline.DefaultDownloadIndex; -import com.google.android.exoplayer2.offline.DefaultDownloaderFactory; import com.google.android.exoplayer2.offline.DownloadManager; -import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.ui.DownloadNotificationHelper; import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory; -import com.google.android.exoplayer2.upstream.FileDataSource; import com.google.android.exoplayer2.upstream.HttpDataSource; import com.google.android.exoplayer2.upstream.cache.Cache; import com.google.android.exoplayer2.upstream.cache.CacheDataSource; -import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory; import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor; import com.google.android.exoplayer2.upstream.cache.SimpleCache; import com.google.android.exoplayer2.util.Log; @@ -131,11 +127,9 @@ public class DemoApplication extends Application { DOWNLOAD_ACTION_FILE, downloadIndex, /* addNewDownloadsAsCompleted= */ false); upgradeActionFile( DOWNLOAD_TRACKER_ACTION_FILE, downloadIndex, /* addNewDownloadsAsCompleted= */ true); - DownloaderConstructorHelper downloaderConstructorHelper = - new DownloaderConstructorHelper(getDownloadCache(), buildHttpDataSourceFactory()); downloadManager = new DownloadManager( - this, downloadIndex, new DefaultDownloaderFactory(downloaderConstructorHelper)); + this, getDatabaseProvider(), getDownloadCache(), buildHttpDataSourceFactory()); downloadTracker = new DownloadTracker(/* context= */ this, buildDataSourceFactory(), downloadManager); } @@ -172,14 +166,12 @@ public class DemoApplication extends Application { return downloadDirectory; } - protected static CacheDataSourceFactory buildReadOnlyCacheDataSource( + protected static CacheDataSource.Factory buildReadOnlyCacheDataSource( DataSource.Factory upstreamFactory, Cache cache) { - return new CacheDataSourceFactory( - cache, - upstreamFactory, - new FileDataSource.Factory(), - /* cacheWriteDataSinkFactory= */ null, - CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR, - /* eventListener= */ null); + return new CacheDataSource.Factory() + .setCache(cache) + .setUpstreamDataSourceFactory(upstreamFactory) + .setCacheWriteDataSinkFactory(null) + .setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR); } } diff --git a/library/core/proguard-rules.txt b/library/core/proguard-rules.txt index 36038b9078..72f2b27849 100644 --- a/library/core/proguard-rules.txt +++ b/library/core/proguard-rules.txt @@ -51,15 +51,15 @@ # Constructors accessed via reflection in DefaultDownloaderFactory -dontnote com.google.android.exoplayer2.source.dash.offline.DashDownloader -keepclassmembers class com.google.android.exoplayer2.source.dash.offline.DashDownloader { - (android.net.Uri, java.util.List, com.google.android.exoplayer2.offline.DownloaderConstructorHelper); + (android.net.Uri, java.util.List, com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory); } -dontnote com.google.android.exoplayer2.source.hls.offline.HlsDownloader -keepclassmembers class com.google.android.exoplayer2.source.hls.offline.HlsDownloader { - (android.net.Uri, java.util.List, com.google.android.exoplayer2.offline.DownloaderConstructorHelper); + (android.net.Uri, java.util.List, com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory); } -dontnote com.google.android.exoplayer2.source.smoothstreaming.offline.SsDownloader -keepclassmembers class com.google.android.exoplayer2.source.smoothstreaming.offline.SsDownloader { - (android.net.Uri, java.util.List, com.google.android.exoplayer2.offline.DownloaderConstructorHelper); + (android.net.Uri, java.util.List, com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory); } # Constructors accessed via reflection in DefaultMediaSourceFactory and DownloadHelper diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/DefaultDownloaderFactory.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/DefaultDownloaderFactory.java index d8126d4736..88699db804 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/DefaultDownloaderFactory.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/DefaultDownloaderFactory.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer2.offline; import android.net.Uri; import androidx.annotation.Nullable; +import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import java.lang.reflect.Constructor; import java.util.List; @@ -32,7 +33,7 @@ public class DefaultDownloaderFactory implements DownloaderFactory { @Nullable private static final Constructor SS_DOWNLOADER_CONSTRUCTOR; static { - Constructor dashDownloaderConstructor = null; + @Nullable Constructor dashDownloaderConstructor = null; try { // LINT.IfChange dashDownloaderConstructor = @@ -43,7 +44,7 @@ public class DefaultDownloaderFactory implements DownloaderFactory { // Expected if the app was built without the DASH module. } DASH_DOWNLOADER_CONSTRUCTOR = dashDownloaderConstructor; - Constructor hlsDownloaderConstructor = null; + @Nullable Constructor hlsDownloaderConstructor = null; try { // LINT.IfChange hlsDownloaderConstructor = @@ -54,7 +55,7 @@ public class DefaultDownloaderFactory implements DownloaderFactory { // Expected if the app was built without the HLS module. } HLS_DOWNLOADER_CONSTRUCTOR = hlsDownloaderConstructor; - Constructor ssDownloaderConstructor = null; + @Nullable Constructor ssDownloaderConstructor = null; try { // LINT.IfChange ssDownloaderConstructor = @@ -68,11 +69,16 @@ public class DefaultDownloaderFactory implements DownloaderFactory { SS_DOWNLOADER_CONSTRUCTOR = ssDownloaderConstructor; } - private final DownloaderConstructorHelper downloaderConstructorHelper; + private final CacheDataSource.Factory cacheDataSourceFactory; - /** @param downloaderConstructorHelper A helper for instantiating downloaders. */ - public DefaultDownloaderFactory(DownloaderConstructorHelper downloaderConstructorHelper) { - this.downloaderConstructorHelper = downloaderConstructorHelper; + /** + * Creates an instance. + * + * @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which + * downloads will be written. + */ + public DefaultDownloaderFactory(CacheDataSource.Factory cacheDataSourceFactory) { + this.cacheDataSourceFactory = cacheDataSourceFactory; } @Override @@ -80,7 +86,7 @@ public class DefaultDownloaderFactory implements DownloaderFactory { switch (request.type) { case DownloadRequest.TYPE_PROGRESSIVE: return new ProgressiveDownloader( - request.uri, request.customCacheKey, downloaderConstructorHelper); + request.uri, request.customCacheKey, cacheDataSourceFactory); case DownloadRequest.TYPE_DASH: return createDownloader(request, DASH_DOWNLOADER_CONSTRUCTOR); case DownloadRequest.TYPE_HLS: @@ -98,7 +104,7 @@ public class DefaultDownloaderFactory implements DownloaderFactory { throw new IllegalStateException("Module missing for: " + request.type); } try { - return constructor.newInstance(request.uri, request.streamKeys, downloaderConstructorHelper); + return constructor.newInstance(request.uri, request.streamKeys, cacheDataSourceFactory); } catch (Exception e) { throw new RuntimeException("Failed to instantiate downloader for: " + request.type, e); } @@ -109,7 +115,7 @@ public class DefaultDownloaderFactory implements DownloaderFactory { try { return clazz .asSubclass(Downloader.class) - .getConstructor(Uri.class, List.class, DownloaderConstructorHelper.class); + .getConstructor(Uri.class, List.class, CacheDataSource.Factory.class); } catch (NoSuchMethodException e) { // The downloader is present, but the expected constructor is missing. throw new RuntimeException("Downloader constructor missing", e); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java index 37247013e3..1e7d226c1c 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java @@ -40,6 +40,7 @@ import com.google.android.exoplayer2.scheduler.RequirementsWatcher; import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource.Factory; import com.google.android.exoplayer2.upstream.cache.Cache; +import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import com.google.android.exoplayer2.upstream.cache.CacheEvictor; import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor; import com.google.android.exoplayer2.util.Assertions; @@ -197,7 +198,10 @@ public final class DownloadManager { this( context, new DefaultDownloadIndex(databaseProvider), - new DefaultDownloaderFactory(new DownloaderConstructorHelper(cache, upstreamFactory))); + new DefaultDownloaderFactory( + new CacheDataSource.Factory() + .setCache(cache) + .setUpstreamDataSourceFactory(upstreamFactory))); } /** 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 deleted file mode 100644 index 1481801249..0000000000 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloaderConstructorHelper.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.android.exoplayer2.offline; - -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.FileDataSource; -import com.google.android.exoplayer2.upstream.cache.Cache; -import com.google.android.exoplayer2.upstream.cache.CacheDataSinkFactory; -import com.google.android.exoplayer2.upstream.cache.CacheDataSource; -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 CacheDataSource.Factory onlineCacheDataSourceFactory; - private final CacheDataSource.Factory offlineCacheDataSourceFactory; - - /** - * @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. - */ - 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 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 FileDataSource.Factory} 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, - DataSource.Factory upstreamFactory, - @Nullable DataSource.Factory cacheReadDataSourceFactory, - @Nullable DataSink.Factory cacheWriteDataSinkFactory, - @Nullable PriorityTaskManager priorityTaskManager) { - 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 FileDataSource.Factory} 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) { - onlineCacheDataSourceFactory = - new CacheDataSource.Factory() - .setCache(cache) - .setUpstreamDataSourceFactory(upstreamFactory) - .setUpstreamPriorityTaskManager(priorityTaskManager) - .setUpstreamPriority(C.PRIORITY_DOWNLOAD) - .setFlags(CacheDataSource.FLAG_BLOCK_ON_CACHE); - offlineCacheDataSourceFactory = - 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 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 4f4114c80f..03e1094596 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 @@ -25,15 +25,7 @@ import com.google.android.exoplayer2.util.PriorityTaskManager; import java.io.IOException; import java.util.concurrent.atomic.AtomicBoolean; -/** - * A downloader for progressive media streams. - * - *

The downloader attempts to download the entire media bytes referenced by a {@link Uri} into a - * cache as defined by {@link DownloaderConstructorHelper}. Callers can use the constructor to - * specify a custom cache key for the downloaded bytes. - * - *

The downloader will avoid downloading already-downloaded media bytes. - */ +/** A downloader for progressive media streams. */ public final class ProgressiveDownloader implements Downloader { private static final int BUFFER_SIZE_BYTES = 128 * 1024; @@ -46,17 +38,18 @@ public final class ProgressiveDownloader implements Downloader { * @param uri Uri of the data to be downloaded. * @param customCacheKey A custom key that uniquely identifies the original stream. Used for cache * indexing. May be null. - * @param constructorHelper A {@link DownloaderConstructorHelper} instance. + * @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the + * download will be written. */ public ProgressiveDownloader( - Uri uri, @Nullable String customCacheKey, DownloaderConstructorHelper constructorHelper) { - this.dataSpec = + Uri uri, @Nullable String customCacheKey, CacheDataSource.Factory cacheDataSourceFactory) { + dataSpec = new DataSpec.Builder() .setUri(uri) .setKey(customCacheKey) .setFlags(DataSpec.FLAG_ALLOW_CACHE_FRAGMENTATION) .build(); - this.dataSource = constructorHelper.createCacheDataSource(); + dataSource = cacheDataSourceFactory.createDataSourceForDownloading(); 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 67bd19bdb6..007fca5b7e 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 @@ -67,7 +67,7 @@ public abstract class SegmentDownloader> impleme private final DataSpec manifestDataSpec; private final CacheDataSource dataSource; - private final CacheDataSource offlineDataSource; + private final CacheDataSource removingDataSource; private final ArrayList streamKeys; private final AtomicBoolean isCanceled; @@ -75,14 +75,15 @@ public abstract class SegmentDownloader> impleme * @param manifestUri The {@link Uri} of the manifest to be downloaded. * @param streamKeys Keys defining which streams in the manifest should be selected for download. * If empty, all streams are downloaded. - * @param constructorHelper A {@link DownloaderConstructorHelper} instance. + * @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the + * download will be written. */ public SegmentDownloader( - Uri manifestUri, List streamKeys, DownloaderConstructorHelper constructorHelper) { + Uri manifestUri, List streamKeys, CacheDataSource.Factory cacheDataSourceFactory) { this.manifestDataSpec = getCompressibleDataSpec(manifestUri); this.streamKeys = new ArrayList<>(streamKeys); - this.dataSource = constructorHelper.createCacheDataSource(); - this.offlineDataSource = constructorHelper.createOfflineCacheDataSource(); + this.dataSource = cacheDataSourceFactory.createDataSourceForDownloading(); + this.removingDataSource = cacheDataSourceFactory.createDataSourceForRemovingDownload(); isCanceled = new AtomicBoolean(); } @@ -176,8 +177,8 @@ public abstract class SegmentDownloader> impleme @Override public final void remove() throws InterruptedException { try { - M manifest = getManifest(offlineDataSource, manifestDataSpec); - List segments = getSegments(offlineDataSource, manifest, true); + M manifest = getManifest(removingDataSource, manifestDataSpec); + List segments = getSegments(removingDataSource, manifest, true); for (int i = 0; i < segments.size(); i++) { removeDataSpec(segments.get(i).dataSpec); } 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 d42d72089d..c316d75501 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 @@ -207,12 +207,54 @@ public final class CacheDataSource implements DataSource { @Override public CacheDataSource createDataSource() { + return createDataSourceInternal( + upstreamDataSourceFactory != null ? upstreamDataSourceFactory.createDataSource() : null, + flags, + upstreamPriority); + } + + /** + * Returns an instance suitable for downloading content. The created instance is equivalent to + * one that would be created by {@link #createDataSource()}, except: + * + *

    + *
  • The {@link #FLAG_BLOCK_ON_CACHE} is always set. + *
  • The task priority is overridden to be {@link C#PRIORITY_DOWNLOAD}. + *
+ * + * @return An instance suitable for downloading content. + */ + public CacheDataSource createDataSourceForDownloading() { + return createDataSourceInternal( + upstreamDataSourceFactory != null ? upstreamDataSourceFactory.createDataSource() : null, + flags | FLAG_BLOCK_ON_CACHE, + C.PRIORITY_DOWNLOAD); + } + + /** + * Returns an instance suitable for reading cached content as part of removing a download. The + * created instance is equivalent to one that would be created by {@link #createDataSource()}, + * except: + * + *
    + *
  • The upstream is overridden to be {@code null}, since when removing content we don't + * want to request anything that's not already cached. + *
  • The {@link #FLAG_BLOCK_ON_CACHE} is always set. + *
  • The task priority is overridden to be {@link C#PRIORITY_DOWNLOAD}. + *
+ * + * @return An instance suitable for reading cached content as part of removing a download. + */ + public CacheDataSource createDataSourceForRemovingDownload() { + return createDataSourceInternal( + /* upstreamDataSource= */ null, flags | FLAG_BLOCK_ON_CACHE, C.PRIORITY_DOWNLOAD); + } + + private CacheDataSource createDataSourceInternal( + @Nullable DataSource upstreamDataSource, @Flags int flags, int upstreamPriority) { Cache cache = Assertions.checkNotNull(this.cache); - @Nullable - DataSource upstreamDataSource = - upstreamDataSourceFactory != null ? upstreamDataSourceFactory.createDataSource() : null; @Nullable DataSink cacheWriteDataSink; - if (cacheIsReadOnly) { + if (cacheIsReadOnly || upstreamDataSource == null) { cacheWriteDataSink = null; } else if (cacheWriteDataSinkFactory != null) { cacheWriteDataSink = cacheWriteDataSinkFactory.createDataSink(); diff --git a/library/core/src/test/java/com/google/android/exoplayer2/offline/DefaultDownloaderFactoryTest.java b/library/core/src/test/java/com/google/android/exoplayer2/offline/DefaultDownloaderFactoryTest.java index c3d23c7d22..5955a9491e 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/offline/DefaultDownloaderFactoryTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/offline/DefaultDownloaderFactoryTest.java @@ -21,6 +21,7 @@ import android.net.Uri; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.android.exoplayer2.upstream.DummyDataSource; import com.google.android.exoplayer2.upstream.cache.Cache; +import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import java.util.Collections; import org.junit.Test; import org.junit.runner.RunWith; @@ -32,9 +33,11 @@ public final class DefaultDownloaderFactoryTest { @Test public void createProgressiveDownloader() throws Exception { - DownloaderConstructorHelper constructorHelper = - new DownloaderConstructorHelper(Mockito.mock(Cache.class), DummyDataSource.FACTORY); - DownloaderFactory factory = new DefaultDownloaderFactory(constructorHelper); + CacheDataSource.Factory cacheDataSourceFactory = + new CacheDataSource.Factory() + .setCache(Mockito.mock(Cache.class)) + .setUpstreamDataSourceFactory(DummyDataSource.FACTORY); + DownloaderFactory factory = new DefaultDownloaderFactory(cacheDataSourceFactory); Downloader downloader = factory.createDownloader( diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/offline/DashDownloader.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/offline/DashDownloader.java index 7f76e65a42..29fc28ab8d 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/offline/DashDownloader.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/offline/DashDownloader.java @@ -20,7 +20,6 @@ import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.extractor.ChunkIndex; import com.google.android.exoplayer2.offline.DownloadException; -import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.SegmentDownloader; import com.google.android.exoplayer2.offline.StreamKey; import com.google.android.exoplayer2.source.dash.DashSegmentIndex; @@ -35,6 +34,7 @@ import com.google.android.exoplayer2.source.dash.manifest.Representation; import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.ParsingLoadable; +import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -46,19 +46,20 @@ import java.util.List; * *
{@code
  * SimpleCache cache = new SimpleCache(downloadFolder, new NoOpCacheEvictor(), databaseProvider);
- * DefaultHttpDataSourceFactory factory = new DefaultHttpDataSourceFactory("ExoPlayer", null);
- * DownloaderConstructorHelper constructorHelper =
- *     new DownloaderConstructorHelper(cache, factory);
+ * CacheDataSource.Factory cacheDataSourceFactory =
+ *     new CacheDataSource.Factory()
+ *         .setCache(cache)
+ *         .setUpstreamDataSourceFactory(new DefaultHttpDataSourceFactory(userAgent));
  * // Create a downloader for the first representation of the first adaptation set of the first
  * // period.
  * DashDownloader dashDownloader =
  *     new DashDownloader(
- *         manifestUrl, Collections.singletonList(new StreamKey(0, 0, 0)), constructorHelper);
+ *         manifestUrl, Collections.singletonList(new StreamKey(0, 0, 0)), cacheDataSourceFactory);
  * // Perform the download.
  * dashDownloader.download(progressListener);
- * // Access downloaded data using CacheDataSource
- * CacheDataSource cacheDataSource =
- *     new CacheDataSource(cache, factory.createDataSource(), CacheDataSource.FLAG_BLOCK_ON_CACHE);
+ * // Use the downloaded data for playback.
+ * DashMediaSource mediaSource =
+ *     new DashMediaSource.Factory(cacheDataSourceFactory).createMediaSource(mediaItem);
  * }
*/ public final class DashDownloader extends SegmentDownloader { @@ -67,11 +68,12 @@ public final class DashDownloader extends SegmentDownloader { * @param manifestUri The {@link Uri} of the manifest to be downloaded. * @param streamKeys Keys defining which representations in the manifest should be selected for * download. If empty, all representations are downloaded. - * @param constructorHelper A {@link DownloaderConstructorHelper} instance. + * @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the + * download will be written. */ public DashDownloader( - Uri manifestUri, List streamKeys, DownloaderConstructorHelper constructorHelper) { - super(manifestUri, streamKeys, constructorHelper); + Uri manifestUri, List streamKeys, CacheDataSource.Factory cacheDataSourceFactory) { + super(manifestUri, streamKeys, cacheDataSourceFactory); } @Override diff --git a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DashDownloaderTest.java b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DashDownloaderTest.java index fc99e20898..49e111b7a7 100644 --- a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DashDownloaderTest.java +++ b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DashDownloaderTest.java @@ -32,17 +32,16 @@ import com.google.android.exoplayer2.offline.DefaultDownloaderFactory; import com.google.android.exoplayer2.offline.DownloadException; import com.google.android.exoplayer2.offline.DownloadRequest; import com.google.android.exoplayer2.offline.Downloader; -import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.DownloaderFactory; import com.google.android.exoplayer2.offline.StreamKey; import com.google.android.exoplayer2.testutil.CacheAsserts.RequestSet; import com.google.android.exoplayer2.testutil.FakeDataSet; import com.google.android.exoplayer2.testutil.FakeDataSource; -import com.google.android.exoplayer2.testutil.FakeDataSource.Factory; import com.google.android.exoplayer2.testutil.TestUtil; import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DummyDataSource; import com.google.android.exoplayer2.upstream.cache.Cache; +import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor; import com.google.android.exoplayer2.upstream.cache.SimpleCache; import com.google.android.exoplayer2.util.Util; @@ -81,9 +80,11 @@ public class DashDownloaderTest { @Test public void createWithDefaultDownloaderFactory() { - DownloaderConstructorHelper constructorHelper = - new DownloaderConstructorHelper(Mockito.mock(Cache.class), DummyDataSource.FACTORY); - DownloaderFactory factory = new DefaultDownloaderFactory(constructorHelper); + CacheDataSource.Factory cacheDataSourceFactory = + new CacheDataSource.Factory() + .setCache(Mockito.mock(Cache.class)) + .setUpstreamDataSourceFactory(DummyDataSource.FACTORY); + DownloaderFactory factory = new DefaultDownloaderFactory(cacheDataSourceFactory); Downloader downloader = factory.createDownloader( @@ -184,7 +185,7 @@ public class DashDownloaderTest { .setRandomData("text_segment_2", 2) .setRandomData("text_segment_3", 3); FakeDataSource fakeDataSource = new FakeDataSource(fakeDataSet); - Factory factory = mock(Factory.class); + FakeDataSource.Factory factory = mock(FakeDataSource.Factory.class); when(factory.createDataSource()).thenReturn(fakeDataSource); DashDownloader dashDownloader = @@ -216,7 +217,7 @@ public class DashDownloaderTest { .setRandomData("period_2_segment_2", 2) .setRandomData("period_2_segment_3", 3); FakeDataSource fakeDataSource = new FakeDataSource(fakeDataSet); - Factory factory = mock(Factory.class); + FakeDataSource.Factory factory = mock(FakeDataSource.Factory.class); when(factory.createDataSource()).thenReturn(fakeDataSource); DashDownloader dashDownloader = @@ -327,12 +328,16 @@ public class DashDownloaderTest { } private DashDownloader getDashDownloader(FakeDataSet fakeDataSet, StreamKey... keys) { - return getDashDownloader(new Factory().setFakeDataSet(fakeDataSet), keys); + return getDashDownloader(new FakeDataSource.Factory().setFakeDataSet(fakeDataSet), keys); } - private DashDownloader getDashDownloader(Factory factory, StreamKey... keys) { - return new DashDownloader( - TEST_MPD_URI, keysList(keys), new DownloaderConstructorHelper(cache, factory)); + private DashDownloader getDashDownloader( + FakeDataSource.Factory upstreamDataSourceFactory, StreamKey... keys) { + CacheDataSource.Factory cacheDataSourceFactory = + new CacheDataSource.Factory() + .setCache(cache) + .setUpstreamDataSourceFactory(upstreamDataSourceFactory); + return new DashDownloader(TEST_MPD_URI, keysList(keys), cacheDataSourceFactory); } private static ArrayList keysList(StreamKey... keys) { diff --git a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DownloadManagerDashTest.java b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DownloadManagerDashTest.java index 89426f753d..164299fb06 100644 --- a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DownloadManagerDashTest.java +++ b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DownloadManagerDashTest.java @@ -29,7 +29,6 @@ import com.google.android.exoplayer2.offline.DefaultDownloadIndex; import com.google.android.exoplayer2.offline.DefaultDownloaderFactory; import com.google.android.exoplayer2.offline.DownloadManager; import com.google.android.exoplayer2.offline.DownloadRequest; -import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.StreamKey; import com.google.android.exoplayer2.scheduler.Requirements; import com.google.android.exoplayer2.testutil.CacheAsserts.RequestSet; @@ -40,6 +39,7 @@ import com.google.android.exoplayer2.testutil.FakeDataSource; import com.google.android.exoplayer2.testutil.TestDownloadManagerListener; import com.google.android.exoplayer2.testutil.TestUtil; import com.google.android.exoplayer2.upstream.DataSource.Factory; +import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor; import com.google.android.exoplayer2.upstream.cache.SimpleCache; import com.google.android.exoplayer2.util.Util; @@ -253,12 +253,14 @@ public class DownloadManagerDashTest { runOnMainThread( () -> { Factory fakeDataSourceFactory = new FakeDataSource.Factory().setFakeDataSet(fakeDataSet); + DefaultDownloaderFactory downloaderFactory = + new DefaultDownloaderFactory( + new CacheDataSource.Factory() + .setCache(cache) + .setUpstreamDataSourceFactory(fakeDataSourceFactory)); downloadManager = new DownloadManager( - ApplicationProvider.getApplicationContext(), - downloadIndex, - new DefaultDownloaderFactory( - new DownloaderConstructorHelper(cache, fakeDataSourceFactory))); + ApplicationProvider.getApplicationContext(), downloadIndex, downloaderFactory); downloadManager.setRequirements(new Requirements(0)); downloadManagerListener = diff --git a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DownloadServiceDashTest.java b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DownloadServiceDashTest.java index 0bf5089117..42b0a2e7c2 100644 --- a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DownloadServiceDashTest.java +++ b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DownloadServiceDashTest.java @@ -33,7 +33,6 @@ import com.google.android.exoplayer2.offline.Download; import com.google.android.exoplayer2.offline.DownloadManager; import com.google.android.exoplayer2.offline.DownloadRequest; import com.google.android.exoplayer2.offline.DownloadService; -import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.StreamKey; import com.google.android.exoplayer2.scheduler.Scheduler; import com.google.android.exoplayer2.testutil.DummyMainThread; @@ -42,6 +41,7 @@ import com.google.android.exoplayer2.testutil.FakeDataSource; import com.google.android.exoplayer2.testutil.TestDownloadManagerListener; import com.google.android.exoplayer2.testutil.TestUtil; import com.google.android.exoplayer2.upstream.DataSource; +import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor; import com.google.android.exoplayer2.upstream.cache.SimpleCache; import com.google.android.exoplayer2.util.ConditionVariable; @@ -113,12 +113,14 @@ public class DownloadServiceDashTest { () -> { DefaultDownloadIndex downloadIndex = new DefaultDownloadIndex(TestUtil.getInMemoryDatabaseProvider()); + DefaultDownloaderFactory downloaderFactory = + new DefaultDownloaderFactory( + new CacheDataSource.Factory() + .setCache(cache) + .setUpstreamDataSourceFactory(fakeDataSourceFactory)); final DownloadManager dashDownloadManager = new DownloadManager( - ApplicationProvider.getApplicationContext(), - downloadIndex, - new DefaultDownloaderFactory( - new DownloaderConstructorHelper(cache, fakeDataSourceFactory))); + ApplicationProvider.getApplicationContext(), downloadIndex, downloaderFactory); downloadManagerListener = new TestDownloadManagerListener(dashDownloadManager, dummyMainThread); dashDownloadManager.resumeDownloads(); diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/offline/HlsDownloader.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/offline/HlsDownloader.java index d172aa299c..43a393398b 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/offline/HlsDownloader.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/offline/HlsDownloader.java @@ -17,7 +17,6 @@ package com.google.android.exoplayer2.source.hls.offline; import android.net.Uri; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.SegmentDownloader; import com.google.android.exoplayer2.offline.StreamKey; import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist; @@ -27,6 +26,7 @@ import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistParser; import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.ParsingLoadable; +import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import com.google.android.exoplayer2.util.UriUtil; import java.io.IOException; import java.util.ArrayList; @@ -40,20 +40,20 @@ import java.util.List; * *
{@code
  * SimpleCache cache = new SimpleCache(downloadFolder, new NoOpCacheEvictor(), databaseProvider);
- * DefaultHttpDataSourceFactory factory = new DefaultHttpDataSourceFactory("ExoPlayer", null);
- * DownloaderConstructorHelper constructorHelper =
- *     new DownloaderConstructorHelper(cache, factory);
+ * CacheDataSource.Factory cacheDataSourceFactory =
+ *     new CacheDataSource.Factory()
+ *         .setCache(cache)
+ *         .setUpstreamDataSourceFactory(new DefaultHttpDataSourceFactory(userAgent));
  * // Create a downloader for the first variant in a master playlist.
  * HlsDownloader hlsDownloader =
  *     new HlsDownloader(
  *         playlistUri,
- *         Collections.singletonList(new StreamKey(HlsMasterPlaylist.GROUP_INDEX_VARIANT, 0)),
- *         constructorHelper);
+ *         Collections.singletonList(new StreamKey(HlsMasterPlaylist.GROUP_INDEX_VARIANT, 0));
  * // Perform the download.
  * hlsDownloader.download(progressListener);
- * // Access downloaded data using CacheDataSource
- * CacheDataSource cacheDataSource =
- *     new CacheDataSource(cache, factory.createDataSource(), CacheDataSource.FLAG_BLOCK_ON_CACHE);
+ * // Use the downloaded data for playback.
+ * HlsMediaSource mediaSource =
+ *     new HlsMediaSource.Factory(cacheDataSourceFactory).createMediaSource(mediaItem);
  * }
*/ public final class HlsDownloader extends SegmentDownloader { @@ -62,11 +62,12 @@ public final class HlsDownloader extends SegmentDownloader { * @param playlistUri The {@link Uri} of the playlist to be downloaded. * @param streamKeys Keys defining which renditions in the playlist should be selected for * download. If empty, all renditions are downloaded. - * @param constructorHelper A {@link DownloaderConstructorHelper} instance. + * @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the + * download will be written. */ public HlsDownloader( - Uri playlistUri, List streamKeys, DownloaderConstructorHelper constructorHelper) { - super(playlistUri, streamKeys, constructorHelper); + Uri playlistUri, List streamKeys, CacheDataSource.Factory cacheDataSourceFactory) { + super(playlistUri, streamKeys, cacheDataSourceFactory); } @Override diff --git a/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/offline/HlsDownloaderTest.java b/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/offline/HlsDownloaderTest.java index a8473b8c9c..0dcae17f74 100644 --- a/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/offline/HlsDownloaderTest.java +++ b/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/offline/HlsDownloaderTest.java @@ -40,15 +40,15 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.android.exoplayer2.offline.DefaultDownloaderFactory; import com.google.android.exoplayer2.offline.DownloadRequest; import com.google.android.exoplayer2.offline.Downloader; -import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.DownloaderFactory; import com.google.android.exoplayer2.offline.StreamKey; import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist; import com.google.android.exoplayer2.testutil.CacheAsserts.RequestSet; import com.google.android.exoplayer2.testutil.FakeDataSet; -import com.google.android.exoplayer2.testutil.FakeDataSource.Factory; +import com.google.android.exoplayer2.testutil.FakeDataSource; import com.google.android.exoplayer2.upstream.DummyDataSource; import com.google.android.exoplayer2.upstream.cache.Cache; +import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor; import com.google.android.exoplayer2.upstream.cache.SimpleCache; import com.google.android.exoplayer2.util.Util; @@ -97,9 +97,11 @@ public class HlsDownloaderTest { @Test public void createWithDefaultDownloaderFactory() { - DownloaderConstructorHelper constructorHelper = - new DownloaderConstructorHelper(Mockito.mock(Cache.class), DummyDataSource.FACTORY); - DownloaderFactory factory = new DefaultDownloaderFactory(constructorHelper); + CacheDataSource.Factory cacheDataSourceFactory = + new CacheDataSource.Factory() + .setCache(Mockito.mock(Cache.class)) + .setUpstreamDataSourceFactory(DummyDataSource.FACTORY); + DownloaderFactory factory = new DefaultDownloaderFactory(cacheDataSourceFactory); Downloader downloader = factory.createDownloader( @@ -213,9 +215,11 @@ public class HlsDownloaderTest { } private HlsDownloader getHlsDownloader(String mediaPlaylistUri, List keys) { - Factory factory = new Factory().setFakeDataSet(fakeDataSet); - return new HlsDownloader( - Uri.parse(mediaPlaylistUri), keys, new DownloaderConstructorHelper(cache, factory)); + CacheDataSource.Factory cacheDataSourceFactory = + new CacheDataSource.Factory() + .setCache(cache) + .setUpstreamDataSourceFactory(new FakeDataSource.Factory().setFakeDataSet(fakeDataSet)); + return new HlsDownloader(Uri.parse(mediaPlaylistUri), keys, cacheDataSourceFactory); } private static ArrayList getKeys(int... variantIndices) { diff --git a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloader.java b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloader.java index 1331fe4617..0eb2cdafcb 100644 --- a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloader.java +++ b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloader.java @@ -17,7 +17,6 @@ package com.google.android.exoplayer2.source.smoothstreaming.offline; import android.net.Uri; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.SegmentDownloader; import com.google.android.exoplayer2.offline.StreamKey; import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest; @@ -27,6 +26,7 @@ import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsUtil; import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.ParsingLoadable; +import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -38,20 +38,21 @@ import java.util.List; * *
{@code
  * SimpleCache cache = new SimpleCache(downloadFolder, new NoOpCacheEvictor(), databaseProvider);
- * DefaultHttpDataSourceFactory factory = new DefaultHttpDataSourceFactory("ExoPlayer", null);
- * DownloaderConstructorHelper constructorHelper =
- *     new DownloaderConstructorHelper(cache, factory);
+ * CacheDataSource.Factory cacheDataSourceFactory =
+ *     new CacheDataSource.Factory()
+ *         .setCache(cache)
+ *         .setUpstreamDataSourceFactory(new DefaultHttpDataSourceFactory(userAgent));
  * // Create a downloader for the first track of the first stream element.
  * SsDownloader ssDownloader =
  *     new SsDownloader(
  *         manifestUrl,
  *         Collections.singletonList(new StreamKey(0, 0)),
- *         constructorHelper);
+ *         cacheDataSourceFactory);
  * // Perform the download.
  * ssDownloader.download(progressListener);
- * // Access downloaded data using CacheDataSource
- * CacheDataSource cacheDataSource =
- *     new CacheDataSource(cache, factory.createDataSource(), CacheDataSource.FLAG_BLOCK_ON_CACHE);
+ * // Use the downloaded data for playback.
+ * SsMediaSource mediaSource =
+ *     new SsMediaSource.Factory(cacheDataSourceFactory).createMediaSource(mediaItem);
  * }
*/ public final class SsDownloader extends SegmentDownloader { @@ -60,11 +61,12 @@ public final class SsDownloader extends SegmentDownloader { * @param manifestUri The {@link Uri} of the manifest to be downloaded. * @param streamKeys Keys defining which streams in the manifest should be selected for download. * If empty, all streams are downloaded. - * @param constructorHelper A {@link DownloaderConstructorHelper} instance. + * @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the + * download will be written. */ public SsDownloader( - Uri manifestUri, List streamKeys, DownloaderConstructorHelper constructorHelper) { - super(SsUtil.fixManifestUri(manifestUri), streamKeys, constructorHelper); + Uri manifestUri, List streamKeys, CacheDataSource.Factory cacheDataSourceFactory) { + super(SsUtil.fixManifestUri(manifestUri), streamKeys, cacheDataSourceFactory); } @Override diff --git a/library/smoothstreaming/src/test/java/com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloaderTest.java b/library/smoothstreaming/src/test/java/com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloaderTest.java index 5560a724c8..1bbe0b191d 100644 --- a/library/smoothstreaming/src/test/java/com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloaderTest.java +++ b/library/smoothstreaming/src/test/java/com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloaderTest.java @@ -22,11 +22,11 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.android.exoplayer2.offline.DefaultDownloaderFactory; import com.google.android.exoplayer2.offline.DownloadRequest; import com.google.android.exoplayer2.offline.Downloader; -import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.DownloaderFactory; import com.google.android.exoplayer2.offline.StreamKey; import com.google.android.exoplayer2.upstream.DummyDataSource; import com.google.android.exoplayer2.upstream.cache.Cache; +import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import java.util.Collections; import org.junit.Test; import org.junit.runner.RunWith; @@ -38,9 +38,11 @@ public final class SsDownloaderTest { @Test public void createWithDefaultDownloaderFactory() throws Exception { - DownloaderConstructorHelper constructorHelper = - new DownloaderConstructorHelper(Mockito.mock(Cache.class), DummyDataSource.FACTORY); - DownloaderFactory factory = new DefaultDownloaderFactory(constructorHelper); + CacheDataSource.Factory cacheDataSourceFactory = + new CacheDataSource.Factory() + .setCache(Mockito.mock(Cache.class)) + .setUpstreamDataSourceFactory(DummyDataSource.FACTORY); + DownloaderFactory factory = new DefaultDownloaderFactory(cacheDataSourceFactory); Downloader downloader = factory.createDownloader( diff --git a/playbacktests/src/androidTest/java/com/google/android/exoplayer2/playbacktests/gts/DashDownloadTest.java b/playbacktests/src/androidTest/java/com/google/android/exoplayer2/playbacktests/gts/DashDownloadTest.java index c2e14ab5d2..596a2fe603 100644 --- a/playbacktests/src/androidTest/java/com/google/android/exoplayer2/playbacktests/gts/DashDownloadTest.java +++ b/playbacktests/src/androidTest/java/com/google/android/exoplayer2/playbacktests/gts/DashDownloadTest.java @@ -20,7 +20,6 @@ import static com.google.common.truth.Truth.assertWithMessage; import android.net.Uri; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.rule.ActivityTestRule; -import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.StreamKey; import com.google.android.exoplayer2.source.dash.DashUtil; import com.google.android.exoplayer2.source.dash.manifest.AdaptationSet; @@ -120,9 +119,11 @@ public final class DashDownloadTest { } } } - DownloaderConstructorHelper constructorHelper = - new DownloaderConstructorHelper(cache, httpDataSourceFactory); - return new DashDownloader(MANIFEST_URI, keys, constructorHelper); + CacheDataSource.Factory cacheDataSourceFactory = + new CacheDataSource.Factory() + .setCache(cache) + .setUpstreamDataSourceFactory(httpDataSourceFactory); + return new DashDownloader(MANIFEST_URI, keys, cacheDataSourceFactory); } }