summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Tobias Thierer <tobiast@google.com> 2019-03-22 11:15:44 +0000
committer Tobias Thierer <tobiast@google.com> 2019-04-08 18:14:04 +0000
commit241377b10a732fa11eaa2be32e4106519a062a8f (patch)
tree6d57c1f7509daa3a8180fa3c4807372708aa4b17
parentdd07ae579c291a2b6ffe09bd576fd908eb9e5ddd (diff)
Revert "MediaHTTPConnection: move connection states into an inner class"
This reverts commit 621e7968adf0253d5e22406f02ccc8bcc0eda5ec. Many of the fields that were moved are annotated @UnsupportedAppUsage, so the CL would have had undesirable app compat impact. Further, because investigation has revealed that lock contention *is* possible, we need to always acquire the lock anyway so there is no longer a benefit in keeping all of the mutable state in a single field that can be atomically set to null. Bug: 114337214 Test: Treehugger (cherry picked from commit dc9f4b4d5d28fc68b1b5e4e8500bf67d4b11621d) Change-Id: I202c5653cb086d99228491e161a159bad640105a Merged-In: I202c5653cb086d99228491e161a159bad640105a
-rw-r--r--media/java/android/media/MediaHTTPConnection.java209
-rw-r--r--media/jni/android_media_MediaHTTPConnection.cpp9
2 files changed, 93 insertions, 125 deletions
diff --git a/media/java/android/media/MediaHTTPConnection.java b/media/java/android/media/MediaHTTPConnection.java
index 3838a99969f0..d72476269e18 100644
--- a/media/java/android/media/MediaHTTPConnection.java
+++ b/media/java/android/media/MediaHTTPConnection.java
@@ -37,7 +37,6 @@ import java.net.URL;
import java.net.UnknownServiceException;
import java.util.HashMap;
import java.util.Map;
-import java.util.concurrent.atomic.AtomicReference;
/** @hide */
public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
@@ -47,23 +46,27 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
// connection timeout - 30 sec
private static final int CONNECT_TIMEOUT_MS = 30 * 1000;
+ @UnsupportedAppUsage
+ private long mCurrentOffset = -1;
+ @UnsupportedAppUsage
+ private URL mURL = null;
+ @UnsupportedAppUsage
+ private Map<String, String> mHeaders = null;
+ @UnsupportedAppUsage
+ private HttpURLConnection mConnection = null;
+ @UnsupportedAppUsage
+ private long mTotalSize = -1;
+ private InputStream mInputStream = null;
+
+ @UnsupportedAppUsage
+ private boolean mAllowCrossDomainRedirect = true;
+ @UnsupportedAppUsage
+ private boolean mAllowCrossProtocolRedirect = true;
+
// from com.squareup.okhttp.internal.http
private final static int HTTP_TEMP_REDIRECT = 307;
private final static int MAX_REDIRECTS = 20;
- class ConnectionState {
- public HttpURLConnection mConnection = null;
- public InputStream mInputStream = null;
- public long mCurrentOffset = -1;
- public Map<String, String> mHeaders = null;
- public URL mURL = null;
- public long mTotalSize = -1;
- public boolean mAllowCrossDomainRedirect = true;
- public boolean mAllowCrossProtocolRedirect = true;
- }
- private final AtomicReference<ConnectionState> mConnectionStateHolder =
- new AtomicReference<ConnectionState>();
-
@UnsupportedAppUsage
public MediaHTTPConnection() {
CookieHandler cookieHandler = CookieHandler.getDefault();
@@ -81,23 +84,13 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
Log.d(TAG, "connect: uri=" + uri + ", headers=" + headers);
}
- ConnectionState connectionState = mConnectionStateHolder.get();
- synchronized (this) {
- if (connectionState == null) {
- connectionState = new ConnectionState();
- mConnectionStateHolder.set(connectionState);
- }
- }
-
try {
disconnect();
- connectionState.mAllowCrossDomainRedirect = true;
- connectionState.mURL = new URL(uri);
- connectionState.mHeaders = convertHeaderStringToMap(headers, connectionState);
+ mAllowCrossDomainRedirect = true;
+ mURL = new URL(uri);
+ mHeaders = convertHeaderStringToMap(headers);
} catch (MalformedURLException e) {
return null;
- } finally {
- mConnectionStateHolder.set(connectionState);
}
return native_getIMemory();
@@ -113,21 +106,18 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
}
/* returns true iff header is internal */
- private boolean filterOutInternalHeaders(
- String key, String val, ConnectionState connectionState) {
+ private boolean filterOutInternalHeaders(String key, String val) {
if ("android-allow-cross-domain-redirect".equalsIgnoreCase(key)) {
- connectionState.mAllowCrossDomainRedirect = parseBoolean(val);
+ mAllowCrossDomainRedirect = parseBoolean(val);
// cross-protocol redirects are also controlled by this flag
- connectionState.mAllowCrossProtocolRedirect =
- connectionState.mAllowCrossDomainRedirect;
+ mAllowCrossProtocolRedirect = mAllowCrossDomainRedirect;
} else {
return false;
}
return true;
}
- private Map<String, String> convertHeaderStringToMap(String headers,
- ConnectionState connectionState) {
+ private Map<String, String> convertHeaderStringToMap(String headers) {
HashMap<String, String> map = new HashMap<String, String>();
String[] pairs = headers.split("\r\n");
@@ -137,7 +127,7 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
String key = pair.substring(0, colonPos);
String val = pair.substring(colonPos + 1);
- if (!filterOutInternalHeaders(key, val, connectionState)) {
+ if (!filterOutInternalHeaders(key, val)) {
map.put(key, val);
}
}
@@ -149,28 +139,25 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
@Override
@UnsupportedAppUsage
public void disconnect() {
- ConnectionState connectionState = mConnectionStateHolder.getAndSet(null);
- if (connectionState != null) {
- teardownConnection(connectionState);
- connectionState.mHeaders = null;
- connectionState.mURL = null;
- }
+ teardownConnection();
+ mHeaders = null;
+ mURL = null;
}
- private void teardownConnection(ConnectionState connectionState) {
- if (connectionState.mConnection != null) {
- if (connectionState.mInputStream != null) {
+ private void teardownConnection() {
+ if (mConnection != null) {
+ if (mInputStream != null) {
try {
- connectionState.mInputStream.close();
+ mInputStream.close();
} catch (IOException e) {
}
- connectionState.mInputStream = null;
+ mInputStream = null;
}
- connectionState.mConnection.disconnect();
- connectionState.mConnection = null;
+ mConnection.disconnect();
+ mConnection = null;
- connectionState.mCurrentOffset = -1;
+ mCurrentOffset = -1;
}
}
@@ -197,44 +184,42 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
return false;
}
- private void seekTo(long offset, ConnectionState connectionState) throws IOException {
- teardownConnection(connectionState);
+ private void seekTo(long offset) throws IOException {
+ teardownConnection();
try {
int response;
int redirectCount = 0;
- URL url = connectionState.mURL;
+ URL url = mURL;
// do not use any proxy for localhost (127.0.0.1)
boolean noProxy = isLocalHost(url);
while (true) {
if (noProxy) {
- connectionState.mConnection =
- (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
+ mConnection = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
} else {
- connectionState.mConnection = (HttpURLConnection) url.openConnection();
+ mConnection = (HttpURLConnection)url.openConnection();
}
- connectionState.mConnection.setConnectTimeout(CONNECT_TIMEOUT_MS);
+ mConnection.setConnectTimeout(CONNECT_TIMEOUT_MS);
// handle redirects ourselves if we do not allow cross-domain redirect
- connectionState.mConnection.setInstanceFollowRedirects(
- connectionState.mAllowCrossDomainRedirect);
+ mConnection.setInstanceFollowRedirects(mAllowCrossDomainRedirect);
- if (connectionState.mHeaders != null) {
- for (Map.Entry<String, String> entry : connectionState.mHeaders.entrySet()) {
- connectionState.mConnection.setRequestProperty(
+ if (mHeaders != null) {
+ for (Map.Entry<String, String> entry : mHeaders.entrySet()) {
+ mConnection.setRequestProperty(
entry.getKey(), entry.getValue());
}
}
if (offset > 0) {
- connectionState.mConnection.setRequestProperty(
+ mConnection.setRequestProperty(
"Range", "bytes=" + offset + "-");
}
- response = connectionState.mConnection.getResponseCode();
+ response = mConnection.getResponseCode();
if (response != HttpURLConnection.HTTP_MULT_CHOICE &&
response != HttpURLConnection.HTTP_MOVED_PERM &&
response != HttpURLConnection.HTTP_MOVED_TEMP &&
@@ -248,7 +233,7 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
throw new NoRouteToHostException("Too many redirects: " + redirectCount);
}
- String method = connectionState.mConnection.getRequestMethod();
+ String method = mConnection.getRequestMethod();
if (response == HTTP_TEMP_REDIRECT &&
!method.equals("GET") && !method.equals("HEAD")) {
// "If the 307 status code is received in response to a
@@ -256,35 +241,34 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
// automatically redirect the request"
throw new NoRouteToHostException("Invalid redirect");
}
- String location = connectionState.mConnection.getHeaderField("Location");
+ String location = mConnection.getHeaderField("Location");
if (location == null) {
throw new NoRouteToHostException("Invalid redirect");
}
- url = new URL(connectionState.mURL /* TRICKY: don't use url! */, location);
+ url = new URL(mURL /* TRICKY: don't use url! */, location);
if (!url.getProtocol().equals("https") &&
!url.getProtocol().equals("http")) {
throw new NoRouteToHostException("Unsupported protocol redirect");
}
- boolean sameProtocol =
- connectionState.mURL.getProtocol().equals(url.getProtocol());
- if (!connectionState.mAllowCrossProtocolRedirect && !sameProtocol) {
+ boolean sameProtocol = mURL.getProtocol().equals(url.getProtocol());
+ if (!mAllowCrossProtocolRedirect && !sameProtocol) {
throw new NoRouteToHostException("Cross-protocol redirects are disallowed");
}
- boolean sameHost = connectionState.mURL.getHost().equals(url.getHost());
- if (!connectionState.mAllowCrossDomainRedirect && !sameHost) {
+ boolean sameHost = mURL.getHost().equals(url.getHost());
+ if (!mAllowCrossDomainRedirect && !sameHost) {
throw new NoRouteToHostException("Cross-domain redirects are disallowed");
}
if (response != HTTP_TEMP_REDIRECT) {
// update effective URL, unless it is a Temporary Redirect
- connectionState.mURL = url;
+ mURL = url;
}
}
- if (connectionState.mAllowCrossDomainRedirect) {
+ if (mAllowCrossDomainRedirect) {
// remember the current, potentially redirected URL if redirects
// were handled by HttpURLConnection
- connectionState.mURL = connectionState.mConnection.getURL();
+ mURL = mConnection.getURL();
}
if (response == HttpURLConnection.HTTP_PARTIAL) {
@@ -292,9 +276,10 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
// because what we want is not just the length of the range
// returned but the size of the full content if available.
- String contentRange = connectionState.mConnection.getHeaderField("Content-Range");
+ String contentRange =
+ mConnection.getHeaderField("Content-Range");
- connectionState.mTotalSize = -1;
+ mTotalSize = -1;
if (contentRange != null) {
// format is "bytes xxx-yyy/zzz
// where "zzz" is the total number of bytes of the
@@ -306,7 +291,7 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
contentRange.substring(lastSlashPos + 1);
try {
- connectionState.mTotalSize = Long.parseLong(total);
+ mTotalSize = Long.parseLong(total);
} catch (NumberFormatException e) {
}
}
@@ -314,7 +299,7 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
} else if (response != HttpURLConnection.HTTP_OK) {
throw new IOException();
} else {
- connectionState.mTotalSize = connectionState.mConnection.getContentLength();
+ mTotalSize = mConnection.getContentLength();
}
if (offset > 0 && response != HttpURLConnection.HTTP_PARTIAL) {
@@ -323,14 +308,14 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
throw new ProtocolException();
}
- connectionState.mInputStream =
- new BufferedInputStream(connectionState.mConnection.getInputStream());
+ mInputStream =
+ new BufferedInputStream(mConnection.getInputStream());
- connectionState.mCurrentOffset = offset;
+ mCurrentOffset = offset;
} catch (IOException e) {
- connectionState.mTotalSize = -1;
- teardownConnection(connectionState);
- connectionState.mCurrentOffset = -1;
+ mTotalSize = -1;
+ teardownConnection();
+ mCurrentOffset = -1;
throw e;
}
@@ -339,14 +324,10 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
@Override
@UnsupportedAppUsage
public int readAt(long offset, int size) {
- ConnectionState connectionState = mConnectionStateHolder.get();
- if (connectionState != null) {
- return native_readAt(offset, size, connectionState);
- }
- return -1;
+ return native_readAt(offset, size);
}
- private int readAt(long offset, byte[] data, int size, ConnectionState connectionState) {
+ private int readAt(long offset, byte[] data, int size) {
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
@@ -354,12 +335,12 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
try {
synchronized(this) {
- if (offset != connectionState.mCurrentOffset) {
- seekTo(offset, connectionState);
+ if (offset != mCurrentOffset) {
+ seekTo(offset);
}
}
- int n = connectionState.mInputStream.read(data, 0, size);
+ int n = mInputStream.read(data, 0, size);
if (n == -1) {
// InputStream signals EOS using a -1 result, our semantics
@@ -367,7 +348,7 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
n = 0;
}
- connectionState.mCurrentOffset += n;
+ mCurrentOffset += n;
if (VERBOSE) {
Log.d(TAG, "readAt " + offset + " / " + size + " => " + n);
@@ -399,47 +380,35 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
@Override
public synchronized long getSize() {
- ConnectionState connectionState = mConnectionStateHolder.get();
- if (connectionState != null) {
- if (connectionState.mConnection == null) {
- try {
- seekTo(0, connectionState);
- } catch (IOException e) {
- return -1;
- }
+ if (mConnection == null) {
+ try {
+ seekTo(0);
+ } catch (IOException e) {
+ return -1;
}
- return connectionState.mTotalSize;
}
- return -1;
+ return mTotalSize;
}
@Override
@UnsupportedAppUsage
public synchronized String getMIMEType() {
- ConnectionState connectionState = mConnectionStateHolder.get();
- if (connectionState != null) {
- if (connectionState.mConnection == null) {
- try {
- seekTo(0, connectionState);
- } catch (IOException e) {
- return "application/octet-stream";
- }
+ if (mConnection == null) {
+ try {
+ seekTo(0);
+ } catch (IOException e) {
+ return "application/octet-stream";
}
- return connectionState.mConnection.getContentType();
}
- return null;
+ return mConnection.getContentType();
}
@Override
@UnsupportedAppUsage
public String getUri() {
- ConnectionState connectionState = mConnectionStateHolder.get();
- if (connectionState != null) {
- return connectionState.mURL.toString();
- }
- return null;
+ return mURL.toString();
}
@Override
@@ -452,7 +421,7 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
private native final void native_finalize();
private native final IBinder native_getIMemory();
- private native int native_readAt(long offset, int size, ConnectionState connectionState);
+ private native final int native_readAt(long offset, int size);
static {
System.loadLibrary("media_jni");
diff --git a/media/jni/android_media_MediaHTTPConnection.cpp b/media/jni/android_media_MediaHTTPConnection.cpp
index d28c15c98d16..365e045689f0 100644
--- a/media/jni/android_media_MediaHTTPConnection.cpp
+++ b/media/jni/android_media_MediaHTTPConnection.cpp
@@ -109,8 +109,7 @@ static void android_media_MediaHTTPConnection_native_init(JNIEnv *env) {
gFields.context = env->GetFieldID(clazz.get(), "mNativeContext", "J");
CHECK(gFields.context != NULL);
- gFields.readAtMethodID = env->GetMethodID(
- clazz.get(), "readAt", "(J[BILandroid/media/MediaHTTPConnection$ConnectionState;)I");
+ gFields.readAtMethodID = env->GetMethodID(clazz.get(), "readAt", "(J[BI)I");
}
static void android_media_MediaHTTPConnection_native_setup(
@@ -133,7 +132,7 @@ static jobject android_media_MediaHTTPConnection_native_getIMemory(
}
static jint android_media_MediaHTTPConnection_native_readAt(
- JNIEnv *env, jobject thiz, jlong offset, jint size, jobject connectionState) {
+ JNIEnv *env, jobject thiz, jlong offset, jint size) {
sp<JMediaHTTPConnection> conn = getObject(env, thiz);
if (size > JMediaHTTPConnection::kBufferSize) {
size = JMediaHTTPConnection::kBufferSize;
@@ -142,7 +141,7 @@ static jint android_media_MediaHTTPConnection_native_readAt(
jbyteArray byteArrayObj = conn->getByteArrayObj();
jint n = env->CallIntMethod(
- thiz, gFields.readAtMethodID, offset, byteArrayObj, size, connectionState);
+ thiz, gFields.readAtMethodID, offset, byteArrayObj, size);
if (n > 0) {
env->GetByteArrayRegion(
@@ -159,7 +158,7 @@ static const JNINativeMethod gMethods[] = {
{ "native_getIMemory", "()Landroid/os/IBinder;",
(void *)android_media_MediaHTTPConnection_native_getIMemory },
- { "native_readAt", "(JILandroid/media/MediaHTTPConnection$ConnectionState;)I",
+ { "native_readAt", "(JI)I",
(void *)android_media_MediaHTTPConnection_native_readAt },
{ "native_init", "()V",