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.CacheDataSourceFactory;
import com.google.android.exoplayer2.upstream.cache.CacheKeyFactory;
import com.google.android.exoplayer2.upstream.cache.CacheUtil;
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;
@Nullable private final CacheKeyFactory cacheKeyFactory;
@Nullable private final PriorityTaskManager priorityTaskManager;
private final CacheDataSourceFactory onlineCacheDataSourceFactory;
private final CacheDataSourceFactory offlineCacheDataSourceFactory;
@ -133,19 +130,7 @@ public final class DownloaderConstructorHelper {
CacheDataSource.FLAG_BLOCK_ON_CACHE,
/* eventListener= */ null,
cacheKeyFactory);
this.cache = cache;
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. */

View File

@ -19,9 +19,7 @@ import android.net.Uri;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
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.CacheKeyFactory;
import com.google.android.exoplayer2.upstream.cache.CacheUtil;
import com.google.android.exoplayer2.util.PriorityTaskManager;
import java.io.IOException;
@ -41,9 +39,7 @@ public final class ProgressiveDownloader implements Downloader {
private static final int BUFFER_SIZE_BYTES = 128 * 1024;
private final DataSpec dataSpec;
private final Cache cache;
private final CacheDataSource dataSource;
private final CacheKeyFactory cacheKeyFactory;
private final PriorityTaskManager priorityTaskManager;
private final AtomicBoolean isCanceled;
@ -61,9 +57,7 @@ public final class ProgressiveDownloader implements Downloader {
.setKey(customCacheKey)
.setFlags(DataSpec.FLAG_ALLOW_CACHE_FRAGMENTATION)
.build();
this.cache = constructorHelper.getCache();
this.dataSource = constructorHelper.createCacheDataSource();
this.cacheKeyFactory = constructorHelper.getCacheKeyFactory();
this.priorityTaskManager = constructorHelper.getPriorityTaskManager();
isCanceled = new AtomicBoolean();
}
@ -75,8 +69,6 @@ public final class ProgressiveDownloader implements Downloader {
try {
CacheUtil.cache(
dataSpec,
cache,
cacheKeyFactory,
dataSource,
new byte[BUFFER_SIZE_BYTES],
priorityTaskManager,
@ -96,7 +88,7 @@ public final class ProgressiveDownloader implements Downloader {
@Override
public void remove() {
CacheUtil.remove(dataSpec, cache, cacheKeyFactory);
CacheUtil.remove(dataSpec, dataSource.getCache(), dataSource.getCacheKeyFactory());
}
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.upstream.DataSource;
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.CacheKeyFactory;
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 final DataSpec manifestDataSpec;
private final Cache cache;
private final CacheDataSource dataSource;
private final CacheDataSource offlineDataSource;
private final CacheKeyFactory cacheKeyFactory;
private final PriorityTaskManager priorityTaskManager;
private final ArrayList<StreamKey> streamKeys;
private final AtomicBoolean isCanceled;
@ -85,10 +82,8 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
Uri manifestUri, List<StreamKey> streamKeys, DownloaderConstructorHelper constructorHelper) {
this.manifestDataSpec = getCompressibleDataSpec(manifestUri);
this.streamKeys = new ArrayList<>(streamKeys);
this.cache = constructorHelper.getCache();
this.dataSource = constructorHelper.createCacheDataSource();
this.offlineDataSource = constructorHelper.createOfflineCacheDataSource();
this.cacheKeyFactory = constructorHelper.getCacheKeyFactory();
this.priorityTaskManager = constructorHelper.getPriorityTaskManager();
isCanceled = new AtomicBoolean();
}
@ -112,7 +107,7 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
}
List<Segment> segments = getSegments(dataSource, manifest, /* allowIncompleteList= */ false);
Collections.sort(segments);
mergeSegments(segments, cacheKeyFactory);
mergeSegments(segments, dataSource.getCacheKeyFactory());
// Scan the segments, removing any that are fully downloaded.
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--) {
Segment segment = segments.get(i);
Pair<Long, Long> segmentLengthAndBytesDownloaded =
CacheUtil.getCached(segment.dataSpec, cache, cacheKeyFactory);
CacheUtil.getCached(
segment.dataSpec, dataSource.getCache(), dataSource.getCacheKeyFactory());
long segmentLength = segmentLengthAndBytesDownloaded.first;
long segmentBytesDownloaded = segmentLengthAndBytesDownloaded.second;
bytesDownloaded += segmentBytesDownloaded;
@ -155,8 +151,6 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
for (int i = 0; i < segments.size(); i++) {
CacheUtil.cache(
segments.get(i).dataSpec,
cache,
cacheKeyFactory,
dataSource,
buffer,
priorityTaskManager,
@ -224,7 +218,7 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
throws InterruptedException, IOException;
private void removeDataSpec(DataSpec dataSpec) {
CacheUtil.remove(dataSpec, cache, cacheKeyFactory);
CacheUtil.remove(dataSpec, dataSource.getCache(), dataSource.getCacheKeyFactory());
}
protected static DataSpec getCompressibleDataSpec(Uri uri) {

View File

@ -244,6 +244,16 @@ public final class CacheDataSource implements DataSource {
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
public void addTransferListener(TransferListener transferListener) {
cacheReadDataSource.addTransferListener(transferListener);

View File

@ -125,8 +125,6 @@ public final class CacheUtil {
throws IOException, InterruptedException {
cache(
dataSpec,
cache,
/* cacheKeyFactory= */ null,
new CacheDataSource(cache, upstream),
new byte[DEFAULT_BUFFER_SIZE_BYTES],
/* 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.
*
* @param dataSpec Defines the data to be cached.
* @param cache A {@link Cache} to store the data.
* @param cacheKeyFactory An optional factory for cache keys.
* @param dataSource A {@link CacheDataSource} that works on the {@code cache}.
* @param dataSource A {@link CacheDataSource} to be used for caching the data.
* @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
* caching.
@ -166,8 +162,6 @@ public final class CacheUtil {
@WorkerThread
public static void cache(
DataSpec dataSpec,
Cache cache,
@Nullable CacheKeyFactory cacheKeyFactory,
CacheDataSource dataSource,
byte[] buffer,
@Nullable PriorityTaskManager priorityTaskManager,
@ -179,6 +173,8 @@ public final class CacheUtil {
Assertions.checkNotNull(dataSource);
Assertions.checkNotNull(buffer);
Cache cache = dataSource.getCache();
CacheKeyFactory cacheKeyFactory = dataSource.getCacheKeyFactory();
String key = buildCacheKey(dataSpec, cacheKeyFactory);
long bytesLeft;
@Nullable ProgressNotifier progressNotifier = null;

View File

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