Finish cleaning DataSource implementations.
- Enfroce read returns 0 if readLength==0 everywhere. - Fixes and simplifications for CronetDataSource. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=135138232
This commit is contained in:
parent
f8ed4cfdee
commit
b3c6f1caae
@ -28,7 +28,6 @@ import com.google.android.exoplayer2.util.Assertions;
|
|||||||
import com.google.android.exoplayer2.util.Clock;
|
import com.google.android.exoplayer2.util.Clock;
|
||||||
import com.google.android.exoplayer2.util.Predicate;
|
import com.google.android.exoplayer2.util.Predicate;
|
||||||
import com.google.android.exoplayer2.util.SystemClock;
|
import com.google.android.exoplayer2.util.SystemClock;
|
||||||
import com.google.android.exoplayer2.util.TraceUtil;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
@ -99,7 +98,7 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
|
|||||||
private final CronetEngine cronetEngine;
|
private final CronetEngine cronetEngine;
|
||||||
private final Executor executor;
|
private final Executor executor;
|
||||||
private final Predicate<String> contentTypePredicate;
|
private final Predicate<String> contentTypePredicate;
|
||||||
private final TransferListener transferListener;
|
private final TransferListener<? super CronetDataSource> listener;
|
||||||
private final int connectTimeoutMs;
|
private final int connectTimeoutMs;
|
||||||
private final int readTimeoutMs;
|
private final int readTimeoutMs;
|
||||||
private final boolean resetTimeoutOnRedirects;
|
private final boolean resetTimeoutOnRedirects;
|
||||||
@ -127,12 +126,12 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
|
|||||||
* @param contentTypePredicate An optional {@link Predicate}. If a content type is rejected by the
|
* @param contentTypePredicate An optional {@link Predicate}. If a content type is rejected by the
|
||||||
* predicate then an {@link InvalidContentTypeException} is thrown from
|
* predicate then an {@link InvalidContentTypeException} is thrown from
|
||||||
* {@link #open(DataSpec)}.
|
* {@link #open(DataSpec)}.
|
||||||
* @param transferListener A listener.
|
* @param listener An optional listener.
|
||||||
*/
|
*/
|
||||||
public CronetDataSource(CronetEngine cronetEngine, Executor executor,
|
public CronetDataSource(CronetEngine cronetEngine, Executor executor,
|
||||||
Predicate<String> contentTypePredicate, TransferListener transferListener) {
|
Predicate<String> contentTypePredicate, TransferListener<? super CronetDataSource> listener) {
|
||||||
this(cronetEngine, executor, contentTypePredicate, transferListener,
|
this(cronetEngine, executor, contentTypePredicate, listener, DEFAULT_CONNECT_TIMEOUT_MILLIS,
|
||||||
DEFAULT_CONNECT_TIMEOUT_MILLIS, DEFAULT_READ_TIMEOUT_MILLIS, false);
|
DEFAULT_READ_TIMEOUT_MILLIS, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -141,25 +140,25 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
|
|||||||
* @param contentTypePredicate An optional {@link Predicate}. If a content type is rejected by the
|
* @param contentTypePredicate An optional {@link Predicate}. If a content type is rejected by the
|
||||||
* predicate then an {@link InvalidContentTypeException} is thrown from
|
* predicate then an {@link InvalidContentTypeException} is thrown from
|
||||||
* {@link #open(DataSpec)}.
|
* {@link #open(DataSpec)}.
|
||||||
* @param transferListener A listener.
|
* @param listener An optional listener.
|
||||||
* @param connectTimeoutMs The connection timeout, in milliseconds.
|
* @param connectTimeoutMs The connection timeout, in milliseconds.
|
||||||
* @param readTimeoutMs The read timeout, in milliseconds.
|
* @param readTimeoutMs The read timeout, in milliseconds.
|
||||||
* @param resetTimeoutOnRedirects Whether the connect timeout is reset when a redirect occurs.
|
* @param resetTimeoutOnRedirects Whether the connect timeout is reset when a redirect occurs.
|
||||||
*/
|
*/
|
||||||
public CronetDataSource(CronetEngine cronetEngine, Executor executor,
|
public CronetDataSource(CronetEngine cronetEngine, Executor executor,
|
||||||
Predicate<String> contentTypePredicate, TransferListener transferListener,
|
Predicate<String> contentTypePredicate, TransferListener<? super CronetDataSource> listener,
|
||||||
int connectTimeoutMs, int readTimeoutMs, boolean resetTimeoutOnRedirects) {
|
int connectTimeoutMs, int readTimeoutMs, boolean resetTimeoutOnRedirects) {
|
||||||
this(cronetEngine, executor, contentTypePredicate, transferListener, connectTimeoutMs,
|
this(cronetEngine, executor, contentTypePredicate, listener, connectTimeoutMs,
|
||||||
readTimeoutMs, resetTimeoutOnRedirects, new SystemClock());
|
readTimeoutMs, resetTimeoutOnRedirects, new SystemClock());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ CronetDataSource(CronetEngine cronetEngine, Executor executor,
|
/* package */ CronetDataSource(CronetEngine cronetEngine, Executor executor,
|
||||||
Predicate<String> contentTypePredicate, TransferListener transferListener,
|
Predicate<String> contentTypePredicate, TransferListener<? super CronetDataSource> listener,
|
||||||
int connectTimeoutMs, int readTimeoutMs, boolean resetTimeoutOnRedirects, Clock clock) {
|
int connectTimeoutMs, int readTimeoutMs, boolean resetTimeoutOnRedirects, Clock clock) {
|
||||||
this.cronetEngine = Assertions.checkNotNull(cronetEngine);
|
this.cronetEngine = Assertions.checkNotNull(cronetEngine);
|
||||||
this.executor = Assertions.checkNotNull(executor);
|
this.executor = Assertions.checkNotNull(executor);
|
||||||
this.contentTypePredicate = contentTypePredicate;
|
this.contentTypePredicate = contentTypePredicate;
|
||||||
this.transferListener = transferListener;
|
this.listener = listener;
|
||||||
this.connectTimeoutMs = connectTimeoutMs;
|
this.connectTimeoutMs = connectTimeoutMs;
|
||||||
this.readTimeoutMs = readTimeoutMs;
|
this.readTimeoutMs = readTimeoutMs;
|
||||||
this.resetTimeoutOnRedirects = resetTimeoutOnRedirects;
|
this.resetTimeoutOnRedirects = resetTimeoutOnRedirects;
|
||||||
@ -198,8 +197,6 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long open(DataSpec dataSpec) throws HttpDataSourceException {
|
public long open(DataSpec dataSpec) throws HttpDataSourceException {
|
||||||
TraceUtil.beginSection("CronetDataSource.open");
|
|
||||||
try {
|
|
||||||
Assertions.checkNotNull(dataSpec);
|
Assertions.checkNotNull(dataSpec);
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
Assertions.checkState(connectionState == IDLE_CONNECTION, "Connection already open");
|
Assertions.checkState(connectionState == IDLE_CONNECTION, "Connection already open");
|
||||||
@ -220,14 +217,11 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Connection was opened.
|
// Connection was opened.
|
||||||
if (transferListener != null) {
|
if (listener != null) {
|
||||||
transferListener.onTransferStart(this, dataSpec);
|
listener.onTransferStart(this, dataSpec);
|
||||||
}
|
}
|
||||||
connectionState = OPEN_CONNECTION;
|
connectionState = OPEN_CONNECTION;
|
||||||
return contentLength;
|
return contentLength;
|
||||||
} finally {
|
|
||||||
TraceUtil.endSection();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startRequest(DataSpec dataSpec) throws HttpDataSourceException {
|
private void startRequest(DataSpec dataSpec) throws HttpDataSourceException {
|
||||||
@ -274,8 +268,8 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void onFailed(
|
public synchronized void onFailed(UrlRequest request, UrlResponseInfo info,
|
||||||
UrlRequest request, UrlResponseInfo info, UrlRequestException error) {
|
UrlRequestException error) {
|
||||||
if (request != currentUrlRequest) {
|
if (request != currentUrlRequest) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -284,7 +278,6 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
|
|||||||
? new UnknownHostException() : error;
|
? new UnknownHostException() : error;
|
||||||
exception = new OpenException(cause, currentDataSpec, getCurrentRequestStatus());
|
exception = new OpenException(cause, currentDataSpec, getCurrentRequestStatus());
|
||||||
} else if (connectionState == OPEN_CONNECTION) {
|
} else if (connectionState == OPEN_CONNECTION) {
|
||||||
readBuffer.limit(0);
|
|
||||||
exception = new HttpDataSourceException(error, currentDataSpec,
|
exception = new HttpDataSourceException(error, currentDataSpec,
|
||||||
HttpDataSourceException.TYPE_READ);
|
HttpDataSourceException.TYPE_READ);
|
||||||
}
|
}
|
||||||
@ -296,7 +289,6 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
|
|||||||
if (request != currentUrlRequest) {
|
if (request != currentUrlRequest) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TraceUtil.beginSection("CronetDataSource.onResponseStarted");
|
|
||||||
try {
|
try {
|
||||||
validateResponse(info);
|
validateResponse(info);
|
||||||
responseInfo = info;
|
responseInfo = info;
|
||||||
@ -327,7 +319,6 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
|
|||||||
exception = e;
|
exception = e;
|
||||||
} finally {
|
} finally {
|
||||||
operation.open();
|
operation.open();
|
||||||
TraceUtil.endSection();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,23 +406,21 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read(byte[] buffer, int offset, int readLength) throws HttpDataSourceException {
|
public int read(byte[] buffer, int offset, int readLength) throws HttpDataSourceException {
|
||||||
TraceUtil.beginSection("CronetDataSource.read");
|
|
||||||
try {
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (connectionState != OPEN_CONNECTION) {
|
Assertions.checkState(connectionState == OPEN_CONNECTION);
|
||||||
throw new IllegalStateException("Connection not ready");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If being asked to read beyond the amount of bytes initially requested, return
|
if (readLength == 0) {
|
||||||
// RESULT_END_OF_INPUT.
|
return 0;
|
||||||
if (expectedBytesRemainingToRead != null && expectedBytesRemainingToRead.get() <= 0) {
|
}
|
||||||
|
if (expectedBytesRemainingToRead != null && expectedBytesRemainingToRead.get() == 0) {
|
||||||
return C.RESULT_END_OF_INPUT;
|
return C.RESULT_END_OF_INPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasData) {
|
if (!hasData) {
|
||||||
// Read more data from cronet.
|
// Read more data from cronet.
|
||||||
operation.close();
|
operation.close();
|
||||||
|
readBuffer.clear();
|
||||||
currentUrlRequest.read(readBuffer);
|
currentUrlRequest.read(readBuffer);
|
||||||
if (!operation.block(readTimeoutMs)) {
|
if (!operation.block(readTimeoutMs)) {
|
||||||
throw new HttpDataSourceException(
|
throw new HttpDataSourceException(
|
||||||
@ -448,25 +437,18 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
|
|||||||
}
|
}
|
||||||
|
|
||||||
int bytesRead = Math.min(readBuffer.remaining(), readLength);
|
int bytesRead = Math.min(readBuffer.remaining(), readLength);
|
||||||
|
|
||||||
readBuffer.get(buffer, offset, bytesRead);
|
readBuffer.get(buffer, offset, bytesRead);
|
||||||
|
|
||||||
if (!readBuffer.hasRemaining()) {
|
if (!readBuffer.hasRemaining()) {
|
||||||
readBuffer.clear();
|
|
||||||
hasData = false;
|
hasData = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expectedBytesRemainingToRead != null) {
|
if (expectedBytesRemainingToRead != null) {
|
||||||
expectedBytesRemainingToRead.addAndGet(-bytesRead);
|
expectedBytesRemainingToRead.addAndGet(-bytesRead);
|
||||||
}
|
}
|
||||||
|
if (listener != null) {
|
||||||
if (transferListener != null && bytesRead >= 0) {
|
listener.onBytesTransferred(this, bytesRead);
|
||||||
transferListener.onBytesTransferred(this, bytesRead);
|
|
||||||
}
|
}
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
} finally {
|
|
||||||
TraceUtil.endSection();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -499,9 +481,7 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
readBuffer.flip();
|
readBuffer.flip();
|
||||||
if (readBuffer.limit() > 0) {
|
|
||||||
hasData = true;
|
hasData = true;
|
||||||
}
|
|
||||||
operation.open();
|
operation.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,13 +496,10 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void close() {
|
public synchronized void close() {
|
||||||
TraceUtil.beginSection("CronetDataSource.close");
|
|
||||||
try {
|
|
||||||
if (currentUrlRequest != null) {
|
if (currentUrlRequest != null) {
|
||||||
currentUrlRequest.cancel();
|
currentUrlRequest.cancel();
|
||||||
currentUrlRequest = null;
|
currentUrlRequest = null;
|
||||||
}
|
}
|
||||||
readBuffer.clear();
|
|
||||||
currentDataSpec = null;
|
currentDataSpec = null;
|
||||||
currentUrl = null;
|
currentUrl = null;
|
||||||
exception = null;
|
exception = null;
|
||||||
@ -531,12 +508,12 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
|
|||||||
responseInfo = null;
|
responseInfo = null;
|
||||||
expectedBytesRemainingToRead = null;
|
expectedBytesRemainingToRead = null;
|
||||||
responseFinished = false;
|
responseFinished = false;
|
||||||
if (transferListener != null && connectionState == OPEN_CONNECTION) {
|
try {
|
||||||
transferListener.onTransferEnd(this);
|
if (listener != null && connectionState == OPEN_CONNECTION) {
|
||||||
|
listener.onTransferEnd(this);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
connectionState = IDLE_CONNECTION;
|
connectionState = IDLE_CONNECTION;
|
||||||
TraceUtil.endSection();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +80,9 @@ public final class FileDataSource implements DataSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read(byte[] buffer, int offset, int readLength) throws FileDataSourceException {
|
public int read(byte[] buffer, int offset, int readLength) throws FileDataSourceException {
|
||||||
if (bytesRemaining == 0) {
|
if (readLength == 0) {
|
||||||
|
return 0;
|
||||||
|
} else if (bytesRemaining == 0) {
|
||||||
return C.RESULT_END_OF_INPUT;
|
return C.RESULT_END_OF_INPUT;
|
||||||
} else {
|
} else {
|
||||||
int bytesRead;
|
int bytesRead;
|
||||||
|
@ -129,6 +129,10 @@ public final class UdpDataSource implements DataSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read(byte[] buffer, int offset, int readLength) throws UdpDataSourceException {
|
public int read(byte[] buffer, int offset, int readLength) throws UdpDataSourceException {
|
||||||
|
if (readLength == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (packetRemaining == 0) {
|
if (packetRemaining == 0) {
|
||||||
// We've read all of the data from the current packet. Get another.
|
// We've read all of the data from the current packet. Get another.
|
||||||
try {
|
try {
|
||||||
@ -136,7 +140,6 @@ public final class UdpDataSource implements DataSource {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new UdpDataSourceException(e);
|
throw new UdpDataSourceException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
packetRemaining = packet.getLength();
|
packetRemaining = packet.getLength();
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
listener.onBytesTransferred(this, packetRemaining);
|
listener.onBytesTransferred(this, packetRemaining);
|
||||||
|
@ -194,12 +194,15 @@ public final class CacheDataSource implements DataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read(byte[] buffer, int offset, int max) throws IOException {
|
public int read(byte[] buffer, int offset, int readLength) throws IOException {
|
||||||
|
if (readLength == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (bytesRemaining == 0) {
|
if (bytesRemaining == 0) {
|
||||||
return C.RESULT_END_OF_INPUT;
|
return C.RESULT_END_OF_INPUT;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
int bytesRead = currentDataSource.read(buffer, offset, max);
|
int bytesRead = currentDataSource.read(buffer, offset, readLength);
|
||||||
if (bytesRead >= 0) {
|
if (bytesRead >= 0) {
|
||||||
if (currentDataSource == cacheReadDataSource) {
|
if (currentDataSource == cacheReadDataSource) {
|
||||||
totalCachedBytesRead += bytesRead;
|
totalCachedBytesRead += bytesRead;
|
||||||
@ -218,7 +221,7 @@ public final class CacheDataSource implements DataSource {
|
|||||||
closeCurrentSource();
|
closeCurrentSource();
|
||||||
if (bytesRemaining > 0 || bytesRemaining == C.LENGTH_UNSET) {
|
if (bytesRemaining > 0 || bytesRemaining == C.LENGTH_UNSET) {
|
||||||
if (openNextSource(false)) {
|
if (openNextSource(false)) {
|
||||||
return read(buffer, offset, max);
|
return read(buffer, offset, readLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user