Better tie injection of Cache/CacheDataSource/CacheKeyFactory

PiperOrigin-RevId: 307056661
This commit is contained in:
olly 2020-04-17 17:22:39 +01:00 committed by Oliver Woodman
parent 704993ce7c
commit 7ea83d7167
6 changed files with 18 additions and 45 deletions

View File

@ -28,14 +28,11 @@ 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.upstream.cache.CacheDataSourceFactory; import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory;
import com.google.android.exoplayer2.upstream.cache.CacheKeyFactory; import com.google.android.exoplayer2.upstream.cache.CacheKeyFactory;
import com.google.android.exoplayer2.upstream.cache.CacheUtil;
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;
@Nullable private final CacheKeyFactory cacheKeyFactory;
@Nullable private final PriorityTaskManager priorityTaskManager; @Nullable private final PriorityTaskManager priorityTaskManager;
private final CacheDataSourceFactory onlineCacheDataSourceFactory; private final CacheDataSourceFactory onlineCacheDataSourceFactory;
private final CacheDataSourceFactory offlineCacheDataSourceFactory; private final CacheDataSourceFactory offlineCacheDataSourceFactory;
@ -133,19 +130,7 @@ public final class DownloaderConstructorHelper {
CacheDataSource.FLAG_BLOCK_ON_CACHE, CacheDataSource.FLAG_BLOCK_ON_CACHE,
/* eventListener= */ null, /* eventListener= */ null,
cacheKeyFactory); cacheKeyFactory);
this.cache = cache;
this.priorityTaskManager = priorityTaskManager; this.priorityTaskManager = priorityTaskManager;
this.cacheKeyFactory = cacheKeyFactory;
}
/** Returns the {@link Cache} instance. */
public Cache getCache() {
return cache;
}
/** Returns the {@link CacheKeyFactory}. */
public CacheKeyFactory getCacheKeyFactory() {
return cacheKeyFactory != null ? cacheKeyFactory : CacheUtil.DEFAULT_CACHE_KEY_FACTORY;
} }
/** Returns a {@link PriorityTaskManager} instance. */ /** Returns a {@link PriorityTaskManager} instance. */

View File

