Simplify the error code handling.

PiperOrigin-RevId: 387786273
This commit is contained in:
claincly 2021-07-30 13:43:22 +01:00 committed by Christos Tsilopoulos
parent f19a3674f3
commit df49f90b7f
5 changed files with 160 additions and 101 deletions

View File

@ -358,16 +358,10 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource {
transferStarted(dataSpec); transferStarted(dataSpec);
try { try {
if (!skipFully(bytesToSkip)) { skipFully(bytesToSkip, dataSpec);
throw new DataSourceException(PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE); } catch (HttpDataSourceException e) {
}
} catch (IOException e) {
closeConnectionQuietly(); closeConnectionQuietly();
throw new HttpDataSourceException( throw e;
e,
dataSpec,
PlaybackException.ERROR_CODE_IO_UNSPECIFIED,
HttpDataSourceException.TYPE_OPEN);
} }
return bytesToRead; return bytesToRead;
@ -452,16 +446,17 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource {
* Attempts to skip the specified number of bytes in full. * Attempts to skip the specified number of bytes in full.
* *
* @param bytesToSkip The number of bytes to skip. * @param bytesToSkip The number of bytes to skip.
* @throws InterruptedIOException If the thread is interrupted during the operation. * @param dataSpec The {@link DataSpec}.
* @throws IOException If an error occurs reading from the source. * @throws HttpDataSourceException If the thread is interrupted during the operation, or an error
* @return Whether the bytes were skipped in full. If {@code false} then the data ended before the * occurs while reading from the source, or if the data ended before skipping the specified
* specified number of bytes were skipped. Always {@code true} if {@code bytesToSkip == 0}. * number of bytes.
*/ */
private boolean skipFully(long bytesToSkip) throws IOException { private void skipFully(long bytesToSkip, DataSpec dataSpec) throws HttpDataSourceException {
if (bytesToSkip == 0) { if (bytesToSkip == 0) {
return true; return;
} }
byte[] skipBuffer = new byte[4096]; byte[] skipBuffer = new byte[4096];
try {
while (bytesToSkip > 0) { while (bytesToSkip > 0) {
int readLength = (int) min(bytesToSkip, skipBuffer.length); int readLength = (int) min(bytesToSkip, skipBuffer.length);
int read = castNonNull(responseByteStream).read(skipBuffer, 0, readLength); int read = castNonNull(responseByteStream).read(skipBuffer, 0, readLength);
@ -469,12 +464,25 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource {
throw new InterruptedIOException(); throw new InterruptedIOException();
} }
if (read == -1) { if (read == -1) {
return false; throw new HttpDataSourceException(
dataSpec,
PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE,
HttpDataSourceException.TYPE_OPEN);
} }
bytesToSkip -= read; bytesToSkip -= read;
bytesTransferred(read); bytesTransferred(read);
} }
return true; return;
} catch (IOException e) {
if (e instanceof HttpDataSourceException) {
throw (HttpDataSourceException) e;
} else {
throw new HttpDataSourceException(
dataSpec,
PlaybackException.ERROR_CODE_IO_UNSPECIFIED,
HttpDataSourceException.TYPE_OPEN);
}
}
} }
/** /**

View File

@ -37,8 +37,8 @@ import java.io.InterruptedIOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.NoRouteToHostException; import java.net.NoRouteToHostException;
import java.net.ProtocolException;
import java.net.URL; import java.net.URL;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -459,11 +459,13 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
transferStarted(dataSpec); transferStarted(dataSpec);
try { try {
if (!skipFully(bytesToSkip)) { skipFully(bytesToSkip, dataSpec);
throw new DataSourceException(PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE);
}
} catch (IOException e) { } catch (IOException e) {
closeConnectionQuietly(); closeConnectionQuietly();
if (e instanceof HttpDataSourceException) {
throw (HttpDataSourceException) e;
}
throw new HttpDataSourceException( throw new HttpDataSourceException(
e, e,
dataSpec, dataSpec,
@ -562,7 +564,7 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
|| responseCode == HTTP_STATUS_TEMPORARY_REDIRECT || responseCode == HTTP_STATUS_TEMPORARY_REDIRECT
|| responseCode == HTTP_STATUS_PERMANENT_REDIRECT)) { || responseCode == HTTP_STATUS_PERMANENT_REDIRECT)) {
connection.disconnect(); connection.disconnect();
url = handleRedirect(url, location); url = handleRedirect(url, location, dataSpec);
} else if (httpMethod == DataSpec.HTTP_METHOD_POST } else if (httpMethod == DataSpec.HTTP_METHOD_POST
&& (responseCode == HttpURLConnection.HTTP_MULT_CHOICE && (responseCode == HttpURLConnection.HTTP_MULT_CHOICE
|| responseCode == HttpURLConnection.HTTP_MOVED_PERM || responseCode == HttpURLConnection.HTTP_MOVED_PERM
@ -576,14 +578,18 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
httpMethod = DataSpec.HTTP_METHOD_GET; httpMethod = DataSpec.HTTP_METHOD_GET;
httpBody = null; httpBody = null;
} }
url = handleRedirect(url, location); url = handleRedirect(url, location, dataSpec);
} else { } else {
return connection; return connection;
} }
} }
// If we get here we've been redirected more times than are permitted. // If we get here we've been redirected more times than are permitted.
throw new NoRouteToHostException("Too many redirects: " + redirectCount); throw new HttpDataSourceException(
new NoRouteToHostException("Too many redirects: " + redirectCount),
dataSpec,
PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED,
HttpDataSourceException.TYPE_OPEN);
} }
/** /**
@ -658,27 +664,50 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
* *
* @param originalUrl The original URL. * @param originalUrl The original URL.
* @param location The Location header in the response. May be {@code null}. * @param location The Location header in the response. May be {@code null}.
* @param dataSpec The {@link DataSpec}.
* @return The next URL. * @return The next URL.
* @throws IOException If redirection isn't possible. * @throws HttpDataSourceException If redirection isn't possible.
*/ */
private URL handleRedirect(URL originalUrl, @Nullable String location) throws IOException { private URL handleRedirect(URL originalUrl, @Nullable String location, DataSpec dataSpec)
throws HttpDataSourceException {
if (location == null) { if (location == null) {
throw new ProtocolException("Null location redirect"); throw new HttpDataSourceException(
"Null location redirect",
dataSpec,
PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED,
HttpDataSourceException.TYPE_OPEN);
} }
// Form the new url. // Form the new url.
URL url = new URL(originalUrl, location); URL url;
try {
url = new URL(originalUrl, location);
} catch (MalformedURLException e) {
throw new HttpDataSourceException(
e,
dataSpec,
PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED,
HttpDataSourceException.TYPE_OPEN);
}
// Check that the protocol of the new url is supported. // Check that the protocol of the new url is supported.
String protocol = url.getProtocol(); String protocol = url.getProtocol();
if (!"https".equals(protocol) && !"http".equals(protocol)) { if (!"https".equals(protocol) && !"http".equals(protocol)) {
throw new ProtocolException("Unsupported protocol redirect: " + protocol); throw new HttpDataSourceException(
"Unsupported protocol redirect: " + protocol,
dataSpec,
PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED,
HttpDataSourceException.TYPE_OPEN);
} }
if (!allowCrossProtocolRedirects && !protocol.equals(originalUrl.getProtocol())) { if (!allowCrossProtocolRedirects && !protocol.equals(originalUrl.getProtocol())) {
throw new ProtocolException( throw new HttpDataSourceException(
"Disallowed cross-protocol redirect (" "Disallowed cross-protocol redirect ("
+ originalUrl.getProtocol() + originalUrl.getProtocol()
+ " to " + " to "
+ protocol + protocol
+ ")"); + ")",
dataSpec,
PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED,
HttpDataSourceException.TYPE_OPEN);
} }
return url; return url;
} }
@ -687,29 +716,34 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
* Attempts to skip the specified number of bytes in full. * Attempts to skip the specified number of bytes in full.
* *
* @param bytesToSkip The number of bytes to skip. * @param bytesToSkip The number of bytes to skip.
* @throws InterruptedIOException If the thread is interrupted during the operation. * @param dataSpec The {@link DataSpec}.
* @throws IOException If an error occurs reading from the source. * @throws IOException If the thread is interrupted during the operation, or if the data ended
* @return Whether the bytes were skipped in full. If {@code false} then the data ended before the * before skipping the specified number of bytes.
* specified number of bytes were skipped. Always {@code true} if {@code bytesToSkip == 0}.
*/ */
private boolean skipFully(long bytesToSkip) throws IOException { private void skipFully(long bytesToSkip, DataSpec dataSpec) throws IOException {
if (bytesToSkip == 0) { if (bytesToSkip == 0) {
return true; return;
} }
byte[] skipBuffer = new byte[4096]; byte[] skipBuffer = new byte[4096];
while (bytesToSkip > 0) { while (bytesToSkip > 0) {
int readLength = (int) min(bytesToSkip, skipBuffer.length); int readLength = (int) min(bytesToSkip, skipBuffer.length);
int read = castNonNull(inputStream).read(skipBuffer, 0, readLength); int read = castNonNull(inputStream).read(skipBuffer, 0, readLength);
if (Thread.currentThread().isInterrupted()) { if (Thread.currentThread().isInterrupted()) {
throw new InterruptedIOException(); throw new HttpDataSourceException(
new InterruptedIOException(),
dataSpec,
PlaybackException.ERROR_CODE_IO_UNSPECIFIED,
HttpDataSourceException.TYPE_OPEN);
} }
if (read == -1) { if (read == -1) {
return false; throw new HttpDataSourceException(
dataSpec,
PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE,
HttpDataSourceException.TYPE_OPEN);
} }
bytesToSkip -= read; bytesToSkip -= read;
bytesTransferred(read); bytesTransferred(read);
} }
return true;
} }
/** /**

View File

@ -39,17 +39,12 @@ public final class ContentDataSource extends BaseDataSource {
/** @deprecated Use {@link #ContentDataSourceException(IOException, int)}. */ /** @deprecated Use {@link #ContentDataSourceException(IOException, int)}. */
@Deprecated @Deprecated
public ContentDataSourceException(IOException cause) { public ContentDataSourceException(IOException cause) {
super(cause, PlaybackException.ERROR_CODE_IO_UNSPECIFIED); this(cause, PlaybackException.ERROR_CODE_IO_UNSPECIFIED);
} }
/** /** Creates a new instance. */
* Creates a new instance.
*
* @param cause The error cause.
* @param errorCode See {@link PlaybackException.ErrorCode}.
*/
public ContentDataSourceException( public ContentDataSourceException(
IOException cause, @PlaybackException.ErrorCode int errorCode) { @Nullable IOException cause, @PlaybackException.ErrorCode int errorCode) {
super(cause, errorCode); super(cause, errorCode);
} }
} }
@ -78,7 +73,10 @@ public final class ContentDataSource extends BaseDataSource {
AssetFileDescriptor assetFileDescriptor = resolver.openAssetFileDescriptor(uri, "r"); AssetFileDescriptor assetFileDescriptor = resolver.openAssetFileDescriptor(uri, "r");
this.assetFileDescriptor = assetFileDescriptor; this.assetFileDescriptor = assetFileDescriptor;
if (assetFileDescriptor == null) { if (assetFileDescriptor == null) {
throw new FileNotFoundException("Could not open file descriptor for: " + uri); // openAssetFileDescriptor returns null if the provider recently crashed.
throw new ContentDataSourceException(
new IOException("Could not open file descriptor for: " + uri),
PlaybackException.ERROR_CODE_IO_UNSPECIFIED);
} }
long assetFileDescriptorLength = assetFileDescriptor.getLength(); long assetFileDescriptorLength = assetFileDescriptor.getLength();
@ -93,7 +91,8 @@ public final class ContentDataSource extends BaseDataSource {
// file. // file.
if (assetFileDescriptorLength != AssetFileDescriptor.UNKNOWN_LENGTH if (assetFileDescriptorLength != AssetFileDescriptor.UNKNOWN_LENGTH
&& dataSpec.position > assetFileDescriptorLength) { && dataSpec.position > assetFileDescriptorLength) {
throw new DataSourceException(PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE); throw new ContentDataSourceException(
/* cause= */ null, PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE);
} }
long assetFileDescriptorOffset = assetFileDescriptor.getStartOffset(); long assetFileDescriptorOffset = assetFileDescriptor.getStartOffset();
long skipped = long skipped =
@ -102,7 +101,8 @@ public final class ContentDataSource extends BaseDataSource {
if (skipped != dataSpec.position) { if (skipped != dataSpec.position) {
// We expect the skip to be satisfied in full. If it isn't then we're probably trying to // We expect the skip to be satisfied in full. If it isn't then we're probably trying to
// read beyond the end of the last resource in the file. // read beyond the end of the last resource in the file.
throw new DataSourceException(PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE); throw new ContentDataSourceException(
/* cause= */ null, PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE);
} }
if (assetFileDescriptorLength == AssetFileDescriptor.UNKNOWN_LENGTH) { if (assetFileDescriptorLength == AssetFileDescriptor.UNKNOWN_LENGTH) {
// The asset must extend to the end of the file. We can try and resolve the length with // The asset must extend to the end of the file. We can try and resolve the length with
@ -115,18 +115,25 @@ public final class ContentDataSource extends BaseDataSource {
bytesRemaining = channelSize - channel.position(); bytesRemaining = channelSize - channel.position();
if (bytesRemaining < 0) { if (bytesRemaining < 0) {
// The skip above was satisfied in full, but skipped beyond the end of the file. // The skip above was satisfied in full, but skipped beyond the end of the file.
throw new DataSourceException( throw new ContentDataSourceException(
PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE); /* cause= */ null, PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE);
} }
} }
} else { } else {
bytesRemaining = assetFileDescriptorLength - skipped; bytesRemaining = assetFileDescriptorLength - skipped;
if (bytesRemaining < 0) { if (bytesRemaining < 0) {
throw new DataSourceException(PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE); throw new ContentDataSourceException(
/* cause= */ null, PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE);
} }
} }
} catch (ContentDataSourceException e) {
throw e;
} catch (IOException e) { } catch (IOException e) {
throw new ContentDataSourceException(e, PlaybackException.ERROR_CODE_IO_UNSPECIFIED); throw new ContentDataSourceException(
e,
e instanceof FileNotFoundException
? PlaybackException.ERROR_CODE_IO_FILE_NOT_FOUND
: PlaybackException.ERROR_CODE_IO_UNSPECIFIED);
} }
if (dataSpec.length != C.LENGTH_UNSET) { if (dataSpec.length != C.LENGTH_UNSET) {

View File

@ -56,37 +56,24 @@ public final class RawResourceDataSource extends BaseDataSource {
/** Thrown when an {@link IOException} is encountered reading from a raw resource. */ /** Thrown when an {@link IOException} is encountered reading from a raw resource. */
public static class RawResourceDataSourceException extends DataSourceException { public static class RawResourceDataSourceException extends DataSourceException {
/** @deprecated Use {@link #RawResourceDataSourceException(String, int)}. */ /** @deprecated Use {@link #RawResourceDataSourceException(String, Throwable, int)}. */
@Deprecated @Deprecated
public RawResourceDataSourceException(String message) { public RawResourceDataSourceException(String message) {
super(message, PlaybackException.ERROR_CODE_IO_UNSPECIFIED); super(message, /* cause= */ null, PlaybackException.ERROR_CODE_IO_UNSPECIFIED);
} }
/** /** @deprecated Use {@link #RawResourceDataSourceException(String, Throwable, int)}. */
* Creates a new instance.
*
* @param message The error message.
* @param errorCode See {@link PlaybackException.ErrorCode}.
*/
public RawResourceDataSourceException(
String message, @PlaybackException.ErrorCode int errorCode) {
super(message, errorCode);
}
/** @deprecated Use {@link #RawResourceDataSourceException(Throwable, int)}. */
@Deprecated @Deprecated
public RawResourceDataSourceException(Throwable e) { public RawResourceDataSourceException(Throwable cause) {
super(e, PlaybackException.ERROR_CODE_IO_UNSPECIFIED); super(cause, PlaybackException.ERROR_CODE_IO_UNSPECIFIED);
} }
/** /** Creates a new instance. */
* Creates a new instance. public RawResourceDataSourceException(
* @Nullable String message,
* @param e The error cause. @Nullable Throwable cause,
* @param errorCode See {@link PlaybackException.ErrorCode}. @PlaybackException.ErrorCode int errorCode) {
*/ super(message, cause, errorCode);
public RawResourceDataSourceException(Throwable e, @PlaybackException.ErrorCode int errorCode) {
super(e, errorCode);
} }
} }
@ -134,7 +121,8 @@ public final class RawResourceDataSource extends BaseDataSource {
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new RawResourceDataSourceException( throw new RawResourceDataSourceException(
"Resource identifier must be an integer.", "Resource identifier must be an integer.",
PlaybackException.ERROR_CODE_IO_FILE_NOT_FOUND); /* cause= */ null,
PlaybackException.ERROR_CODE_FAILED_RUNTIME_CHECK);
} }
} else if (TextUtils.equals(ContentResolver.SCHEME_ANDROID_RESOURCE, uri.getScheme())) { } else if (TextUtils.equals(ContentResolver.SCHEME_ANDROID_RESOURCE, uri.getScheme())) {
String path = Assertions.checkNotNull(uri.getPath()); String path = Assertions.checkNotNull(uri.getPath());
@ -148,7 +136,9 @@ public final class RawResourceDataSource extends BaseDataSource {
resourceName, /* defType= */ "raw", /* defPackage= */ packageName); resourceName, /* defType= */ "raw", /* defPackage= */ packageName);
if (resourceId == 0) { if (resourceId == 0) {
throw new RawResourceDataSourceException( throw new RawResourceDataSourceException(
"Resource not found.", PlaybackException.ERROR_CODE_IO_FILE_NOT_FOUND); "Resource not found.",
/* cause= */ null,
PlaybackException.ERROR_CODE_IO_FILE_NOT_FOUND);
} }
} else { } else {
throw new RawResourceDataSourceException( throw new RawResourceDataSourceException(
@ -156,7 +146,8 @@ public final class RawResourceDataSource extends BaseDataSource {
+ RAW_RESOURCE_SCHEME + RAW_RESOURCE_SCHEME
+ " or " + " or "
+ ContentResolver.SCHEME_ANDROID_RESOURCE, + ContentResolver.SCHEME_ANDROID_RESOURCE,
PlaybackException.ERROR_CODE_IO_FILE_NOT_FOUND); /* cause= */ null,
PlaybackException.ERROR_CODE_FAILED_RUNTIME_CHECK);
} }
transferInitializing(dataSpec); transferInitializing(dataSpec);
@ -165,13 +156,16 @@ public final class RawResourceDataSource extends BaseDataSource {
try { try {
assetFileDescriptor = resources.openRawResourceFd(resourceId); assetFileDescriptor = resources.openRawResourceFd(resourceId);
} catch (Resources.NotFoundException e) { } catch (Resources.NotFoundException e) {
throw new RawResourceDataSourceException(e, PlaybackException.ERROR_CODE_IO_FILE_NOT_FOUND); throw new RawResourceDataSourceException(
/* message= */ null, e, PlaybackException.ERROR_CODE_IO_FILE_NOT_FOUND);
} }
this.assetFileDescriptor = assetFileDescriptor; this.assetFileDescriptor = assetFileDescriptor;
if (assetFileDescriptor == null) { if (assetFileDescriptor == null) {
throw new RawResourceDataSourceException( throw new RawResourceDataSourceException(
"Resource is compressed: " + uri, PlaybackException.ERROR_CODE_IO_UNSPECIFIED); "Resource is compressed: " + uri,
/* cause= */ null,
PlaybackException.ERROR_CODE_IO_UNSPECIFIED);
} }
long assetFileDescriptorLength = assetFileDescriptor.getLength(); long assetFileDescriptorLength = assetFileDescriptor.getLength();
@ -187,7 +181,10 @@ public final class RawResourceDataSource extends BaseDataSource {
// extends to the end of the file. // extends to the end of the file.
if (assetFileDescriptorLength != AssetFileDescriptor.UNKNOWN_LENGTH if (assetFileDescriptorLength != AssetFileDescriptor.UNKNOWN_LENGTH
&& dataSpec.position > assetFileDescriptorLength) { && dataSpec.position > assetFileDescriptorLength) {
throw new DataSourceException(PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE); throw new RawResourceDataSourceException(
/* message= */ null,
/* cause= */ null,
PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE);
} }
long assetFileDescriptorOffset = assetFileDescriptor.getStartOffset(); long assetFileDescriptorOffset = assetFileDescriptor.getStartOffset();
long skipped = long skipped =
@ -196,7 +193,10 @@ public final class RawResourceDataSource extends BaseDataSource {
if (skipped != dataSpec.position) { if (skipped != dataSpec.position) {
// We expect the skip to be satisfied in full. If it isn't then we're probably trying to // We expect the skip to be satisfied in full. If it isn't then we're probably trying to
// read beyond the end of the last resource in the file. // read beyond the end of the last resource in the file.
throw new DataSourceException(PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE); throw new RawResourceDataSourceException(
/* message= */ null,
/* cause= */ null,
PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE);
} }
if (assetFileDescriptorLength == AssetFileDescriptor.UNKNOWN_LENGTH) { if (assetFileDescriptorLength == AssetFileDescriptor.UNKNOWN_LENGTH) {
// The asset must extend to the end of the file. We can try and resolve the length with // The asset must extend to the end of the file. We can try and resolve the length with
@ -208,7 +208,9 @@ public final class RawResourceDataSource extends BaseDataSource {
bytesRemaining = channel.size() - channel.position(); bytesRemaining = channel.size() - channel.position();
if (bytesRemaining < 0) { if (bytesRemaining < 0) {
// The skip above was satisfied in full, but skipped beyond the end of the file. // The skip above was satisfied in full, but skipped beyond the end of the file.
throw new DataSourceException( throw new RawResourceDataSourceException(
/* message= */ null,
/* cause= */ null,
PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE); PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE);
} }
} }
@ -218,8 +220,11 @@ public final class RawResourceDataSource extends BaseDataSource {
throw new DataSourceException(PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE); throw new DataSourceException(PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE);
} }
} }
} catch (RawResourceDataSourceException e) {
throw e;
} catch (IOException e) { } catch (IOException e) {
throw new RawResourceDataSourceException(e, PlaybackException.ERROR_CODE_IO_UNSPECIFIED); throw new RawResourceDataSourceException(
/* message= */ null, e, PlaybackException.ERROR_CODE_IO_UNSPECIFIED);
} }
if (dataSpec.length != C.LENGTH_UNSET) { if (dataSpec.length != C.LENGTH_UNSET) {
@ -245,14 +250,17 @@ public final class RawResourceDataSource extends BaseDataSource {
bytesRemaining == C.LENGTH_UNSET ? length : (int) min(bytesRemaining, length); bytesRemaining == C.LENGTH_UNSET ? length : (int) min(bytesRemaining, length);
bytesRead = castNonNull(inputStream).read(buffer, offset, bytesToRead); bytesRead = castNonNull(inputStream).read(buffer, offset, bytesToRead);
} catch (IOException e) { } catch (IOException e) {
throw new RawResourceDataSourceException(e, PlaybackException.ERROR_CODE_IO_UNSPECIFIED); throw new RawResourceDataSourceException(
/* message= */ null, e, PlaybackException.ERROR_CODE_IO_UNSPECIFIED);
} }
if (bytesRead == -1) { if (bytesRead == -1) {
if (bytesRemaining != C.LENGTH_UNSET) { if (bytesRemaining != C.LENGTH_UNSET) {
// End of stream reached having not read sufficient data. // End of stream reached having not read sufficient data.
throw new RawResourceDataSourceException( throw new RawResourceDataSourceException(
new EOFException(), PlaybackException.ERROR_CODE_IO_UNSPECIFIED); "End of stream reached having not read sufficient data.",
new EOFException(),
PlaybackException.ERROR_CODE_IO_UNSPECIFIED);
} }
return C.RESULT_END_OF_INPUT; return C.RESULT_END_OF_INPUT;
} }
@ -278,7 +286,8 @@ public final class RawResourceDataSource extends BaseDataSource {
inputStream.close(); inputStream.close();
} }
} catch (IOException e) { } catch (IOException e) {
throw new RawResourceDataSourceException(e, PlaybackException.ERROR_CODE_IO_UNSPECIFIED); throw new RawResourceDataSourceException(
/* message= */ null, e, PlaybackException.ERROR_CODE_IO_UNSPECIFIED);
} finally { } finally {
inputStream = null; inputStream = null;
try { try {
@ -286,7 +295,8 @@ public final class RawResourceDataSource extends BaseDataSource {
assetFileDescriptor.close(); assetFileDescriptor.close();
} }
} catch (IOException e) { } catch (IOException e) {
throw new RawResourceDataSourceException(e, PlaybackException.ERROR_CODE_IO_UNSPECIFIED); throw new RawResourceDataSourceException(
/* message= */ null, e, PlaybackException.ERROR_CODE_IO_UNSPECIFIED);
} finally { } finally {
assetFileDescriptor = null; assetFileDescriptor = null;
if (opened) { if (opened) {