diff --git a/library/src/androidTest/java/com/google/android/exoplayer2/upstream/cache/CacheDataSourceTest.java b/library/src/androidTest/java/com/google/android/exoplayer2/upstream/cache/CacheDataSourceTest.java index 067cfe4fcd..a5b272cebd 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer2/upstream/cache/CacheDataSourceTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer2/upstream/cache/CacheDataSourceTest.java @@ -20,9 +20,9 @@ import android.test.InstrumentationTestCase; import android.test.MoreAsserts; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.testutil.FakeDataSource; -import com.google.android.exoplayer2.testutil.FakeDataSource.Builder; import com.google.android.exoplayer2.testutil.TestUtil; import com.google.android.exoplayer2.upstream.DataSpec; +import com.google.android.exoplayer2.upstream.FileDataSource; import java.io.File; import java.io.IOException; import java.util.Arrays; @@ -126,9 +126,15 @@ public class CacheDataSourceTest extends InstrumentationTestCase { MoreAsserts.assertEmpty(simpleCache.getKeys()); } + public void testReadOnlyCache() throws Exception { + CacheDataSource cacheDataSource = createCacheDataSource(false, false, 0, null); + assertReadDataContentLength(cacheDataSource, false, false); + assertEquals(0, cacheDir.list().length); + } + private void assertCacheAndRead(boolean unboundedRequest, boolean simulateUnknownLength) throws IOException { - // Read all data from upstream and cache + // Read all data from upstream and write to cache CacheDataSource cacheDataSource = createCacheDataSource(false, simulateUnknownLength); assertReadDataContentLength(cacheDataSource, unboundedRequest, simulateUnknownLength); @@ -184,14 +190,21 @@ public class CacheDataSourceTest extends InstrumentationTestCase { private CacheDataSource createCacheDataSource(boolean setReadException, boolean simulateUnknownLength, @CacheDataSource.Flags int flags) { - Builder builder = new Builder(); + return createCacheDataSource(setReadException, simulateUnknownLength, flags, + new CacheDataSink(simpleCache, MAX_CACHE_FILE_SIZE)); + } + + private CacheDataSource createCacheDataSource(boolean setReadException, + boolean simulateUnknownLength, @CacheDataSource.Flags int flags, + CacheDataSink cacheWriteDataSink) { + FakeDataSource.Builder builder = new FakeDataSource.Builder(); if (setReadException) { builder.appendReadError(new IOException("Shouldn't read from upstream")); } - builder.setSimulateUnknownLength(simulateUnknownLength); - builder.appendReadData(TEST_DATA); - FakeDataSource upstream = builder.build(); - return new CacheDataSource(simpleCache, upstream, flags, MAX_CACHE_FILE_SIZE); + FakeDataSource upstream = + builder.setSimulateUnknownLength(simulateUnknownLength).appendReadData(TEST_DATA).build(); + return new CacheDataSource(simpleCache, upstream, new FileDataSource(), cacheWriteDataSink, + flags, null); } } diff --git a/library/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSource.java b/library/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSource.java index 9b29984d06..dc8797362f 100644 --- a/library/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSource.java +++ b/library/src/main/java/com/google/android/exoplayer2/upstream/cache/CacheDataSource.java @@ -142,7 +142,8 @@ public final class CacheDataSource implements DataSource { * @param cache The cache. * @param upstream A {@link DataSource} for reading data not in the cache. * @param cacheReadDataSource A {@link DataSource} for reading data from the cache. - * @param cacheWriteDataSink A {@link DataSink} for writing data to the cache. + * @param cacheWriteDataSink A {@link DataSink} for writing data to the cache. If null, cache is + * accessed read-only. * @param flags A combination of {@link #FLAG_BLOCK_ON_CACHE} and {@link * #FLAG_IGNORE_CACHE_ON_ERROR} or 0. * @param eventListener An optional {@link EventListener} to receive events. @@ -283,7 +284,6 @@ public final class CacheDataSource implements DataSource { currentDataSource = cacheReadDataSource; } else { // Data is not cached, and data is not locked, read from upstream with cache backing. - lockedSpan = span; long length; if (span.isOpenEnded()) { length = bytesRemaining; @@ -294,8 +294,13 @@ public final class CacheDataSource implements DataSource { } } dataSpec = new DataSpec(uri, readPosition, length, key, flags); - currentDataSource = cacheWriteDataSource != null ? cacheWriteDataSource - : upstreamDataSource; + if (cacheWriteDataSource != null) { + currentDataSource = cacheWriteDataSource; + lockedSpan = span; + } else { + currentDataSource = upstreamDataSource; + cache.releaseHoleSpan(span); + } } currentRequestUnbounded = dataSpec.length == C.LENGTH_UNSET;