Commit 314bc65d by olly Committed by Oliver Woodman

Enable download parallelisation in demo app

- Deprecate constructors that don't take an executor, to direct
  developers toward the new ones. Callers can trivially pass
  Runnable::run to one of the new ones if they want old behaviour.
- Add comment explaining warning suppression added in the CL that
  added parallelised download support.

Issue: #5978
PiperOrigin-RevId: 318803296
parent 2eab6802
...@@ -145,7 +145,10 @@ ...@@ -145,7 +145,10 @@
([#7078](https://github.com/google/ExoPlayer/issues/7078)). ([#7078](https://github.com/google/ExoPlayer/issues/7078)).
* Remove generics from DRM components. * Remove generics from DRM components.
* Downloads and caching: * Downloads and caching:
* Merge downloads in `SegmentDownloader` to improve overall download speed * Support passing an `Executor` to `DefaultDownloaderFactory` on which
data downloads are performed.
* Parallelize and merge downloads in `SegmentDownloader` to improve
overall download speed
([#5978](https://github.com/google/ExoPlayer/issues/5978)). ([#5978](https://github.com/google/ExoPlayer/issues/5978)).
* Support multiple non-overlapping write locks for the same key in * Support multiple non-overlapping write locks for the same key in
`SimpleCache`. `SimpleCache`.
......
...@@ -36,6 +36,7 @@ import com.google.android.exoplayer2.util.Log; ...@@ -36,6 +36,7 @@ import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.Executors;
/** /**
* Placeholder application to facilitate overriding Application methods for debugging and testing. * Placeholder application to facilitate overriding Application methods for debugging and testing.
...@@ -129,7 +130,11 @@ public class DemoApplication extends MultiDexApplication { ...@@ -129,7 +130,11 @@ public class DemoApplication extends MultiDexApplication {
DOWNLOAD_TRACKER_ACTION_FILE, downloadIndex, /* addNewDownloadsAsCompleted= */ true); DOWNLOAD_TRACKER_ACTION_FILE, downloadIndex, /* addNewDownloadsAsCompleted= */ true);
downloadManager = downloadManager =
new DownloadManager( new DownloadManager(
this, getDatabaseProvider(), getDownloadCache(), buildHttpDataSourceFactory()); this,
getDatabaseProvider(),
getDownloadCache(),
buildHttpDataSourceFactory(),
Executors.newFixedThreadPool(/* nThreads= */ 6));
downloadTracker = downloadTracker =
new DownloadTracker(/* context= */ this, buildDataSourceFactory(), downloadManager); new DownloadTracker(/* context= */ this, buildDataSourceFactory(), downloadManager);
} }
......
...@@ -79,7 +79,9 @@ public class DefaultDownloaderFactory implements DownloaderFactory { ...@@ -79,7 +79,9 @@ public class DefaultDownloaderFactory implements DownloaderFactory {
* *
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which * @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which
* downloads will be written. * downloads will be written.
* @deprecated Use {@link #DefaultDownloaderFactory(CacheDataSource.Factory, Executor)}.
*/ */
@Deprecated
public DefaultDownloaderFactory(CacheDataSource.Factory cacheDataSourceFactory) { public DefaultDownloaderFactory(CacheDataSource.Factory cacheDataSourceFactory) {
this(cacheDataSourceFactory, Runnable::run); this(cacheDataSourceFactory, Runnable::run);
} }
...@@ -89,9 +91,10 @@ public class DefaultDownloaderFactory implements DownloaderFactory { ...@@ -89,9 +91,10 @@ public class DefaultDownloaderFactory implements DownloaderFactory {
* *
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which * @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which
* downloads will be written. * downloads will be written.
* @param executor An {@link Executor} used to make requests for media being downloaded. Providing * @param executor An {@link Executor} used to download data. Passing {@code Runnable::run} will
* an {@link Executor} that uses multiple threads will speed up download tasks that can be * cause each download task to download data on its own thread. Passing an {@link Executor}
* split into smaller parts for parallel execution. * that uses multiple threads will speed up download tasks that can be split into smaller
* parts for parallel execution.
*/ */
public DefaultDownloaderFactory( public DefaultDownloaderFactory(
CacheDataSource.Factory cacheDataSourceFactory, Executor executor) { CacheDataSource.Factory cacheDataSourceFactory, Executor executor) {
......
...@@ -52,6 +52,7 @@ import java.util.Collections; ...@@ -52,6 +52,7 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.Executor;
/** /**
* Manages downloads. * Manages downloads.
...@@ -197,16 +198,42 @@ public final class DownloadManager { ...@@ -197,16 +198,42 @@ public final class DownloadManager {
* an {@link CacheEvictor} that will not evict downloaded content, for example {@link * an {@link CacheEvictor} that will not evict downloaded content, for example {@link
* NoOpCacheEvictor}. * NoOpCacheEvictor}.
* @param upstreamFactory A {@link Factory} for creating {@link DataSource}s for downloading data. * @param upstreamFactory A {@link Factory} for creating {@link DataSource}s for downloading data.
* @deprecated Use {@link #DownloadManager(Context, DatabaseProvider, Cache, Factory, Executor)}.
*/ */
@Deprecated
public DownloadManager( public DownloadManager(
Context context, DatabaseProvider databaseProvider, Cache cache, Factory upstreamFactory) { Context context, DatabaseProvider databaseProvider, Cache cache, Factory upstreamFactory) {
this(context, databaseProvider, cache, upstreamFactory, Runnable::run);
}
/**
* Constructs a {@link DownloadManager}.
*
* @param context Any context.
* @param databaseProvider Provides the SQLite database in which downloads are persisted.
* @param cache A cache to be used to store downloaded data. The cache should be configured with
* an {@link CacheEvictor} that will not evict downloaded content, for example {@link
* NoOpCacheEvictor}.
* @param upstreamFactory A {@link Factory} for creating {@link DataSource}s for downloading data.
* @param executor An {@link Executor} used to download data. Passing {@code Runnable::run} will
* cause each download task to download data on its own thread. Passing an {@link Executor}
* that uses multiple threads will speed up download tasks that can be split into smaller
* parts for parallel execution.
*/
public DownloadManager(
Context context,
DatabaseProvider databaseProvider,
Cache cache,
Factory upstreamFactory,
Executor executor) {
this( this(
context, context,
new DefaultDownloadIndex(databaseProvider), new DefaultDownloadIndex(databaseProvider),
new DefaultDownloaderFactory( new DefaultDownloaderFactory(
new CacheDataSource.Factory() new CacheDataSource.Factory()
.setCache(cache) .setCache(cache)
.setUpstreamDataSourceFactory(upstreamFactory))); .setUpstreamDataSourceFactory(upstreamFactory),
executor));
} }
/** /**
......
...@@ -159,6 +159,8 @@ public abstract class RunnableFutureTask<R, E extends Exception> implements Runn ...@@ -159,6 +159,8 @@ public abstract class RunnableFutureTask<R, E extends Exception> implements Runn
// Do nothing. // Do nothing.
} }
// The return value is guaranteed to be non-null if and only if R is a non-null type, but there's
// no way to assert this. Suppress the warning instead.
@SuppressWarnings("return.type.incompatible") @SuppressWarnings("return.type.incompatible")
@UnknownNull @UnknownNull
private R getResult() throws ExecutionException { private R getResult() throws ExecutionException {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment