Chromium Code Reviews| 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.os.ConditionVariable; | 7 import android.os.ConditionVariable; |
| 8 import android.os.Handler; | 8 import android.os.Handler; |
| 9 import android.os.Looper; | 9 import android.os.Looper; |
| 10 import android.os.Process; | 10 import android.os.Process; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 import org.chromium.net.UrlRequest; | 26 import org.chromium.net.UrlRequest; |
| 27 import org.chromium.net.urlconnection.CronetHttpURLConnection; | 27 import org.chromium.net.urlconnection.CronetHttpURLConnection; |
| 28 import org.chromium.net.urlconnection.CronetURLStreamHandlerFactory; | 28 import org.chromium.net.urlconnection.CronetURLStreamHandlerFactory; |
| 29 | 29 |
| 30 import java.net.Proxy; | 30 import java.net.Proxy; |
| 31 import java.net.URL; | 31 import java.net.URL; |
| 32 import java.net.URLConnection; | 32 import java.net.URLConnection; |
| 33 import java.net.URLStreamHandlerFactory; | 33 import java.net.URLStreamHandlerFactory; |
| 34 import java.util.ArrayList; | 34 import java.util.ArrayList; |
| 35 import java.util.Collection; | 35 import java.util.Collection; |
| 36 import java.util.HashMap; | |
| 36 import java.util.List; | 37 import java.util.List; |
| 37 import java.util.Map; | 38 import java.util.Map; |
| 38 import java.util.concurrent.Executor; | 39 import java.util.concurrent.Executor; |
| 39 import java.util.concurrent.RejectedExecutionException; | 40 import java.util.concurrent.RejectedExecutionException; |
| 40 import java.util.concurrent.atomic.AtomicInteger; | 41 import java.util.concurrent.atomic.AtomicInteger; |
| 41 | 42 |
| 42 import javax.annotation.concurrent.GuardedBy; | 43 import javax.annotation.concurrent.GuardedBy; |
| 43 | 44 |
| 44 /** | 45 /** |
| 45 * CronetEngine using Chromium HTTP stack implementation. | 46 * CronetEngine using Chromium HTTP stack implementation. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 112 * computed by the network quality estimator. | 113 * computed by the network quality estimator. |
| 113 */ | 114 */ |
| 114 @GuardedBy("mNetworkQualityLock") | 115 @GuardedBy("mNetworkQualityLock") |
| 115 private int mDownstreamThroughputKbps = RttThroughputValues.INVALID_RTT_THRO UGHPUT; | 116 private int mDownstreamThroughputKbps = RttThroughputValues.INVALID_RTT_THRO UGHPUT; |
| 116 | 117 |
| 117 @GuardedBy("mNetworkQualityLock") | 118 @GuardedBy("mNetworkQualityLock") |
| 118 private final ObserverList<NetworkQualityRttListener> mRttListenerList = | 119 private final ObserverList<NetworkQualityRttListener> mRttListenerList = |
| 119 new ObserverList<NetworkQualityRttListener>(); | 120 new ObserverList<NetworkQualityRttListener>(); |
| 120 | 121 |
| 121 @GuardedBy("mNetworkQualityLock") | 122 @GuardedBy("mNetworkQualityLock") |
| 123 private final Map<NetworkQualityRttListener, | |
| 124 VersionSafeCallbacks.NetworkQualityRttListenerWrapper> mRttListenerM ap = | |
| 125 new HashMap<NetworkQualityRttListener, | |
| 126 VersionSafeCallbacks.NetworkQualityRttListenerWrapper>(); | |
| 127 | |
| 128 @GuardedBy("mNetworkQualityLock") | |
| 122 private final ObserverList<NetworkQualityThroughputListener> mThroughputList enerList = | 129 private final ObserverList<NetworkQualityThroughputListener> mThroughputList enerList = |
| 123 new ObserverList<NetworkQualityThroughputListener>(); | 130 new ObserverList<NetworkQualityThroughputListener>(); |
| 124 | 131 |
| 132 @GuardedBy("mNetworkQualityLock") | |
| 133 private final Map<NetworkQualityThroughputListener, | |
| 134 VersionSafeCallbacks.NetworkQualityThroughputListenerWrapper> mThrou ghputListenerMap = | |
| 135 new HashMap<NetworkQualityThroughputListener, | |
| 136 VersionSafeCallbacks.NetworkQualityThroughputListenerWrapper >(); | |
| 137 | |
| 125 @GuardedBy("mFinishedListenerLock") | 138 @GuardedBy("mFinishedListenerLock") |
| 126 private final List<RequestFinishedInfo.Listener> mFinishedListenerList = | 139 private final Map<RequestFinishedInfo.Listener, |
|
kapishnikov
2016/11/18 20:11:18
Can we instead of using the map, implement equals(
pauljensen
2016/11/19 01:12:18
I thought about that but it had a couple downsides
kapishnikov
2016/11/21 17:35:22
I personally like the idea of implementing equals(
pauljensen
2016/11/22 12:38:02
I delegated the equals() and hashCode() to the wra
| |
| 127 new ArrayList<RequestFinishedInfo.Listener>(); | 140 VersionSafeCallbacks.RequestFinishedInfoListener> mFinishedListenerM ap = |
| 141 new HashMap<RequestFinishedInfo.Listener, | |
| 142 VersionSafeCallbacks.RequestFinishedInfoListener>(); | |
| 128 | 143 |
| 129 /** | 144 /** |
| 130 * Synchronize access to mCertVerifierData. | 145 * Synchronize access to mCertVerifierData. |
| 131 */ | 146 */ |
| 132 private ConditionVariable mWaitGetCertVerifierDataComplete = new ConditionVa riable(); | 147 private ConditionVariable mWaitGetCertVerifierDataComplete = new ConditionVa riable(); |
| 133 | 148 |
| 134 /** Holds CertVerifier data. */ | 149 /** Holds CertVerifier data. */ |
| 135 private String mCertVerifierData; | 150 private String mCertVerifierData; |
| 136 | 151 |
| 137 private ConditionVariable mStopNetLogCompleted; | 152 private ConditionVariable mStopNetLogCompleted; |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 406 throw new IllegalStateException("Network quality estimator must be e nabled"); | 421 throw new IllegalStateException("Network quality estimator must be e nabled"); |
| 407 } | 422 } |
| 408 synchronized (mNetworkQualityLock) { | 423 synchronized (mNetworkQualityLock) { |
| 409 if (mRttListenerList.isEmpty()) { | 424 if (mRttListenerList.isEmpty()) { |
| 410 synchronized (mLock) { | 425 synchronized (mLock) { |
| 411 checkHaveAdapter(); | 426 checkHaveAdapter(); |
| 412 nativeProvideRTTObservations(mUrlRequestContextAdapter, true ); | 427 nativeProvideRTTObservations(mUrlRequestContextAdapter, true ); |
| 413 } | 428 } |
| 414 } | 429 } |
| 415 mRttListenerList.addObserver(listener); | 430 mRttListenerList.addObserver(listener); |
| 431 mRttListenerMap.put( | |
| 432 listener, new VersionSafeCallbacks.NetworkQualityRttListener Wrapper(listener)); | |
| 416 } | 433 } |
| 417 } | 434 } |
| 418 | 435 |
| 419 @Override | 436 @Override |
| 420 public void removeRttListener(NetworkQualityRttListener listener) { | 437 public void removeRttListener(NetworkQualityRttListener listener) { |
| 421 if (!mNetworkQualityEstimatorEnabled) { | 438 if (!mNetworkQualityEstimatorEnabled) { |
| 422 throw new IllegalStateException("Network quality estimator must be e nabled"); | 439 throw new IllegalStateException("Network quality estimator must be e nabled"); |
| 423 } | 440 } |
| 424 synchronized (mNetworkQualityLock) { | 441 synchronized (mNetworkQualityLock) { |
| 425 mRttListenerList.removeObserver(listener); | 442 if (mRttListenerList.removeObserver(listener)) { |
| 426 if (mRttListenerList.isEmpty()) { | 443 mRttListenerMap.remove(listener); |
| 427 synchronized (mLock) { | 444 if (mRttListenerList.isEmpty()) { |
| 428 checkHaveAdapter(); | 445 synchronized (mLock) { |
| 429 nativeProvideRTTObservations(mUrlRequestContextAdapter, fals e); | 446 checkHaveAdapter(); |
| 447 nativeProvideRTTObservations(mUrlRequestContextAdapter, false); | |
| 448 } | |
| 430 } | 449 } |
| 431 } | 450 } |
| 432 } | 451 } |
| 433 } | 452 } |
| 434 | 453 |
| 435 @Override | 454 @Override |
| 436 public void addThroughputListener(NetworkQualityThroughputListener listener) { | 455 public void addThroughputListener(NetworkQualityThroughputListener listener) { |
| 437 if (!mNetworkQualityEstimatorEnabled) { | 456 if (!mNetworkQualityEstimatorEnabled) { |
| 438 throw new IllegalStateException("Network quality estimator must be e nabled"); | 457 throw new IllegalStateException("Network quality estimator must be e nabled"); |
| 439 } | 458 } |
| 440 synchronized (mNetworkQualityLock) { | 459 synchronized (mNetworkQualityLock) { |
| 441 if (mThroughputListenerList.isEmpty()) { | 460 if (mThroughputListenerList.isEmpty()) { |
| 442 synchronized (mLock) { | 461 synchronized (mLock) { |
| 443 checkHaveAdapter(); | 462 checkHaveAdapter(); |
| 444 nativeProvideThroughputObservations(mUrlRequestContextAdapte r, true); | 463 nativeProvideThroughputObservations(mUrlRequestContextAdapte r, true); |
| 445 } | 464 } |
| 446 } | 465 } |
| 447 mThroughputListenerList.addObserver(listener); | 466 mThroughputListenerList.addObserver(listener); |
| 467 mThroughputListenerMap.put(listener, | |
| 468 new VersionSafeCallbacks.NetworkQualityThroughputListenerWra pper(listener)); | |
| 448 } | 469 } |
| 449 } | 470 } |
| 450 | 471 |
| 451 @Override | 472 @Override |
| 452 public void removeThroughputListener(NetworkQualityThroughputListener listen er) { | 473 public void removeThroughputListener(NetworkQualityThroughputListener listen er) { |
| 453 if (!mNetworkQualityEstimatorEnabled) { | 474 if (!mNetworkQualityEstimatorEnabled) { |
| 454 throw new IllegalStateException("Network quality estimator must be e nabled"); | 475 throw new IllegalStateException("Network quality estimator must be e nabled"); |
| 455 } | 476 } |
| 456 synchronized (mNetworkQualityLock) { | 477 synchronized (mNetworkQualityLock) { |
| 457 mThroughputListenerList.removeObserver(listener); | 478 if (mThroughputListenerList.removeObserver(listener)) { |
| 458 if (mThroughputListenerList.isEmpty()) { | 479 mThroughputListenerMap.remove(listener); |
| 459 synchronized (mLock) { | 480 if (mThroughputListenerList.isEmpty()) { |
| 460 checkHaveAdapter(); | 481 synchronized (mLock) { |
| 461 nativeProvideThroughputObservations(mUrlRequestContextAdapte r, false); | 482 checkHaveAdapter(); |
| 483 nativeProvideThroughputObservations(mUrlRequestContextAd apter, false); | |
| 484 } | |
| 462 } | 485 } |
| 463 } | 486 } |
| 464 } | 487 } |
| 465 } | 488 } |
| 466 | 489 |
| 467 @Override | 490 @Override |
| 468 public void addRequestFinishedListener(RequestFinishedInfo.Listener listener ) { | 491 public void addRequestFinishedListener(RequestFinishedInfo.Listener listener ) { |
| 469 synchronized (mFinishedListenerLock) { | 492 synchronized (mFinishedListenerLock) { |
| 470 mFinishedListenerList.add(listener); | 493 mFinishedListenerMap.put( |
| 494 listener, new VersionSafeCallbacks.RequestFinishedInfoListen er(listener)); | |
| 471 } | 495 } |
| 472 } | 496 } |
| 473 | 497 |
| 474 @Override | 498 @Override |
| 475 public void removeRequestFinishedListener(RequestFinishedInfo.Listener liste ner) { | 499 public void removeRequestFinishedListener(RequestFinishedInfo.Listener liste ner) { |
| 476 synchronized (mFinishedListenerLock) { | 500 synchronized (mFinishedListenerLock) { |
| 477 mFinishedListenerList.remove(listener); | 501 mFinishedListenerMap.remove(listener); |
| 478 } | 502 } |
| 479 } | 503 } |
| 480 | 504 |
| 481 boolean hasRequestFinishedListener() { | 505 boolean hasRequestFinishedListener() { |
| 482 synchronized (mFinishedListenerLock) { | 506 synchronized (mFinishedListenerLock) { |
| 483 return !mFinishedListenerList.isEmpty(); | 507 return !mFinishedListenerMap.isEmpty(); |
| 484 } | 508 } |
| 485 } | 509 } |
| 486 | 510 |
| 487 @Override | 511 @Override |
| 488 public URLConnection openConnection(URL url) { | 512 public URLConnection openConnection(URL url) { |
| 489 return openConnection(url, Proxy.NO_PROXY); | 513 return openConnection(url, Proxy.NO_PROXY); |
| 490 } | 514 } |
| 491 | 515 |
| 492 @Override | 516 @Override |
| 493 public URLConnection openConnection(URL url, Proxy proxy) { | 517 public URLConnection openConnection(URL url, Proxy proxy) { |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 606 mHttpRttMs = httpRttMs; | 630 mHttpRttMs = httpRttMs; |
| 607 mTransportRttMs = transportRttMs; | 631 mTransportRttMs = transportRttMs; |
| 608 mDownstreamThroughputKbps = downstreamThroughputKbps; | 632 mDownstreamThroughputKbps = downstreamThroughputKbps; |
| 609 } | 633 } |
| 610 } | 634 } |
| 611 | 635 |
| 612 @SuppressWarnings("unused") | 636 @SuppressWarnings("unused") |
| 613 @CalledByNative | 637 @CalledByNative |
| 614 private void onRttObservation(final int rttMs, final long whenMs, final int source) { | 638 private void onRttObservation(final int rttMs, final long whenMs, final int source) { |
| 615 synchronized (mNetworkQualityLock) { | 639 synchronized (mNetworkQualityLock) { |
| 616 for (final NetworkQualityRttListener listener : mRttListenerList) { | 640 for (NetworkQualityRttListener unsafeListener : mRttListenerList) { |
| 641 final VersionSafeCallbacks.NetworkQualityRttListenerWrapper list ener = | |
| 642 mRttListenerMap.get(unsafeListener); | |
| 617 Runnable task = new Runnable() { | 643 Runnable task = new Runnable() { |
| 618 @Override | 644 @Override |
| 619 public void run() { | 645 public void run() { |
| 620 listener.onRttObservation(rttMs, whenMs, source); | 646 listener.onRttObservation(rttMs, whenMs, source); |
| 621 } | 647 } |
| 622 }; | 648 }; |
| 623 postObservationTaskToExecutor(listener.getExecutor(), task); | 649 postObservationTaskToExecutor(listener.getExecutor(), task); |
| 624 } | 650 } |
| 625 } | 651 } |
| 626 } | 652 } |
| 627 | 653 |
| 628 @SuppressWarnings("unused") | 654 @SuppressWarnings("unused") |
| 629 @CalledByNative | 655 @CalledByNative |
| 630 private void onThroughputObservation( | 656 private void onThroughputObservation( |
| 631 final int throughputKbps, final long whenMs, final int source) { | 657 final int throughputKbps, final long whenMs, final int source) { |
| 632 synchronized (mNetworkQualityLock) { | 658 synchronized (mNetworkQualityLock) { |
| 633 for (final NetworkQualityThroughputListener listener : mThroughputLi stenerList) { | 659 for (NetworkQualityThroughputListener unsafeListener : mThroughputLi stenerList) { |
| 660 final VersionSafeCallbacks.NetworkQualityThroughputListenerWrapp er listener = | |
| 661 mThroughputListenerMap.get(unsafeListener); | |
| 634 Runnable task = new Runnable() { | 662 Runnable task = new Runnable() { |
| 635 @Override | 663 @Override |
| 636 public void run() { | 664 public void run() { |
| 637 listener.onThroughputObservation(throughputKbps, whenMs, source); | 665 listener.onThroughputObservation(throughputKbps, whenMs, source); |
| 638 } | 666 } |
| 639 }; | 667 }; |
| 640 postObservationTaskToExecutor(listener.getExecutor(), task); | 668 postObservationTaskToExecutor(listener.getExecutor(), task); |
| 641 } | 669 } |
| 642 } | 670 } |
| 643 } | 671 } |
| 644 | 672 |
| 645 @SuppressWarnings("unused") | 673 @SuppressWarnings("unused") |
| 646 @CalledByNative | 674 @CalledByNative |
| 647 private void onGetCertVerifierData(String certVerifierData) { | 675 private void onGetCertVerifierData(String certVerifierData) { |
| 648 mCertVerifierData = certVerifierData; | 676 mCertVerifierData = certVerifierData; |
| 649 mWaitGetCertVerifierDataComplete.open(); | 677 mWaitGetCertVerifierDataComplete.open(); |
| 650 } | 678 } |
| 651 | 679 |
| 652 void reportFinished(final RequestFinishedInfo requestInfo) { | 680 void reportFinished(final RequestFinishedInfo requestInfo) { |
| 653 ArrayList<RequestFinishedInfo.Listener> currentListeners; | 681 ArrayList<VersionSafeCallbacks.RequestFinishedInfoListener> currentListe ners; |
| 654 synchronized (mFinishedListenerLock) { | 682 synchronized (mFinishedListenerLock) { |
| 655 currentListeners = new ArrayList<RequestFinishedInfo.Listener>(mFini shedListenerList); | 683 currentListeners = new ArrayList<VersionSafeCallbacks.RequestFinishe dInfoListener>( |
| 684 mFinishedListenerMap.values()); | |
| 656 } | 685 } |
| 657 for (final RequestFinishedInfo.Listener listener : currentListeners) { | 686 for (final VersionSafeCallbacks.RequestFinishedInfoListener listener : c urrentListeners) { |
| 658 Runnable task = new Runnable() { | 687 Runnable task = new Runnable() { |
| 659 @Override | 688 @Override |
| 660 public void run() { | 689 public void run() { |
| 661 listener.onRequestFinished(requestInfo); | 690 listener.onRequestFinished(requestInfo); |
| 662 } | 691 } |
| 663 }; | 692 }; |
| 664 postObservationTaskToExecutor(listener.getExecutor(), task); | 693 postObservationTaskToExecutor(listener.getExecutor(), task); |
| 665 } | 694 } |
| 666 } | 695 } |
| 667 | 696 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 722 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 751 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
| 723 private native void nativeProvideRTTObservations(long nativePtr, boolean sho uld); | 752 private native void nativeProvideRTTObservations(long nativePtr, boolean sho uld); |
| 724 | 753 |
| 725 @NativeClassQualifiedName("CronetURLRequestContextAdapter") | 754 @NativeClassQualifiedName("CronetURLRequestContextAdapter") |
| 726 private native void nativeProvideThroughputObservations(long nativePtr, bool ean should); | 755 private native void nativeProvideThroughputObservations(long nativePtr, bool ean should); |
| 727 | 756 |
| 728 public boolean isNetworkThread(Thread thread) { | 757 public boolean isNetworkThread(Thread thread) { |
| 729 return thread == mNetworkThread; | 758 return thread == mNetworkThread; |
| 730 } | 759 } |
| 731 } | 760 } |
| OLD | NEW |