Commit 0bf40f89 by claincly Committed by Christos Tsilopoulos

Fix some ErrorCode assigning cases.

DefaultHttpDataSource and OkHttpDataSource can share the same error code
assigning logic.

Fixes CronetDataSource's handling of closed connection.

PiperOrigin-RevId: 387791679
parent df49f90b
...@@ -1126,13 +1126,15 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource { ...@@ -1126,13 +1126,15 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource {
if (message != null) { if (message != null) {
if (message.contains("net::ERR_INTERNET_DISCONNECTED")) { if (message.contains("net::ERR_INTERNET_DISCONNECTED")) {
return PlaybackException.ERROR_CODE_IO_NETWORK_UNAVAILABLE; return PlaybackException.ERROR_CODE_IO_NETWORK_UNAVAILABLE;
} else if (message.contains("net::ERR_CONTENT_LENGTH_MISMATCH")
|| message.contains("net::ERR_SOCKET_NOT_CONNECTED")) {
return PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_CLOSED;
} }
} }
if (occurredWhileOpeningConnection) { if (occurredWhileOpeningConnection) {
return PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED; return PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED;
} else {
return PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_CLOSED;
} }
return PlaybackException.ERROR_CODE_IO_UNSPECIFIED;
} }
private static boolean isCompressed(UrlResponseInfo info) { private static boolean isCompressed(UrlResponseInfo info) {
......
...@@ -33,7 +33,6 @@ import com.google.android.exoplayer2.upstream.HttpUtil; ...@@ -33,7 +33,6 @@ import com.google.android.exoplayer2.upstream.HttpUtil;
import com.google.android.exoplayer2.upstream.TransferListener; import com.google.android.exoplayer2.upstream.TransferListener;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.common.base.Ascii;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.net.HttpHeaders; import com.google.common.net.HttpHeaders;
import java.io.IOException; import java.io.IOException;
...@@ -289,17 +288,8 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource { ...@@ -289,17 +288,8 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource {
responseBody = Assertions.checkNotNull(response.body()); responseBody = Assertions.checkNotNull(response.body());
responseByteStream = responseBody.byteStream(); responseByteStream = responseBody.byteStream();
} catch (IOException e) { } catch (IOException e) {
@Nullable String message = e.getMessage(); throw HttpDataSourceException.createForIOException(
if (message != null e, dataSpec, HttpDataSourceException.TYPE_OPEN);
&& Ascii.toLowerCase(message).matches("cleartext communication.*not permitted.*")) {
throw new CleartextNotPermittedException(e, dataSpec);
}
throw new HttpDataSourceException(
"Unable to connect",
e,
dataSpec,
PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED,
HttpDataSourceException.TYPE_OPEN);
} }
int responseCode = response.code(); int responseCode = response.code();
...@@ -372,11 +362,8 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource { ...@@ -372,11 +362,8 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource {
try { try {
return readInternal(buffer, offset, length); return readInternal(buffer, offset, length);
} catch (IOException e) { } catch (IOException e) {
throw new HttpDataSourceException( throw HttpDataSourceException.createForIOException(
e, e, castNonNull(dataSpec), HttpDataSourceException.TYPE_READ);
Assertions.checkNotNull(dataSpec),
PlaybackException.ERROR_CODE_IO_UNSPECIFIED,
HttpDataSourceException.TYPE_READ);
} }
} }
......
...@@ -28,7 +28,6 @@ import com.google.android.exoplayer2.PlaybackException; ...@@ -28,7 +28,6 @@ import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.upstream.DataSpec.HttpMethod; import com.google.android.exoplayer2.upstream.DataSpec.HttpMethod;
import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.common.base.Ascii;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.net.HttpHeaders; import com.google.common.net.HttpHeaders;
import java.io.IOException; import java.io.IOException;
...@@ -347,35 +346,17 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou ...@@ -347,35 +346,17 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
bytesToRead = 0; bytesToRead = 0;
transferInitializing(dataSpec); transferInitializing(dataSpec);
try {
connection = makeConnection(dataSpec);
} catch (IOException e) {
@Nullable String message = e.getMessage();
if (message != null
&& Ascii.toLowerCase(message).matches("cleartext http traffic.*not permitted.*")) {
throw new CleartextNotPermittedException(e, dataSpec);
}
throw new HttpDataSourceException(
"Unable to connect",
e,
dataSpec,
PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED,
HttpDataSourceException.TYPE_OPEN);
}
HttpURLConnection connection = this.connection;
String responseMessage; String responseMessage;
HttpURLConnection connection;
try { try {
this.connection = makeConnection(dataSpec);
connection = this.connection;
responseCode = connection.getResponseCode(); responseCode = connection.getResponseCode();
responseMessage = connection.getResponseMessage(); responseMessage = connection.getResponseMessage();
} catch (IOException e) { } catch (IOException e) {
closeConnectionQuietly(); closeConnectionQuietly();
throw new HttpDataSourceException( throw HttpDataSourceException.createForIOException(
"Unable to connect", e, dataSpec, HttpDataSourceException.TYPE_OPEN);
e,
dataSpec,
PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED,
HttpDataSourceException.TYPE_OPEN);
} }
// Check for a valid response code. // Check for a valid response code.
...@@ -481,11 +462,8 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou ...@@ -481,11 +462,8 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
try { try {
return readInternal(buffer, offset, length); return readInternal(buffer, offset, length);
} catch (IOException e) { } catch (IOException e) {
throw new HttpDataSourceException( throw HttpDataSourceException.createForIOException(
e, e, castNonNull(dataSpec), HttpDataSourceException.TYPE_READ);
castNonNull(dataSpec),
PlaybackException.ERROR_CODE_IO_UNSPECIFIED,
HttpDataSourceException.TYPE_READ);
} }
} }
......
...@@ -26,6 +26,8 @@ import java.io.IOException; ...@@ -26,6 +26,8 @@ import java.io.IOException;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
...@@ -207,6 +209,36 @@ public interface HttpDataSource extends DataSource { ...@@ -207,6 +209,36 @@ public interface HttpDataSource extends DataSource {
/** The error occurred in closing a {@code HttpDataSource}. */ /** The error occurred in closing a {@code HttpDataSource}. */
public static final int TYPE_CLOSE = 3; public static final int TYPE_CLOSE = 3;
/**
* Returns a {@code HttpDataSourceException} whose error code is assigned according to the cause
* and type.
*/
public static HttpDataSourceException createForIOException(
IOException cause, DataSpec dataSpec, @Type int type) {
@PlaybackException.ErrorCode int errorCode = PlaybackException.ERROR_CODE_IO_UNSPECIFIED;
if (cause instanceof SocketTimeoutException) {
errorCode = PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT;
} else if (cause instanceof UnknownHostException) {
errorCode = PlaybackException.ERROR_CODE_IO_DNS_FAILED;
} else {
@Nullable String message = cause.getMessage();
if (message != null) {
if (Ascii.toLowerCase(message).matches("cleartext.*not permitted.*")) {
errorCode = PlaybackException.ERROR_CODE_IO_CLEARTEXT_NOT_PERMITTED;
} else if (message.contains("unexpected end of stream")) {
errorCode = PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_CLOSED;
}
}
if (type == TYPE_OPEN && errorCode == PlaybackException.ERROR_CODE_IO_UNSPECIFIED) {
errorCode = PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED;
}
}
return errorCode == PlaybackException.ERROR_CODE_IO_CLEARTEXT_NOT_PERMITTED
? new CleartextNotPermittedException(cause, dataSpec)
: new HttpDataSourceException(cause, dataSpec, errorCode, type);
}
/** The {@link DataSpec} associated with the current connection. */ /** The {@link DataSpec} associated with the current connection. */
public final DataSpec dataSpec; public final DataSpec dataSpec;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment