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.contains("net::ERR_INTERNET_DISCONNECTED")) {
|
||||
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) {
|
||||
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) {
|
||||
|
@ -33,7 +33,6 @@ import com.google.android.exoplayer2.upstream.HttpUtil;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import com.google.common.base.Ascii;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.net.HttpHeaders;
|
||||
import java.io.IOException;
|
||||
@ -289,17 +288,8 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource {
|
||||
responseBody = Assertions.checkNotNull(response.body());
|
||||
responseByteStream = responseBody.byteStream();
|
||||
} catch (IOException e) {
|
||||
@Nullable String message = e.getMessage();
|
||||
if (message != null
|
||||
&& 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);
|
||||
throw HttpDataSourceException.createForIOException(
|
||||
e, dataSpec, HttpDataSourceException.TYPE_OPEN);
|
||||
}
|
||||
|
||||
int responseCode = response.code();
|
||||
@ -372,11 +362,8 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource {
|
||||
try {
|
||||
return readInternal(buffer, offset, length);
|
||||
} catch (IOException e) {
|
||||
throw new HttpDataSourceException(
|
||||
e,
|
||||
Assertions.checkNotNull(dataSpec),
|
||||
PlaybackException.ERROR_CODE_IO_UNSPECIFIED,
|
||||
HttpDataSourceException.TYPE_READ);
|
||||
throw HttpDataSourceException.createForIOException(
|
||||
e, castNonNull(dataSpec), 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.util.Log;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import com.google.common.base.Ascii;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.net.HttpHeaders;
|
||||
import java.io.IOException;
|
||||
@ -347,35 +346,17 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
|
||||
bytesToRead = 0;
|
||||
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;
|
||||
HttpURLConnection connection;
|
||||
try {
|
||||
this.connection = makeConnection(dataSpec);
|
||||
connection = this.connection;
|
||||
responseCode = connection.getResponseCode();
|
||||
responseMessage = connection.getResponseMessage();
|
||||
} catch (IOException e) {
|
||||
closeConnectionQuietly();
|
||||
throw new HttpDataSourceException(
|
||||
"Unable to connect",
|
||||
e,
|
||||
dataSpec,
|
||||
PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED,
|
||||
HttpDataSourceException.TYPE_OPEN);
|
||||
throw HttpDataSourceException.createForIOException(
|
||||
e, dataSpec, HttpDataSourceException.TYPE_OPEN);
|
||||
}
|
||||
|
||||
// Check for a valid response code.
|
||||
@ -481,11 +462,8 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
|
||||
try {
|
||||
return readInternal(buffer, offset, length);
|
||||
} catch (IOException e) {
|
||||
throw new HttpDataSourceException(
|
||||
e,
|
||||
castNonNull(dataSpec),
|
||||
PlaybackException.ERROR_CODE_IO_UNSPECIFIED,
|
||||
HttpDataSourceException.TYPE_READ);
|
||||
throw HttpDataSourceException.createForIOException(
|
||||
e, castNonNull(dataSpec), HttpDataSourceException.TYPE_READ);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,8 @@ import java.io.IOException;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -207,6 +209,36 @@ public interface HttpDataSource extends DataSource {
|
||||
/** The error occurred in closing a {@code HttpDataSource}. */
|
||||
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. */
|
||||
public final DataSpec dataSpec;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user