*** Original commit ***

DataSource.open() throws if already opened.

Update DataSource implementations to throw an error if open() is called
when the DataSource is already open.

***

PiperOrigin-RevId: 348783425
This commit is contained in:
olly 2020-12-23 14:00:27 +00:00 committed by Oliver Woodman
parent 653d180d4c
commit d01093d711
21 changed files with 18 additions and 90 deletions

View File

@ -15,8 +15,6 @@
*/
package com.google.android.exoplayer2.ext.media2;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import android.content.Context;
import android.net.Uri;
import android.os.Looper;
@ -145,7 +143,6 @@ import org.junit.rules.ExternalResource;
private final DataSource wrappedDataSource;
private final DataSourceInstrumentation instrumentation;
private boolean opened;
public InstrumentedDataSource(
DataSource wrappedDataSource, DataSourceInstrumentation instrumentation) {
@ -160,11 +157,8 @@ import org.junit.rules.ExternalResource;
@Override
public long open(DataSpec dataSpec) throws IOException {
checkState(!opened);
instrumentation.onPreOpen(dataSpec);
long length = wrappedDataSource.open(dataSpec);
opened = true;
return length;
return wrappedDataSource.open(dataSpec);
}
@Nullable
@ -186,7 +180,6 @@ import org.junit.rules.ExternalResource;
@Override
public void close() throws IOException {
wrappedDataSource.close();
opened = false;
}
}
}

View File

