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
This commit is contained in:
parent
df49f90b7f
commit
0bf40f8978
@ -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;
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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;
|
|||||||
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
|
|||||||
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
|
|||||||
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;
|
|||||||
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 {
|
|||||||
/** 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;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user