OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.net.impl; | 5 package org.chromium.net.impl; |
6 | 6 |
7 import android.content.Context; | 7 import android.content.Context; |
8 import android.os.Build; | 8 import android.os.Build; |
9 import android.os.ConditionVariable; | 9 import android.os.ConditionVariable; |
10 import android.os.Handler; | 10 import android.os.Handler; |
11 import android.os.Looper; | 11 import android.os.Looper; |
12 import android.os.Process; | 12 import android.os.Process; |
13 import android.util.Log; | 13 import android.util.Log; |
14 | 14 |
15 import org.chromium.base.ObserverList; | 15 import org.chromium.base.ObserverList; |
16 import org.chromium.base.VisibleForTesting; | 16 import org.chromium.base.VisibleForTesting; |
17 import org.chromium.base.annotations.CalledByNative; | 17 import org.chromium.base.annotations.CalledByNative; |
18 import org.chromium.base.annotations.JNINamespace; | 18 import org.chromium.base.annotations.JNINamespace; |
19 import org.chromium.base.annotations.NativeClassQualifiedName; | 19 import org.chromium.base.annotations.NativeClassQualifiedName; |
20 import org.chromium.base.annotations.UsedByReflection; | 20 import org.chromium.base.annotations.UsedByReflection; |
21 import org.chromium.net.BidirectionalStream; | 21 import org.chromium.net.BidirectionalStream; |
22 import org.chromium.net.CronetEngine; | 22 import org.chromium.net.CronetEngine; |
23 import org.chromium.net.NetworkQualityRttListener; | 23 import org.chromium.net.NetworkQualityRttListener; |
24 import org.chromium.net.NetworkQualityThroughputListener; | 24 import org.chromium.net.NetworkQualityThroughputListener; |
25 import org.chromium.net.RequestFinishedListener; | |
25 import org.chromium.net.UrlRequest; | 26 import org.chromium.net.UrlRequest; |
26 import org.chromium.net.urlconnection.CronetHttpURLConnection; | 27 import org.chromium.net.urlconnection.CronetHttpURLConnection; |
27 import org.chromium.net.urlconnection.CronetURLStreamHandlerFactory; | 28 import org.chromium.net.urlconnection.CronetURLStreamHandlerFactory; |
28 | 29 |
29 import java.net.Proxy; | 30 import java.net.Proxy; |
30 import java.net.URL; | 31 import java.net.URL; |
31 import java.net.URLConnection; | 32 import java.net.URLConnection; |
32 import java.net.URLStreamHandlerFactory; | 33 import java.net.URLStreamHandlerFactory; |
34 import java.util.ArrayList; | |
33 import java.util.Collection; | 35 import java.util.Collection; |
34 import java.util.List; | 36 import java.util.List; |
35 import java.util.Map; | 37 import java.util.Map; |
36 import java.util.concurrent.Executor; | 38 import java.util.concurrent.Executor; |
37 import java.util.concurrent.RejectedExecutionException; | 39 import java.util.concurrent.RejectedExecutionException; |
38 import java.util.concurrent.atomic.AtomicInteger; | 40 import java.util.concurrent.atomic.AtomicInteger; |
39 | 41 |
40 import javax.annotation.concurrent.GuardedBy; | 42 import javax.annotation.concurrent.GuardedBy; |
41 | 43 |
42 /** | 44 /** |
(...skipping 19 matching lines...) Expand all Loading... | |
62 private Thread mNetworkThread; | 64 private Thread mNetworkThread; |
63 | 65 |
64 private Executor mNetworkQualityExecutor; | 66 private Executor mNetworkQualityExecutor; |
65 private boolean mNetworkQualityEstimatorEnabled; | 67 private boolean mNetworkQualityEstimatorEnabled; |
66 | 68 |
67 /** Locks operations on network quality listeners, because listener | 69 /** Locks operations on network quality listeners, because listener |
68 * addition and removal may occur on a different thread from notification. | 70 * addition and removal may occur on a different thread from notification. |
69 */ | 71 */ |
70 private final Object mNetworkQualityLock = new Object(); | 72 private final Object mNetworkQualityLock = new Object(); |
71 | 73 |
74 /** Locks operations on the list of RequestFinishedListeners, because operat ions 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.
| |
75 * any thread. | |
76 */ | |
77 private final Object mFinishedListenerLock = new Object(); | |
78 | |
72 @GuardedBy("mNetworkQualityLock") | 79 @GuardedBy("mNetworkQualityLock") |
73 private final ObserverList<NetworkQualityRttListener> mRttListenerList = | 80 private final ObserverList<NetworkQualityRttListener> mRttListenerList = |
74 new ObserverList<NetworkQualityRttListener>(); | 81 new ObserverList<NetworkQualityRttListener>(); |
75 | 82 |
76 @GuardedBy("mNetworkQualityLock") | 83 @GuardedBy("mNetworkQualityLock") |
77 private final ObserverList<NetworkQualityThroughputListener> mThroughputList enerList = | 84 private final ObserverList<NetworkQualityThroughputListener> mThroughputList enerList = |
78 new ObserverList<NetworkQualityThroughputListener>(); | 85 new ObserverList<NetworkQualityThroughputListener>(); |
79 | 86 |
80 @GuardedBy("mNetworkQualityLock") | 87 @GuardedBy("mFinishedListenerLock") |
81 private final ObserverList<RequestFinishedListener> mFinishedListenerList = | 88 private final List<RequestFinishedListener> mFinishedListenerList = |
82 new ObserverList<RequestFinishedListener>(); | 89 new ArrayList<RequestFinishedListener>(); |
83 | 90 |
84 /** | 91 /** |
85 * Synchronize access to mCertVerifierData. | 92 * Synchronize access to mCertVerifierData. |
86 */ | 93 */ |
87 private ConditionVariable mWaitGetCertVerifierDataComplete = new ConditionVa riable(); | 94 private ConditionVariable mWaitGetCertVerifierDataComplete = new ConditionVa riable(); |
88 | 95 |
89 /** Holds CertVerifier data. */ | 96 /** Holds CertVerifier data. */ |
90 private String mCertVerifierData; | 97 private String mCertVerifierData; |
91 | 98 |
92 @UsedByReflection("CronetEngine.java") | 99 @UsedByReflection("CronetEngine.java") |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
146 } | 153 } |
147 return urlRequestContextConfig; | 154 return urlRequestContextConfig; |
148 } | 155 } |
149 | 156 |
150 @Override | 157 @Override |
151 public UrlRequest createRequest(String url, UrlRequest.Callback callback, Ex ecutor executor, | 158 public UrlRequest createRequest(String url, UrlRequest.Callback callback, Ex ecutor executor, |
152 int priority, Collection<Object> requestAnnotations, boolean disable Cache, | 159 int priority, Collection<Object> requestAnnotations, boolean disable Cache, |
153 boolean disableConnectionMigration) { | 160 boolean disableConnectionMigration) { |
154 synchronized (mLock) { | 161 synchronized (mLock) { |
155 checkHaveAdapter(); | 162 checkHaveAdapter(); |
156 boolean metricsCollectionEnabled = mNetworkQualityEstimatorEnabled; | 163 boolean metricsCollectionEnabled = false; |
157 if (metricsCollectionEnabled) { // Collect metrics only if someone i s listening. | 164 synchronized (mFinishedListenerLock) { |
158 synchronized (mNetworkQualityLock) { | 165 metricsCollectionEnabled = !mFinishedListenerList.isEmpty(); |
159 metricsCollectionEnabled = !mFinishedListenerList.isEmpty(); | |
160 } | |
161 } | 166 } |
162 return new CronetUrlRequest(this, url, priority, callback, executor, requestAnnotations, | 167 return new CronetUrlRequest(this, url, priority, callback, executor, requestAnnotations, |
163 metricsCollectionEnabled, disableCache, disableConnectionMig ration); | 168 metricsCollectionEnabled, disableCache, disableConnectionMig ration); |
164 } | 169 } |
165 } | 170 } |
166 | 171 |
167 @Override | 172 @Override |
168 public BidirectionalStream createBidirectionalStream(String url, | 173 public BidirectionalStream createBidirectionalStream(String url, |
169 BidirectionalStream.Callback callback, Executor executor, String htt pMethod, | 174 BidirectionalStream.Callback callback, Executor executor, String htt pMethod, |
170 List<Map.Entry<String, String>> requestHeaders, | 175 List<Map.Entry<String, String>> requestHeaders, |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
372 } | 377 } |
373 } | 378 } |
374 | 379 |
375 /** | 380 /** |
376 * TODO(tbansal): http://crbug.com/618034 Remove this API once all | 381 * TODO(tbansal): http://crbug.com/618034 Remove this API once all |
377 * embedders have switched to using a request finished listener that | 382 * embedders have switched to using a request finished listener that |
378 * provides its own executor. | 383 * provides its own executor. |
379 */ | 384 */ |
380 @Override | 385 @Override |
381 public void addRequestFinishedListener(RequestFinishedListener listener) { | 386 public void addRequestFinishedListener(RequestFinishedListener listener) { |
382 if (!mNetworkQualityEstimatorEnabled) { | 387 synchronized (mFinishedListenerLock) { |
383 throw new IllegalStateException("Network quality estimator must be e nabled"); | 388 mFinishedListenerList.add(listener); |
384 } | |
385 // RequestFinishedListener does not provide its own executor. | |
386 if (mNetworkQualityExecutor == null) { | |
387 throw new IllegalStateException("Executor must not be null"); | |
388 } | |
389 synchronized (mNetworkQualityLock) { | |
390 mFinishedListenerList.addObserver(listener); | |
391 } | 389 } |
392 } | 390 } |
393 | 391 |
394 /** | 392 /** |
395 * TODO(tbansal): http://crbug.com/618034 Remove this API. | 393 * TODO(tbansal): http://crbug.com/618034 Remove this API. |
396 */ | 394 */ |
397 @Override | 395 @Override |
398 public void removeRequestFinishedListener(RequestFinishedListener listener) { | 396 public void removeRequestFinishedListener(RequestFinishedListener listener) { |
399 if (!mNetworkQualityEstimatorEnabled) { | 397 synchronized (mFinishedListenerLock) { |
400 throw new IllegalStateException("Network quality estimator must be e nabled"); | 398 mFinishedListenerList.remove(listener); |
401 } | |
402 synchronized (mNetworkQualityLock) { | |
403 mFinishedListenerList.removeObserver(listener); | |
404 } | 399 } |
405 } | 400 } |
406 | 401 |
407 @Override | 402 @Override |
408 public URLConnection openConnection(URL url) { | 403 public URLConnection openConnection(URL url) { |
409 return openConnection(url, Proxy.NO_PROXY); | 404 return openConnection(url, Proxy.NO_PROXY); |
410 } | 405 } |
411 | 406 |
412 @Override | 407 @Override |
413 public URLConnection openConnection(URL url, Proxy proxy) { | 408 public URLConnection openConnection(URL url, Proxy proxy) { |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
521 } | 516 } |
522 | 517 |
523 @SuppressWarnings("unused") | 518 @SuppressWarnings("unused") |
524 @CalledByNative | 519 @CalledByNative |
525 private void onGetCertVerifierData(String certVerifierData) { | 520 private void onGetCertVerifierData(String certVerifierData) { |
526 mCertVerifierData = certVerifierData; | 521 mCertVerifierData = certVerifierData; |
527 mWaitGetCertVerifierDataComplete.open(); | 522 mWaitGetCertVerifierDataComplete.open(); |
528 } | 523 } |
529 | 524 |
530 void reportFinished(final CronetUrlRequest request) { | 525 void reportFinished(final CronetUrlRequest request) { |
531 if (!mNetworkQualityEstimatorEnabled) { | 526 final UrlRequestInfo requestInfo = request.getRequestInfo(); |
532 return; | 527 ArrayList<RequestFinishedListener> currentListeners; |
528 synchronized (mFinishedListenerLock) { | |
529 currentListeners = new ArrayList<RequestFinishedListener>(mFinishedL istenerList); | |
533 } | 530 } |
534 // If no request finished listener has been added, then mNetworkQualityE xecutor may be | 531 for (final RequestFinishedListener listener : currentListeners) { |
535 // null. Exit early to avoid posting to a null executor. | 532 Runnable task = new Runnable() { |
536 synchronized (mNetworkQualityLock) { | 533 @Override |
537 if (mFinishedListenerList.isEmpty()) { | 534 public void run() { |
538 return; | 535 listener.onRequestFinished(requestInfo); |
539 } | 536 } |
537 }; | |
538 postObservationTaskToExecutor(listener.getExecutor(), task); | |
540 } | 539 } |
541 Runnable task = new Runnable() { | |
542 @Override | |
543 public void run() { | |
544 synchronized (mNetworkQualityLock) { | |
545 UrlRequestInfo requestInfo = request.getRequestInfo(); | |
546 for (RequestFinishedListener listener : mFinishedListenerLis t) { | |
547 listener.onRequestFinished(requestInfo); | |
548 } | |
549 } | |
550 } | |
551 }; | |
552 // Use {@link mNetworkQualityExecutor} since | |
553 // RequestFInishedListeners do not provide an executor. | |
554 postObservationTaskToExecutor(mNetworkQualityExecutor, task); | |
555 } | 540 } |
556 | 541 |
557 private static void postObservationTaskToExecutor(Executor executor, Runnabl e task) { | 542 private static void postObservationTaskToExecutor(Executor executor, Runnabl e task) { |
558 try { | 543 try { |
559 executor.execute(task); | 544 executor.execute(task); |
560 } catch (RejectedExecutionException failException) { | 545 } catch (RejectedExecutionException failException) { |
561 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception posting task to ex ecutor", | 546 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception posting task to ex ecutor", |
562 failException); | 547 failException); |
563 } | 548 } |
564 } | 549 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
606 | 591 |
607 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 592 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
608 private native void nativeEnableNetworkQualityEstimator(long nativePtr); | 593 private native void nativeEnableNetworkQualityEstimator(long nativePtr); |
609 | 594 |
610 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 595 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
611 private native void nativeProvideRTTObservations(long nativePtr, boolean sho uld); | 596 private native void nativeProvideRTTObservations(long nativePtr, boolean sho uld); |
612 | 597 |
613 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 598 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
614 private native void nativeProvideThroughputObservations(long nativePtr, bool ean should); | 599 private native void nativeProvideThroughputObservations(long nativePtr, bool ean should); |
615 } | 600 } |
OLD | NEW |