@ -16,7 +16,6 @@
package com.google.android.exoplayer2.ext.okhttp;
import static com.google.android.exoplayer2.ExoPlayerLibraryInfo.DEFAULT_USER_AGENT;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import static java.lang.Math.min;
@ -278,7 +277,6 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource {
@Override
public long open(DataSpec dataSpec) throws HttpDataSourceException {
checkState(!opened);
this.dataSpec = dataSpec;
this.bytesRead = 0;
this.bytesSkipped = 0;

View File

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.ext.rtmp;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import android.net.Uri;
@ -38,7 +37,6 @@ public final class RtmpDataSource extends BaseDataSource {
@Nullable private RtmpClient rtmpClient;
@Nullable private Uri uri;
private boolean opened;
public RtmpDataSource() {
super(/* isNetwork= */ true);
@ -46,14 +44,12 @@ public final class RtmpDataSource extends BaseDataSource {
@Override
public long open(DataSpec dataSpec) throws RtmpIOException {
checkState(!opened);
transferInitializing(dataSpec);
rtmpClient = new RtmpClient();
rtmpClient.open(dataSpec.uri.toString(), false);
this.uri = dataSpec.uri;
transferStarted(dataSpec);
opened = true;
return C.LENGTH_UNSET;
}
@ -77,7 +73,6 @@ public final class RtmpDataSource extends BaseDataSource {
rtmpClient.close();
rtmpClient = null;
}
opened = false;
}
@Override

View File

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import static java.lang.Math.min;
@ -58,7 +57,6 @@ public final class AssetDataSource extends BaseDataSource {
@Override
public long open(DataSpec dataSpec) throws AssetDataSourceException {
checkState(!opened);
try {
uri = dataSpec.uri;
String path = Assertions.checkNotNull(uri.getPath());

View File

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static java.lang.Math.min;
import android.net.Uri;
@ -46,7 +45,6 @@ public final class ByteArrayDataSource extends BaseDataSource {
@Override
public long open(DataSpec dataSpec) throws IOException {
checkState(!opened);
uri = dataSpec.uri;
transferInitializing(dataSpec);
readPosition = (int) dataSpec.position;

View File

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import static java.lang.Math.min;
@ -63,8 +62,6 @@ public final class ContentDataSource extends BaseDataSource {
@Override
public long open(DataSpec dataSpec) throws ContentDataSourceException {
checkState(!opened);
try {
Uri uri = dataSpec.uri;
this.uri = uri;

View File

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import static java.lang.Math.min;
@ -45,7 +44,6 @@ public final class DataSchemeDataSource extends BaseDataSource {
@Override
public long open(DataSpec dataSpec) throws IOException {
checkState(this.dataSpec == null);
transferInitializing(dataSpec);
this.dataSpec = dataSpec;
readPosition = (int) dataSpec.position;

View File

@ -16,7 +16,6 @@
package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.ExoPlayerLibraryInfo.DEFAULT_USER_AGENT;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static java.lang.Math.max;
import static java.lang.Math.min;
@ -343,7 +342,6 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
*/
@Override
public long open(DataSpec dataSpec) throws HttpDataSourceException {
checkState(!opened);
this.dataSpec = dataSpec;
this.bytesRead = 0;
this.bytesSkipped = 0;

View File

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import static java.lang.Math.min;
@ -81,7 +80,6 @@ public final class FileDataSource extends BaseDataSource {
@Override
public long open(DataSpec dataSpec) throws FileDataSourceException {
checkState(!opened);
try {
Uri uri = dataSpec.uri;
this.uri = uri;

View File

@ -15,8 +15,6 @@
*/
package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import android.net.Uri;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.util.Assertions;
@ -42,7 +40,6 @@ public final class PriorityDataSource implements DataSource {
private final DataSource upstream;
private final PriorityTaskManager priorityTaskManager;
private final int priority;
private boolean opened;
/**
* @param upstream The upstream {@link DataSource}.
@ -64,11 +61,8 @@ public final class PriorityDataSource implements DataSource {
@Override
public long open(DataSpec dataSpec) throws IOException {
checkState(!opened);
priorityTaskManager.proceedOrThrow(priority);
long length = upstream.open(dataSpec);
opened = true;
return length;
return upstream.open(dataSpec);
}
@Override
@ -91,7 +85,6 @@ public final class PriorityDataSource implements DataSource {
@Override
public void close() throws IOException {
upstream.close();
opened = false;
}
}

View File

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import static java.lang.Math.min;
@ -99,7 +98,6 @@ public final class RawResourceDataSource extends BaseDataSource {
@Override
public long open(DataSpec dataSpec) throws RawResourceDataSourceException {
checkState(!opened);
Uri uri = dataSpec.uri;
this.uri = uri;

View File

@ -16,7 +16,6 @@
package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import android.net.Uri;
import androidx.annotation.Nullable;
@ -104,7 +103,6 @@ public final class ResolvingDataSource implements DataSource {
@Override
public long open(DataSpec dataSpec) throws IOException {
checkState(!upstreamOpened);
DataSpec resolvedDataSpec = resolver.resolveDataSpec(dataSpec);
upstreamOpened = true;
return upstreamDataSource.open(resolvedDataSpec);

View File

@ -15,8 +15,6 @@
*/
package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import android.net.Uri;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
@ -37,7 +35,6 @@ public final class StatsDataSource implements DataSource {
private long bytesRead;
private Uri lastOpenedUri;
private Map<String, List<String>> lastResponseHeaders;
private boolean opened;
/**
* Creates the stats data source.
@ -81,14 +78,12 @@ public final class StatsDataSource implements DataSource {
@Override
public long open(DataSpec dataSpec) throws IOException {
checkState(!opened);
// Reassign defaults in case dataSource.open throws an exception.
lastOpenedUri = dataSpec.uri;
lastResponseHeaders = Collections.emptyMap();
long availableBytes = dataSource.open(dataSpec);
lastOpenedUri = Assertions.checkNotNull(getUri());
lastResponseHeaders = getResponseHeaders();
opened = true;
return availableBytes;
}
@ -115,6 +110,5 @@ public final class StatsDataSource implements DataSource {
@Override
public void close() throws IOException {
dataSource.close();
opened = false;
}
}

View File

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static java.lang.Math.min;
import android.net.Uri;
@ -90,8 +89,6 @@ public final class UdpDataSource extends BaseDataSource {
@Override
public long open(DataSpec dataSpec) throws UdpDataSourceException {
checkState(!opened);
uri = dataSpec.uri;
String host = uri.getHost();
int port = uri.getPort();

View File

@ -16,7 +16,6 @@
package com.google.android.exoplayer2.upstream.cache;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import static java.lang.Math.min;
@ -34,6 +33,7 @@ import com.google.android.exoplayer2.upstream.PriorityDataSource;
import com.google.android.exoplayer2.upstream.TeeDataSource;
import com.google.android.exoplayer2.upstream.TransferListener;
import com.google.android.exoplayer2.upstream.cache.Cache.CacheException;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.PriorityTaskManager;
import java.io.IOException;
import java.io.InterruptedIOException;
@ -397,7 +397,6 @@ public final class CacheDataSource implements DataSource {
private boolean currentRequestIgnoresCache;
private long totalCachedBytesRead;
private long checkCachePosition;
private boolean opened;
/**
* Constructs an instance with default {@link DataSource} and {@link DataSink} instances for
@ -553,7 +552,6 @@ public final class CacheDataSource implements DataSource {
@Override
public long open(DataSpec dataSpec) throws IOException {
checkState(!opened);
try {
String key = cacheKeyFactory.buildCacheKey(dataSpec);
DataSpec requestDataSpec = dataSpec.buildUpon().setKey(key).build();
@ -579,7 +577,6 @@ public final class CacheDataSource implements DataSource {
}
}
openNextSource(requestDataSpec, false);
opened = true;
return bytesRemaining;
} catch (Throwable e) {
handleBeforeThrow(e);
@ -652,7 +649,6 @@ public final class CacheDataSource implements DataSource {
notifyBytesRead();
try {
closeCurrentSource();
opened = false;
} catch (Throwable e) {
handleBeforeThrow(e);
throw e;
@ -743,7 +739,7 @@ public final class CacheDataSource implements DataSource {
? readPosition + MIN_READ_BEFORE_CHECKING_CACHE
: Long.MAX_VALUE;
if (checkCache) {
checkState(isBypassingCache());
Assertions.checkState(isBypassingCache());
if (nextDataSource == upstreamDataSource) {
// Continue reading from upstream.
return;

View File

@ -16,7 +16,6 @@
package com.google.android.exoplayer2.upstream.crypto;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import android.net.Uri;
@ -37,7 +36,6 @@ public final class AesCipherDataSource implements DataSource {
private final DataSource upstream;
private final byte[] secretKey;
private boolean opened;
@Nullable private AesFlushingCipher cipher;
@ -54,13 +52,11 @@ public final class AesCipherDataSource implements DataSource {
@Override
public long open(DataSpec dataSpec) throws IOException {
checkState(!opened);
long dataLength = upstream.open(dataSpec);
long nonce = CryptoUtil.getFNV64Hash(dataSpec.key);
cipher =
new AesFlushingCipher(
Cipher.DECRYPT_MODE, secretKey, nonce, dataSpec.uriPositionOffset + dataSpec.position);
opened = true;
return dataLength;
}
@ -92,6 +88,5 @@ public final class AesCipherDataSource implements DataSource {
public void close() throws IOException {
cipher = null;
upstream.close();
opened = false;
}
}

View File

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.common.truth.Truth.assertThat;
import android.net.Uri;
@ -90,18 +89,14 @@ public class BaseDataSourceTest {
private static final class TestSource extends BaseDataSource {
private boolean opened;
public TestSource(boolean isNetwork) {
super(isNetwork);
}
@Override
public long open(DataSpec dataSpec) throws IOException {
checkState(!opened);
transferInitializing(dataSpec);
transferStarted(dataSpec);
opened = true;
return C.LENGTH_UNSET;
}
@ -120,7 +115,6 @@ public class BaseDataSourceTest {
@Override
public void close() throws IOException {
transferEnded();
opened = false;
}
}

View File

@ -17,7 +17,6 @@ package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.C.RESULT_END_OF_INPUT;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail;
import android.net.Uri;
@ -131,20 +130,19 @@ public final class DataSchemeDataSourceTest {
}
@Test
public void malformedData_throwsIOException() {
assertThrows(
IOException.class,
() ->
schemeDataDataSource.open(
buildDataSpec("data:text/plain;base64,,This%20is%20Content")));
public void malformedData() {
try {
schemeDataDataSource.open(buildDataSpec("data:text/plain;base64,,This%20is%20Content"));
fail();
} catch (IOException e) {
// Expected.
}
try {
schemeDataDataSource.open(buildDataSpec("data:text/plain;base64,IncorrectPadding=="));
fail();
} catch (IOException e) {
// Expected.
}
@Test
public void malformedData_incorrectPadding_throwsIOException() {
assertThrows(
IOException.class,
() ->
schemeDataDataSource.open(buildDataSpec("data:text/plain;base64,IncorrectPadding==")));
}
@Test

View File

@ -284,7 +284,6 @@ public final class CacheDataSourceTest {
cacheDataSource.open(
buildDataSpec(TEST_DATA.length - 2, C.LENGTH_UNSET, defaultCacheKey)))
.isEqualTo(2);
cacheDataSource.close();
// An unbounded request with offset for not cached content.
dataSpec =

View File

@ -15,8 +15,6 @@
*/
package com.google.android.exoplayer2.source.hls;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import android.net.Uri;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
@ -52,7 +50,6 @@ import javax.crypto.spec.SecretKeySpec;
private final DataSource upstream;
private final byte[] encryptionKey;
private final byte[] encryptionIv;
private boolean opened;
@Nullable private CipherInputStream cipherInputStream;
@ -75,7 +72,6 @@ import javax.crypto.spec.SecretKeySpec;
@Override
public final long open(DataSpec dataSpec) throws IOException {
checkState(!opened);
Cipher cipher;
try {
cipher = getCipherInstance();
@ -95,7 +91,7 @@ import javax.crypto.spec.SecretKeySpec;
DataSourceInputStream inputStream = new DataSourceInputStream(upstream, dataSpec);
cipherInputStream = new CipherInputStream(inputStream, cipher);
inputStream.open();
opened = true;
return C.LENGTH_UNSET;
}
@ -125,7 +121,6 @@ import javax.crypto.spec.SecretKeySpec;
if (cipherInputStream != null) {
cipherInputStream = null;
upstream.close();
opened = false;
}
}

View File

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.source.hls;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.common.truth.Truth.assertThat;
import android.net.Uri;
@ -105,7 +104,6 @@ public class Aes128DataSourceTest {
@Override
public long open(DataSpec dataSpec) throws IOException {
checkState(!opened);
opened = true;
return C.LENGTH_UNSET;
}