@ -19,9 +19,7 @@ import android.net.Uri;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.cache.Cache;
import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
import com.google.android.exoplayer2.upstream.cache.CacheKeyFactory;
import com.google.android.exoplayer2.upstream.cache.CacheUtil; import com.google.android.exoplayer2.upstream.cache.CacheUtil;
import com.google.android.exoplayer2.util.PriorityTaskManager; import com.google.android.exoplayer2.util.PriorityTaskManager;
import java.io.IOException; import java.io.IOException;
@ -41,9 +39,7 @@ public final class ProgressiveDownloader implements Downloader {
private static final int BUFFER_SIZE_BYTES = 128 * 1024; private static final int BUFFER_SIZE_BYTES = 128 * 1024;
private final DataSpec dataSpec; private final DataSpec dataSpec;
private final Cache cache;
private final CacheDataSource dataSource; private final CacheDataSource dataSource;
private final CacheKeyFactory cacheKeyFactory;
private final PriorityTaskManager priorityTaskManager; private final PriorityTaskManager priorityTaskManager;
private final AtomicBoolean isCanceled; private final AtomicBoolean isCanceled;
@ -61,9 +57,7 @@ public final class ProgressiveDownloader implements Downloader {
.setKey(customCacheKey) .setKey(customCacheKey)
.setFlags(DataSpec.FLAG_ALLOW_CACHE_FRAGMENTATION) .setFlags(DataSpec.FLAG_ALLOW_CACHE_FRAGMENTATION)
.build(); .build();
this.cache = constructorHelper.getCache();
this.dataSource = constructorHelper.createCacheDataSource(); this.dataSource = constructorHelper.createCacheDataSource();
this.cacheKeyFactory = constructorHelper.getCacheKeyFactory();
this.priorityTaskManager = constructorHelper.getPriorityTaskManager(); this.priorityTaskManager = constructorHelper.getPriorityTaskManager();
isCanceled = new AtomicBoolean(); isCanceled = new AtomicBoolean();
} }
@ -75,8 +69,6 @@ public final class ProgressiveDownloader implements Downloader {
try { try {
CacheUtil.cache( CacheUtil.cache(
dataSpec, dataSpec,
cache,
cacheKeyFactory,
dataSource, dataSource,
new byte[BUFFER_SIZE_BYTES], new byte[BUFFER_SIZE_BYTES],
priorityTaskManager, priorityTaskManager,
@ -96,7 +88,7 @@ public final class ProgressiveDownloader implements Downloader {
@Override @Override
public void remove() { public void remove() {
CacheUtil.remove(dataSpec, cache, cacheKeyFactory); CacheUtil.remove(dataSpec, dataSource.getCache(), dataSource.getCacheKeyFactory());
} }
private static final class ProgressForwarder implements CacheUtil.ProgressListener { private static final class ProgressForwarder implements CacheUtil.ProgressListener {

View File

@ -21,7 +21,6 @@ import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.cache.Cache;
import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
import com.google.android.exoplayer2.upstream.cache.CacheKeyFactory; import com.google.android.exoplayer2.upstream.cache.CacheKeyFactory;
import com.google.android.exoplayer2.upstream.cache.CacheUtil; import com.google.android.exoplayer2.upstream.cache.CacheUtil;
@ -67,10 +66,8 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
private static final long MAX_MERGED_SEGMENT_START_TIME_DIFF_US = 20 * C.MICROS_PER_SECOND; private static final long MAX_MERGED_SEGMENT_START_TIME_DIFF_US = 20 * C.MICROS_PER_SECOND;
private final DataSpec manifestDataSpec; private final DataSpec manifestDataSpec;
private final Cache cache;
private final CacheDataSource dataSource; private final CacheDataSource dataSource;
private final CacheDataSource offlineDataSource; private final CacheDataSource offlineDataSource;
private final CacheKeyFactory cacheKeyFactory;
private final PriorityTaskManager priorityTaskManager; private final PriorityTaskManager priorityTaskManager;
private final ArrayList<StreamKey> streamKeys; private final ArrayList<StreamKey> streamKeys;
private final AtomicBoolean isCanceled; private final AtomicBoolean isCanceled;
@ -85,10 +82,8 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
Uri manifestUri, List<StreamKey> streamKeys, DownloaderConstructorHelper constructorHelper) { Uri manifestUri, List<StreamKey> streamKeys, DownloaderConstructorHelper constructorHelper) {
this.manifestDataSpec = getCompressibleDataSpec(manifestUri); this.manifestDataSpec = getCompressibleDataSpec(manifestUri);
this.streamKeys = new ArrayList<>(streamKeys); this.streamKeys = new ArrayList<>(streamKeys);
this.cache = constructorHelper.getCache();
this.dataSource = constructorHelper.createCacheDataSource(); this.dataSource = constructorHelper.createCacheDataSource();
this.offlineDataSource = constructorHelper.createOfflineCacheDataSource(); this.offlineDataSource = constructorHelper.createOfflineCacheDataSource();
this.cacheKeyFactory = constructorHelper.getCacheKeyFactory();
this.priorityTaskManager = constructorHelper.getPriorityTaskManager(); this.priorityTaskManager = constructorHelper.getPriorityTaskManager();
isCanceled = new AtomicBoolean(); isCanceled = new AtomicBoolean();
} }
@ -112,7 +107,7 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
} }
List<Segment> segments = getSegments(dataSource, manifest, /* allowIncompleteList= */ false); List<Segment> segments = getSegments(dataSource, manifest, /* allowIncompleteList= */ false);
Collections.sort(segments); Collections.sort(segments);
mergeSegments(segments, cacheKeyFactory); mergeSegments(segments, dataSource.getCacheKeyFactory());
// Scan the segments, removing any that are fully downloaded. // Scan the segments, removing any that are fully downloaded.
int totalSegments = segments.size(); int totalSegments = segments.size();
@ -122,7 +117,8 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
for (int i = segments.size() - 1; i >= 0; i--) { for (int i = segments.size() - 1; i >= 0; i--) {
Segment segment = segments.get(i); Segment segment = segments.get(i);
Pair<Long, Long> segmentLengthAndBytesDownloaded = Pair<Long, Long> segmentLengthAndBytesDownloaded =
CacheUtil.getCached(segment.dataSpec, cache, cacheKeyFactory); CacheUtil.getCached(
segment.dataSpec, dataSource.getCache(), dataSource.getCacheKeyFactory());
long segmentLength = segmentLengthAndBytesDownloaded.first; long segmentLength = segmentLengthAndBytesDownloaded.first;
long segmentBytesDownloaded = segmentLengthAndBytesDownloaded.second; long segmentBytesDownloaded = segmentLengthAndBytesDownloaded.second;
bytesDownloaded += segmentBytesDownloaded; bytesDownloaded += segmentBytesDownloaded;
@ -155,8 +151,6 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
for (int i = 0; i < segments.size(); i++) { for (int i = 0; i < segments.size(); i++) {
CacheUtil.cache( CacheUtil.cache(
segments.get(i).dataSpec, segments.get(i).dataSpec,
cache,
cacheKeyFactory,
dataSource, dataSource,
buffer, buffer,
priorityTaskManager, priorityTaskManager,
@ -224,7 +218,7 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
throws InterruptedException, IOException; throws InterruptedException, IOException;
private void removeDataSpec(DataSpec dataSpec) { private void removeDataSpec(DataSpec dataSpec) {
CacheUtil.remove(dataSpec, cache, cacheKeyFactory); CacheUtil.remove(dataSpec, dataSource.getCache(), dataSource.getCacheKeyFactory());
} }
protected static DataSpec getCompressibleDataSpec(Uri uri) { protected static DataSpec getCompressibleDataSpec(Uri uri) {

View File

@ -244,6 +244,16 @@ public final class CacheDataSource implements DataSource {
this.eventListener = eventListener; this.eventListener = eventListener;
} }
/** Returns the {@link Cache} used by this instance. */
public Cache getCache() {
return cache;
}
/** Returns the {@link CacheKeyFactory} used by this instance. */
public CacheKeyFactory getCacheKeyFactory() {
return cacheKeyFactory;
}
@Override @Override
public void addTransferListener(TransferListener transferListener) { public void addTransferListener(TransferListener transferListener) {
cacheReadDataSource.addTransferListener(transferListener); cacheReadDataSource.addTransferListener(transferListener);

View File

@ -125,8 +125,6 @@ public final class CacheUtil {
throws IOException, InterruptedException { throws IOException, InterruptedException {
cache( cache(
dataSpec, dataSpec,
cache,
/* cacheKeyFactory= */ null,
new CacheDataSource(cache, upstream), new CacheDataSource(cache, upstream),
new byte[DEFAULT_BUFFER_SIZE_BYTES], new byte[DEFAULT_BUFFER_SIZE_BYTES],
/* priorityTaskManager= */ null, /* priorityTaskManager= */ null,
@ -149,9 +147,7 @@ public final class CacheUtil {
* <p>This method may be slow and shouldn't normally be called on the main thread. * <p>This method may be slow and shouldn't normally be called on the main thread.
* *
* @param dataSpec Defines the data to be cached. * @param dataSpec Defines the data to be cached.
* @param cache A {@link Cache} to store the data. * @param dataSource A {@link CacheDataSource} to be used for caching the data.
* @param cacheKeyFactory An optional factory for cache keys.
* @param dataSource A {@link CacheDataSource} that works on the {@code cache}.
* @param buffer The buffer to be used while caching. * @param buffer The buffer to be used while caching.
* @param priorityTaskManager If not null it's used to check whether it is allowed to proceed with * @param priorityTaskManager If not null it's used to check whether it is allowed to proceed with
* caching. * caching.
@ -166,8 +162,6 @@ public final class CacheUtil {
@WorkerThread @WorkerThread
public static void cache( public static void cache(
DataSpec dataSpec, DataSpec dataSpec,
Cache cache,
@Nullable CacheKeyFactory cacheKeyFactory,
CacheDataSource dataSource, CacheDataSource dataSource,
byte[] buffer, byte[] buffer,
@Nullable PriorityTaskManager priorityTaskManager, @Nullable PriorityTaskManager priorityTaskManager,
@ -179,6 +173,8 @@ public final class CacheUtil {
Assertions.checkNotNull(dataSource); Assertions.checkNotNull(dataSource);
Assertions.checkNotNull(buffer); Assertions.checkNotNull(buffer);
Cache cache = dataSource.getCache();
CacheKeyFactory cacheKeyFactory = dataSource.getCacheKeyFactory();
String key = buildCacheKey(dataSpec, cacheKeyFactory); String key = buildCacheKey(dataSpec, cacheKeyFactory);
long bytesLeft; long bytesLeft;
@Nullable ProgressNotifier progressNotifier = null; @Nullable ProgressNotifier progressNotifier = null;

View File

@ -301,8 +301,6 @@ public final class CacheUtilTest {
try { try {
CacheUtil.cache( CacheUtil.cache(
dataSpec, dataSpec,
cache,
/* cacheKeyFactory= */ null,
new CacheDataSource(cache, dataSource), new CacheDataSource(cache, dataSource),
new byte[CacheUtil.DEFAULT_BUFFER_SIZE_BYTES], new byte[CacheUtil.DEFAULT_BUFFER_SIZE_BYTES],
/* priorityTaskManager= */ null, /* priorityTaskManager= */ null,
@ -353,8 +351,6 @@ public final class CacheUtilTest {
.build(); .build();
CacheUtil.cache( CacheUtil.cache(
dataSpec, dataSpec,
cache,
/* cacheKeyFactory= */ null,
// Set fragmentSize to 10 to make sure there are multiple spans. // Set fragmentSize to 10 to make sure there are multiple spans.
new CacheDataSource( new CacheDataSource(
cache, cache,