mirror of
https://github.com/androidx/media.git
synced 2025-05-10 00:59:51 +08:00
Forward addTransferListener for all wrapping data sources.
This allows to register a listener on an outer wrapping data source which receives data transfer events from the wrapped source. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=203358981
This commit is contained in:
parent
5047a5a4da
commit
264bed06f2
@ -52,8 +52,7 @@ public interface DataSource {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link TransferListener} to listen to data transfers. Must be called before the first
|
||||
* call to {@link #open(DataSpec)}.
|
||||
* Adds a {@link TransferListener} to listen to data transfers. This method is not thread-safe.
|
||||
*
|
||||
* @param transferListener A {@link TransferListener}.
|
||||
*/
|
||||
|
@ -17,10 +17,12 @@ package com.google.android.exoplayer2.upstream;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -55,19 +57,18 @@ public final class DefaultDataSource implements DataSource {
|
||||
private static final String SCHEME_RAW = RawResourceDataSource.RAW_RESOURCE_SCHEME;
|
||||
|
||||
private final Context context;
|
||||
private final TransferListener<? super DataSource> listener;
|
||||
|
||||
private final List<TransferListener<? super DataSource>> transferListeners;
|
||||
private final DataSource baseDataSource;
|
||||
|
||||
// Lazily initialized.
|
||||
private DataSource fileDataSource;
|
||||
private DataSource assetDataSource;
|
||||
private DataSource contentDataSource;
|
||||
private DataSource rtmpDataSource;
|
||||
private DataSource dataSchemeDataSource;
|
||||
private DataSource rawResourceDataSource;
|
||||
private @Nullable DataSource fileDataSource;
|
||||
private @Nullable DataSource assetDataSource;
|
||||
private @Nullable DataSource contentDataSource;
|
||||
private @Nullable DataSource rtmpDataSource;
|
||||
private @Nullable DataSource dataSchemeDataSource;
|
||||
private @Nullable DataSource rawResourceDataSource;
|
||||
|
||||
private DataSource dataSource;
|
||||
private @Nullable DataSource dataSource;
|
||||
|
||||
/**
|
||||
* Constructs a new instance, optionally configured to follow cross-protocol redirects.
|
||||
@ -78,8 +79,11 @@ public final class DefaultDataSource implements DataSource {
|
||||
* @param allowCrossProtocolRedirects Whether cross-protocol redirects (i.e. redirects from HTTP
|
||||
* to HTTPS and vice versa) are enabled when fetching remote data.
|
||||
*/
|
||||
public DefaultDataSource(Context context, TransferListener<? super DataSource> listener,
|
||||
String userAgent, boolean allowCrossProtocolRedirects) {
|
||||
public DefaultDataSource(
|
||||
Context context,
|
||||
@Nullable TransferListener<? super DataSource> listener,
|
||||
String userAgent,
|
||||
boolean allowCrossProtocolRedirects) {
|
||||
this(context, listener, userAgent, DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
|
||||
DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS, allowCrossProtocolRedirects);
|
||||
}
|
||||
@ -92,13 +96,17 @@ public final class DefaultDataSource implements DataSource {
|
||||
* @param userAgent The User-Agent string that should be used when requesting remote data.
|
||||
* @param connectTimeoutMillis The connection timeout that should be used when requesting remote
|
||||
* data, in milliseconds. A timeout of zero is interpreted as an infinite timeout.
|
||||
* @param readTimeoutMillis The read timeout that should be used when requesting remote data,
|
||||
* in milliseconds. A timeout of zero is interpreted as an infinite timeout.
|
||||
* @param readTimeoutMillis The read timeout that should be used when requesting remote data, in
|
||||
* milliseconds. A timeout of zero is interpreted as an infinite timeout.
|
||||
* @param allowCrossProtocolRedirects Whether cross-protocol redirects (i.e. redirects from HTTP
|
||||
* to HTTPS and vice versa) are enabled when fetching remote data.
|
||||
*/
|
||||
public DefaultDataSource(Context context, TransferListener<? super DataSource> listener,
|
||||
String userAgent, int connectTimeoutMillis, int readTimeoutMillis,
|
||||
public DefaultDataSource(
|
||||
Context context,
|
||||
@Nullable TransferListener<? super DataSource> listener,
|
||||
String userAgent,
|
||||
int connectTimeoutMillis,
|
||||
int readTimeoutMillis,
|
||||
boolean allowCrossProtocolRedirects) {
|
||||
this(context, listener,
|
||||
new DefaultHttpDataSource(userAgent, null, listener, connectTimeoutMillis,
|
||||
@ -114,11 +122,28 @@ public final class DefaultDataSource implements DataSource {
|
||||
* @param baseDataSource A {@link DataSource} to use for URI schemes other than file, asset and
|
||||
* content. This {@link DataSource} should normally support at least http(s).
|
||||
*/
|
||||
public DefaultDataSource(Context context, TransferListener<? super DataSource> listener,
|
||||
public DefaultDataSource(
|
||||
Context context,
|
||||
@Nullable TransferListener<? super DataSource> listener,
|
||||
DataSource baseDataSource) {
|
||||
this.context = context.getApplicationContext();
|
||||
this.listener = listener;
|
||||
this.baseDataSource = Assertions.checkNotNull(baseDataSource);
|
||||
transferListeners = new ArrayList<>();
|
||||
if (listener != null) {
|
||||
transferListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTransferListener(TransferListener<? super DataSource> transferListener) {
|
||||
baseDataSource.addTransferListener(transferListener);
|
||||
transferListeners.add(transferListener);
|
||||
maybeAddListenerToDataSource(fileDataSource, transferListener);
|
||||
maybeAddListenerToDataSource(assetDataSource, transferListener);
|
||||
maybeAddListenerToDataSource(contentDataSource, transferListener);
|
||||
maybeAddListenerToDataSource(rtmpDataSource, transferListener);
|
||||
maybeAddListenerToDataSource(dataSchemeDataSource, transferListener);
|
||||
maybeAddListenerToDataSource(rawResourceDataSource, transferListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -151,11 +176,11 @@ public final class DefaultDataSource implements DataSource {
|
||||
|
||||
@Override
|
||||
public int read(byte[] buffer, int offset, int readLength) throws IOException {
|
||||
return dataSource.read(buffer, offset, readLength);
|
||||
return Assertions.checkNotNull(dataSource).read(buffer, offset, readLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri getUri() {
|
||||
public @Nullable Uri getUri() {
|
||||
return dataSource == null ? null : dataSource.getUri();
|
||||
}
|
||||
|
||||
@ -179,21 +204,24 @@ public final class DefaultDataSource implements DataSource {
|
||||
|
||||
private DataSource getFileDataSource() {
|
||||
if (fileDataSource == null) {
|
||||
fileDataSource = new FileDataSource(listener);
|
||||
fileDataSource = new FileDataSource();
|
||||
addListenersToDataSource(fileDataSource);
|
||||
}
|
||||
return fileDataSource;
|
||||
}
|
||||
|
||||
private DataSource getAssetDataSource() {
|
||||
if (assetDataSource == null) {
|
||||
assetDataSource = new AssetDataSource(context, listener);
|
||||
assetDataSource = new AssetDataSource(context);
|
||||
addListenersToDataSource(assetDataSource);
|
||||
}
|
||||
return assetDataSource;
|
||||
}
|
||||
|
||||
private DataSource getContentDataSource() {
|
||||
if (contentDataSource == null) {
|
||||
contentDataSource = new ContentDataSource(context, listener);
|
||||
contentDataSource = new ContentDataSource(context);
|
||||
addListenersToDataSource(contentDataSource);
|
||||
}
|
||||
return contentDataSource;
|
||||
}
|
||||
@ -205,6 +233,7 @@ public final class DefaultDataSource implements DataSource {
|
||||
Class<?> clazz = Class.forName("com.google.android.exoplayer2.ext.rtmp.RtmpDataSource");
|
||||
rtmpDataSource = (DataSource) clazz.getConstructor().newInstance();
|
||||
// LINT.ThenChange(../../../../../../../../proguard-rules.txt)
|
||||
addListenersToDataSource(rtmpDataSource);
|
||||
} catch (ClassNotFoundException e) {
|
||||
// Expected if the app was built without the RTMP extension.
|
||||
Log.w(TAG, "Attempting to play RTMP stream without depending on the RTMP extension");
|
||||
@ -222,14 +251,29 @@ public final class DefaultDataSource implements DataSource {
|
||||
private DataSource getDataSchemeDataSource() {
|
||||
if (dataSchemeDataSource == null) {
|
||||
dataSchemeDataSource = new DataSchemeDataSource();
|
||||
addListenersToDataSource(dataSchemeDataSource);
|
||||
}
|
||||
return dataSchemeDataSource;
|
||||
}
|
||||
|
||||
private DataSource getRawResourceDataSource() {
|
||||
if (rawResourceDataSource == null) {
|
||||
rawResourceDataSource = new RawResourceDataSource(context, listener);
|
||||
rawResourceDataSource = new RawResourceDataSource(context);
|
||||
addListenersToDataSource(rawResourceDataSource);
|
||||
}
|
||||
return rawResourceDataSource;
|
||||
}
|
||||
|
||||
private void addListenersToDataSource(DataSource dataSource) {
|
||||
for (int i = 0; i < transferListeners.size(); i++) {
|
||||
dataSource.addTransferListener(transferListeners.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeAddListenerToDataSource(
|
||||
@Nullable DataSource dataSource, TransferListener<? super DataSource> listener) {
|
||||
if (dataSource != null) {
|
||||
dataSource.addTransferListener(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.PriorityTaskManager;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A {@link DataSource} that can be used as part of a task registered with a
|
||||
@ -51,6 +53,11 @@ public final class PriorityDataSource implements DataSource {
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTransferListener(TransferListener<? super DataSource> transferListener) {
|
||||
upstream.addTransferListener(transferListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long open(DataSpec dataSpec) throws IOException {
|
||||
priorityTaskManager.proceedOrThrow(priority);
|
||||
@ -68,6 +75,11 @@ public final class PriorityDataSource implements DataSource {
|
||||
return upstream.getUri();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<String>> getResponseHeaders() {
|
||||
return upstream.getResponseHeaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
upstream.close();
|
||||
|
@ -70,6 +70,11 @@ public final class StatsDataSource implements DataSource {
|
||||
return lastResponseHeaders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTransferListener(TransferListener<? super DataSource> transferListener) {
|
||||
dataSource.addTransferListener(transferListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long open(DataSpec dataSpec) throws IOException {
|
||||
// Reassign defaults in case dataSource.open throws an exception.
|
||||
|
@ -16,9 +16,12 @@
|
||||
package com.google.android.exoplayer2.upstream;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Tees data into a {@link DataSink} as the data is read.
|
||||
@ -40,6 +43,11 @@ public final class TeeDataSource implements DataSource {
|
||||
this.dataSink = Assertions.checkNotNull(dataSink);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTransferListener(TransferListener<? super DataSource> transferListener) {
|
||||
upstream.addTransferListener(transferListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long open(DataSpec dataSpec) throws IOException {
|
||||
bytesRemaining = upstream.open(dataSpec);
|
||||
@ -79,10 +87,15 @@ public final class TeeDataSource implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri getUri() {
|
||||
public @Nullable Uri getUri() {
|
||||
return upstream.getUri();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<String>> getResponseHeaders() {
|
||||
return upstream.getResponseHeaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
try {
|
||||
|
@ -25,6 +25,7 @@ import com.google.android.exoplayer2.upstream.DataSourceException;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.FileDataSource;
|
||||
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 java.io.IOException;
|
||||
@ -119,7 +120,7 @@ public final class CacheDataSource implements DataSource {
|
||||
|
||||
private final Cache cache;
|
||||
private final DataSource cacheReadDataSource;
|
||||
private final DataSource cacheWriteDataSource;
|
||||
private final @Nullable DataSource cacheWriteDataSource;
|
||||
private final DataSource upstreamDataSource;
|
||||
private final CacheKeyFactory cacheKeyFactory;
|
||||
@Nullable private final EventListener eventListener;
|
||||
@ -128,15 +129,15 @@ public final class CacheDataSource implements DataSource {
|
||||
private final boolean ignoreCacheOnError;
|
||||
private final boolean ignoreCacheForUnsetLengthRequests;
|
||||
|
||||
private DataSource currentDataSource;
|
||||
private @Nullable DataSource currentDataSource;
|
||||
private boolean currentDataSpecLengthUnset;
|
||||
private Uri uri;
|
||||
private Uri actualUri;
|
||||
private @Nullable Uri uri;
|
||||
private @Nullable Uri actualUri;
|
||||
private int flags;
|
||||
private String key;
|
||||
private @Nullable String key;
|
||||
private long readPosition;
|
||||
private long bytesRemaining;
|
||||
private CacheSpan currentHoleSpan;
|
||||
private @Nullable CacheSpan currentHoleSpan;
|
||||
private boolean seenCacheError;
|
||||
private boolean currentRequestIgnoresCache;
|
||||
private long totalCachedBytesRead;
|
||||
@ -256,6 +257,12 @@ public final class CacheDataSource implements DataSource {
|
||||
this.eventListener = eventListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTransferListener(TransferListener<? super DataSource> transferListener) {
|
||||
cacheReadDataSource.addTransferListener(transferListener);
|
||||
upstreamDataSource.addTransferListener(transferListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long open(DataSpec dataSpec) throws IOException {
|
||||
try {
|
||||
@ -330,7 +337,7 @@ public final class CacheDataSource implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri getUri() {
|
||||
public @Nullable Uri getUri() {
|
||||
return actualUri;
|
||||
}
|
||||
|
||||
|
@ -16,9 +16,11 @@
|
||||
package com.google.android.exoplayer2.upstream.crypto;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.support.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.TransferListener;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -32,13 +34,18 @@ public final class AesCipherDataSource implements DataSource {
|
||||
private final DataSource upstream;
|
||||
private final byte[] secretKey;
|
||||
|
||||
private AesFlushingCipher cipher;
|
||||
private @Nullable AesFlushingCipher cipher;
|
||||
|
||||
public AesCipherDataSource(byte[] secretKey, DataSource upstream) {
|
||||
this.upstream = upstream;
|
||||
this.secretKey = secretKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTransferListener(TransferListener<? super DataSource> transferListener) {
|
||||
upstream.addTransferListener(transferListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long open(DataSpec dataSpec) throws IOException {
|
||||
long dataLength = upstream.open(dataSpec);
|
||||
@ -62,7 +69,7 @@ public final class AesCipherDataSource implements DataSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri getUri() {
|
||||
public @Nullable Uri getUri() {
|
||||
return upstream.getUri();
|
||||
}
|
||||
|
||||
|
@ -16,10 +16,12 @@
|
||||
package com.google.android.exoplayer2.source.hls;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSourceInputStream;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
@ -49,7 +51,7 @@ import javax.crypto.spec.SecretKeySpec;
|
||||
private final byte[] encryptionKey;
|
||||
private final byte[] encryptionIv;
|
||||
|
||||
private CipherInputStream cipherInputStream;
|
||||
private @Nullable CipherInputStream cipherInputStream;
|
||||
|
||||
/**
|
||||
* @param upstream The upstream {@link DataSource}.
|
||||
@ -62,6 +64,11 @@ import javax.crypto.spec.SecretKeySpec;
|
||||
this.encryptionIv = encryptionIv;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTransferListener(TransferListener<? super DataSource> transferListener) {
|
||||
upstream.addTransferListener(transferListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long open(DataSpec dataSpec) throws IOException {
|
||||
Cipher cipher;
|
||||
@ -89,7 +96,7 @@ import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
@Override
|
||||
public int read(byte[] buffer, int offset, int readLength) throws IOException {
|
||||
Assertions.checkState(cipherInputStream != null);
|
||||
Assertions.checkNotNull(cipherInputStream);
|
||||
int bytesRead = cipherInputStream.read(buffer, offset, readLength);
|
||||
if (bytesRead < 0) {
|
||||
return C.RESULT_END_OF_INPUT;
|
||||
@ -98,7 +105,7 @@ import javax.crypto.spec.SecretKeySpec;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri getUri() {
|
||||
public @Nullable Uri getUri() {
|
||||
return upstream.getUri();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user