Index: components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java |
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java b/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java |
index 345692dc565c1e8efbbb3e1241d0c14a3e41c3bf..b9ab56c81b18844bd34ebe14ae963e54a3b34404 100644 |
--- a/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java |
+++ b/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java |
@@ -22,6 +22,7 @@ import org.chromium.net.BidirectionalStream; |
import org.chromium.net.CronetEngine; |
import org.chromium.net.NetworkQualityRttListener; |
import org.chromium.net.NetworkQualityThroughputListener; |
+import org.chromium.net.RequestFinishedListener; |
import org.chromium.net.UrlRequest; |
import org.chromium.net.urlconnection.CronetHttpURLConnection; |
import org.chromium.net.urlconnection.CronetURLStreamHandlerFactory; |
@@ -30,6 +31,7 @@ import java.net.Proxy; |
import java.net.URL; |
import java.net.URLConnection; |
import java.net.URLStreamHandlerFactory; |
+import java.util.ArrayList; |
import java.util.Collection; |
import java.util.List; |
import java.util.Map; |
@@ -69,6 +71,11 @@ public class CronetUrlRequestContext extends CronetEngine { |
*/ |
private final Object mNetworkQualityLock = new Object(); |
+ /** Locks operations on the list of RequestFinishedListeners, because operations can happen on |
xunjieli
2016/07/29 16:35:25
The previous example is a bad example :(
The firs
mgersh
2016/07/29 18:21:52
Done.
|
+ * any thread. |
+ */ |
+ private final Object mFinishedListenerLock = new Object(); |
+ |
@GuardedBy("mNetworkQualityLock") |
private final ObserverList<NetworkQualityRttListener> mRttListenerList = |
new ObserverList<NetworkQualityRttListener>(); |
@@ -77,9 +84,9 @@ public class CronetUrlRequestContext extends CronetEngine { |
private final ObserverList<NetworkQualityThroughputListener> mThroughputListenerList = |
new ObserverList<NetworkQualityThroughputListener>(); |
- @GuardedBy("mNetworkQualityLock") |
- private final ObserverList<RequestFinishedListener> mFinishedListenerList = |
- new ObserverList<RequestFinishedListener>(); |
+ @GuardedBy("mFinishedListenerLock") |
+ private final List<RequestFinishedListener> mFinishedListenerList = |
+ new ArrayList<RequestFinishedListener>(); |
/** |
* Synchronize access to mCertVerifierData. |
@@ -153,11 +160,9 @@ public class CronetUrlRequestContext extends CronetEngine { |
boolean disableConnectionMigration) { |
synchronized (mLock) { |
checkHaveAdapter(); |
- boolean metricsCollectionEnabled = mNetworkQualityEstimatorEnabled; |
- if (metricsCollectionEnabled) { // Collect metrics only if someone is listening. |
- synchronized (mNetworkQualityLock) { |
- metricsCollectionEnabled = !mFinishedListenerList.isEmpty(); |
- } |
+ boolean metricsCollectionEnabled = false; |
+ synchronized (mFinishedListenerLock) { |
+ metricsCollectionEnabled = !mFinishedListenerList.isEmpty(); |
} |
return new CronetUrlRequest(this, url, priority, callback, executor, requestAnnotations, |
metricsCollectionEnabled, disableCache, disableConnectionMigration); |
@@ -379,15 +384,8 @@ public class CronetUrlRequestContext extends CronetEngine { |
*/ |
@Override |
public void addRequestFinishedListener(RequestFinishedListener listener) { |
- if (!mNetworkQualityEstimatorEnabled) { |
- throw new IllegalStateException("Network quality estimator must be enabled"); |
- } |
- // RequestFinishedListener does not provide its own executor. |
- if (mNetworkQualityExecutor == null) { |
- throw new IllegalStateException("Executor must not be null"); |
- } |
- synchronized (mNetworkQualityLock) { |
- mFinishedListenerList.addObserver(listener); |
+ synchronized (mFinishedListenerLock) { |
+ mFinishedListenerList.add(listener); |
} |
} |
@@ -396,11 +394,8 @@ public class CronetUrlRequestContext extends CronetEngine { |
*/ |
@Override |
public void removeRequestFinishedListener(RequestFinishedListener listener) { |
- if (!mNetworkQualityEstimatorEnabled) { |
- throw new IllegalStateException("Network quality estimator must be enabled"); |
- } |
- synchronized (mNetworkQualityLock) { |
- mFinishedListenerList.removeObserver(listener); |
+ synchronized (mFinishedListenerLock) { |
+ mFinishedListenerList.remove(listener); |
} |
} |
@@ -528,30 +523,20 @@ public class CronetUrlRequestContext extends CronetEngine { |
} |
void reportFinished(final CronetUrlRequest request) { |
- if (!mNetworkQualityEstimatorEnabled) { |
- return; |
- } |
- // If no request finished listener has been added, then mNetworkQualityExecutor may be |
- // null. Exit early to avoid posting to a null executor. |
- synchronized (mNetworkQualityLock) { |
- if (mFinishedListenerList.isEmpty()) { |
- return; |
- } |
- } |
- Runnable task = new Runnable() { |
- @Override |
- public void run() { |
- synchronized (mNetworkQualityLock) { |
- UrlRequestInfo requestInfo = request.getRequestInfo(); |
- for (RequestFinishedListener listener : mFinishedListenerList) { |
- listener.onRequestFinished(requestInfo); |
- } |
+ final UrlRequestInfo requestInfo = request.getRequestInfo(); |
+ ArrayList<RequestFinishedListener> currentListeners; |
+ synchronized (mFinishedListenerLock) { |
+ currentListeners = new ArrayList<RequestFinishedListener>(mFinishedListenerList); |
+ } |
+ for (final RequestFinishedListener listener : currentListeners) { |
+ Runnable task = new Runnable() { |
+ @Override |
+ public void run() { |
+ listener.onRequestFinished(requestInfo); |
} |
- } |
- }; |
- // Use {@link mNetworkQualityExecutor} since |
- // RequestFInishedListeners do not provide an executor. |
- postObservationTaskToExecutor(mNetworkQualityExecutor, task); |
+ }; |
+ postObservationTaskToExecutor(listener.getExecutor(), task); |
+ } |
} |
private static void postObservationTaskToExecutor(Executor executor, Runnable task) { |