diff options
| -rw-r--r-- | media/java/android/media/MediaHTTPConnection.java | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/media/java/android/media/MediaHTTPConnection.java b/media/java/android/media/MediaHTTPConnection.java index d72476269e18..b5c4cca12ff7 100644 --- a/media/java/android/media/MediaHTTPConnection.java +++ b/media/java/android/media/MediaHTTPConnection.java @@ -24,6 +24,7 @@ import android.os.IBinder; import android.os.StrictMode; import android.util.Log; +import com.android.internal.annotations.GuardedBy; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; @@ -46,20 +47,35 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub { // connection timeout - 30 sec private static final int CONNECT_TIMEOUT_MS = 30 * 1000; + @GuardedBy("this") @UnsupportedAppUsage private long mCurrentOffset = -1; + + @GuardedBy("this") @UnsupportedAppUsage private URL mURL = null; + + @GuardedBy("this") @UnsupportedAppUsage private Map<String, String> mHeaders = null; + + // volatile so that disconnect() can be called without acquiring a lock. + // All other access is @GuardedBy("this"). @UnsupportedAppUsage - private HttpURLConnection mConnection = null; + private volatile HttpURLConnection mConnection = null; + + @GuardedBy("this") @UnsupportedAppUsage private long mTotalSize = -1; + + @GuardedBy("this") private InputStream mInputStream = null; + @GuardedBy("this") @UnsupportedAppUsage private boolean mAllowCrossDomainRedirect = true; + + @GuardedBy("this") @UnsupportedAppUsage private boolean mAllowCrossProtocolRedirect = true; @@ -79,7 +95,7 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub { @Override @UnsupportedAppUsage - public IBinder connect(String uri, String headers) { + public synchronized IBinder connect(String uri, String headers) { if (VERBOSE) { Log.d(TAG, "connect: uri=" + uri + ", headers=" + headers); } @@ -96,7 +112,7 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub { return native_getIMemory(); } - private boolean parseBoolean(String val) { + private static boolean parseBoolean(String val) { try { return Long.parseLong(val) != 0; } catch (NumberFormatException e) { @@ -106,7 +122,7 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub { } /* returns true iff header is internal */ - private boolean filterOutInternalHeaders(String key, String val) { + private synchronized boolean filterOutInternalHeaders(String key, String val) { if ("android-allow-cross-domain-redirect".equalsIgnoreCase(key)) { mAllowCrossDomainRedirect = parseBoolean(val); // cross-protocol redirects are also controlled by this flag @@ -117,7 +133,7 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub { return true; } - private Map<String, String> convertHeaderStringToMap(String headers) { + private synchronized Map<String, String> convertHeaderStringToMap(String headers) { HashMap<String, String> map = new HashMap<String, String>(); String[] pairs = headers.split("\r\n"); @@ -139,12 +155,23 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub { @Override @UnsupportedAppUsage public void disconnect() { - teardownConnection(); - mHeaders = null; - mURL = null; + HttpURLConnection connectionToDisconnect = mConnection; + // Call disconnect() before blocking for the lock in order to ensure that any + // other thread that is blocked in readAt() will return quickly. + if (connectionToDisconnect != null) { + connectionToDisconnect.disconnect(); + } + synchronized (this) { + // It's unlikely but possible that while we were waiting to acquire the lock, another + // thread concurrently started a new connection; if so, we're disconnecting that one + // here, too. + teardownConnection(); + mHeaders = null; + mURL = null; + } } - private void teardownConnection() { + private synchronized void teardownConnection() { if (mConnection != null) { if (mInputStream != null) { try { @@ -184,7 +211,7 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub { return false; } - private void seekTo(long offset) throws IOException { + private synchronized void seekTo(long offset) throws IOException { teardownConnection(); try { @@ -323,21 +350,19 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub { @Override @UnsupportedAppUsage - public int readAt(long offset, int size) { + public synchronized int readAt(long offset, int size) { return native_readAt(offset, size); } - private int readAt(long offset, byte[] data, int size) { + private synchronized int readAt(long offset, byte[] data, int size) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); try { - synchronized(this) { - if (offset != mCurrentOffset) { - seekTo(offset); - } + if (offset != mCurrentOffset) { + seekTo(offset); } int n = mInputStream.read(data, 0, size); @@ -407,7 +432,7 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub { @Override @UnsupportedAppUsage - public String getUri() { + public synchronized String getUri() { return mURL.toString(); } |