CacheDataSource implements DataSource { @Override public long open(DataSpec dataSpec) throws IOException { try { key = cacheKeyFactory.buildCacheKey(dataSpec); uri = dataSpec.uri; actualUri = getRedirectedUriOrDefault(cache, key, uri); httpMethod = dataSpec.httpMethod; httpBody = dataSpec.httpBody; httpRequestHeaders = dataSpec.httpRequestHeaders; flags = dataSpec.flags; readPosition = dataSpec.position; int reason = shouldIgnoreCacheForRequest(dataSpec); currentRequestIgnoresCache = reason != CACHE_NOT_IGNORED; if (currentRequestIgnoresCache) { notifyCacheIgnored(reason); } if (dataSpec.length != C.LENGTH_UNSET || currentRequestIgnoresCache) { bytesRemaining = dataSpec.length; } else { bytesRemaining = ContentMetadata.getContentLength(cache.getContentMetadata(key)); if (bytesRemaining != C.LENGTH_UNSET) { bytesRemaining -= dataSpec.position; if (bytesRemaining <= 0) { throw new DataSourceException(DataSourceException.POSITION_OUT_OF_RANGE); } } } openNextSource(false); return bytesRemaining; } catch (Throwable e) { handleBeforeThrow(e); throw e; } } CacheDataSource(Cache cache, DataSource upstream);  CacheDataSource(Cache cache, DataSource upstream, @Flags int flags);  CacheDataSource(
      Cache cache,
      DataSource upstream,
      DataSource cacheReadDataSource,
      @Nullable DataSink cacheWriteDataSink,
      @Flags int flags,
      @Nullable EventListener eventListener);  CacheDataSource(
      Cache cache,
      DataSource upstream,
      DataSource cacheReadDataSource,
      @Nullable DataSink cacheWriteDataSink,
      @Flags int flags,
      @Nullable EventListener eventListener,
      @Nullable CacheKeyFactory cacheKeyFactory); @Override void addTransferListener(TransferListener transferListener); @Override long open(DataSpec dataSpec); @Override int read(byte[] buffer, int offset, int readLength); @Override @Nullable Uri getUri(); @Override Map<String, List<String>> getResponseHeaders(); @Override void close(); static final int FLAG_BLOCK_ON_CACHE; static final int FLAG_IGNORE_CACHE_ON_ERROR; static final int FLAG_IGNORE_CACHE_FOR_UNSET_LENGTH_REQUESTS; static final int CACHE_IGNORED_REASON_ERROR; static final int CACHE_IGNORED_REASON_UNSET_LENGTH; }
@Test public void testPropagatesHttpHeadersUpstream() throws Exception { CacheDataSource cacheDataSource = createCacheDataSource( false, false); DataSpec dataSpec = buildDataSpec( 2, 5); cacheDataSource.open(dataSpec); DataSpec[] upstreamDataSpecs = upstreamDataSource.getAndClearOpenedDataSpecs(); assertThat(upstreamDataSpecs).hasLength(1); assertThat(upstreamDataSpecs[0].httpRequestHeaders).isEqualTo(this.httpRequestHeaders); }
@Test public void testUnsatisfiableRange() throws Exception { assertCacheAndRead(boundedDataSpec, true); CacheDataSource cacheDataSource = createCacheDataSource( true, true); assertReadDataContentLength( cacheDataSource, unboundedDataSpec, true, false); try { cacheDataSource = createCacheDataSource( false, false); cacheDataSource.open(buildDataSpec(TEST_DATA.length, 1, defaultCacheKey)); fail(); } catch (IOException e) { } }
@Test public void testUnsatisfiableRangeWithCacheKeyFactoryNullDataSpecCacheKey() throws Exception { assertCacheAndRead(boundedDataSpec, true, cacheKeyFactory); CacheDataSource cacheDataSource = createCacheDataSource( true, true, cacheKeyFactory); assertReadDataContentLength( cacheDataSource, unboundedDataSpec, true, true); try { cacheDataSource = createCacheDataSource( false, false, cacheKeyFactory); cacheDataSource.open(buildDataSpec(TEST_DATA.length, 1, customCacheKey)); fail(); } catch (IOException e) { } }
@Test public void testUnsatisfiableRangeWithCacheKeyFactoryOverridingDataSpecCacheKey() throws Exception { assertCacheAndRead(boundedDataSpecWithKey, true, cacheKeyFactory); CacheDataSource cacheDataSource = createCacheDataSource( true, true, cacheKeyFactory); assertReadDataContentLength( cacheDataSource, unboundedDataSpecWithKey, true, true); try { cacheDataSource = createCacheDataSource( false, false, cacheKeyFactory); cacheDataSource.open(buildDataSpec(TEST_DATA.length, 1, customCacheKey)); fail(); } catch (IOException e) { } }
@Test public void testContentLengthEdgeCases() throws Exception { DataSpec dataSpec = buildDataSpec(TEST_DATA.length - 2, 2); CacheDataSource cacheDataSource = createCacheDataSource(false, true); assertReadData(cacheDataSource, dataSpec, true); assertThat(ContentMetadata.getContentLength(cache.getContentMetadata(defaultCacheKey))) .isEqualTo(C.LENGTH_UNSET); cacheDataSource = createCacheDataSource(false, true); assertReadDataContentLength(cacheDataSource, unboundedDataSpec, true, false); assertThat( cacheDataSource.open( buildDataSpec(TEST_DATA.length - 2, C.LENGTH_UNSET, defaultCacheKey))) .isEqualTo(2); dataSpec = new DataSpec( Uri.parse("https: TEST_DATA.length - 2, C.LENGTH_UNSET, null); assertThat(cacheDataSource.open(dataSpec)).isEqualTo(C.LENGTH_UNSET); }