Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 #include "net/base/network_quality_estimator.h" | 5 #include "net/base/network_quality_estimator.h" |
| 6 | 6 |
| 7 #include <float.h> | 7 #include <float.h> |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <cmath> | 9 #include <cmath> |
| 10 #include <limits> | 10 #include <limits> |
| 11 #include <utility> | 11 #include <utility> |
| 12 #include <vector> | 12 #include <vector> |
| 13 | 13 |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/metrics/histogram.h" | 15 #include "base/metrics/histogram.h" |
| 16 #include "base/metrics/histogram_base.h" | 16 #include "base/metrics/histogram_base.h" |
| 17 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
| 18 #include "base/thread_task_runner_handle.h" | |
| 18 #include "build/build_config.h" | 19 #include "build/build_config.h" |
| 19 #include "net/base/load_flags.h" | 20 #include "net/base/load_flags.h" |
| 20 #include "net/base/load_timing_info.h" | 21 #include "net/base/load_timing_info.h" |
| 21 #include "net/base/network_interfaces.h" | 22 #include "net/base/network_interfaces.h" |
| 22 #include "net/base/url_util.h" | 23 #include "net/base/url_util.h" |
| 23 #include "net/url_request/url_request.h" | 24 #include "net/url_request/url_request.h" |
| 24 #include "url/gurl.h" | 25 #include "url/gurl.h" |
| 25 | 26 |
| 26 #if defined(OS_ANDROID) | 27 #if defined(OS_ANDROID) |
| 27 #include "net/android/network_library.h" | 28 #include "net/android/network_library.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 134 bool allow_smaller_responses_for_tests) | 135 bool allow_smaller_responses_for_tests) |
| 135 : allow_localhost_requests_(allow_local_host_requests_for_tests), | 136 : allow_localhost_requests_(allow_local_host_requests_for_tests), |
| 136 allow_small_responses_(allow_smaller_responses_for_tests), | 137 allow_small_responses_(allow_smaller_responses_for_tests), |
| 137 last_connection_change_(base::TimeTicks::Now()), | 138 last_connection_change_(base::TimeTicks::Now()), |
| 138 current_network_id_( | 139 current_network_id_( |
| 139 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, | 140 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, |
| 140 std::string())), | 141 std::string())), |
| 141 downstream_throughput_kbps_observations_( | 142 downstream_throughput_kbps_observations_( |
| 142 GetWeightMultiplierPerSecond(variation_params)), | 143 GetWeightMultiplierPerSecond(variation_params)), |
| 143 rtt_observations_(GetWeightMultiplierPerSecond(variation_params)), | 144 rtt_observations_(GetWeightMultiplierPerSecond(variation_params)), |
| 144 external_estimate_provider_(std::move(external_estimates_provider)) { | 145 external_estimate_provider_(std::move(external_estimates_provider)), |
| 146 weak_ptr_factory_(this) { | |
| 145 static_assert(kMinRequestDurationMicroseconds > 0, | 147 static_assert(kMinRequestDurationMicroseconds > 0, |
| 146 "Minimum request duration must be > 0"); | 148 "Minimum request duration must be > 0"); |
| 147 static_assert(kDefaultHalfLifeSeconds > 0, | 149 static_assert(kDefaultHalfLifeSeconds > 0, |
| 148 "Default half life duration must be > 0"); | 150 "Default half life duration must be > 0"); |
| 149 static_assert(kMaximumNetworkQualityCacheSize > 0, | 151 static_assert(kMaximumNetworkQualityCacheSize > 0, |
| 150 "Size of the network quality cache must be > 0"); | 152 "Size of the network quality cache must be > 0"); |
| 151 // This limit should not be increased unless the logic for removing the | 153 // This limit should not be increased unless the logic for removing the |
| 152 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. | 154 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. |
| 153 static_assert(kMaximumNetworkQualityCacheSize <= 10, | 155 static_assert(kMaximumNetworkQualityCacheSize <= 10, |
| 154 "Size of the network quality cache must <= 10"); | 156 "Size of the network quality cache must <= 10"); |
| 155 | 157 |
| 156 ObtainOperatingParams(variation_params); | 158 ObtainOperatingParams(variation_params); |
| 157 NetworkChangeNotifier::AddConnectionTypeObserver(this); | 159 NetworkChangeNotifier::AddConnectionTypeObserver(this); |
| 158 if (external_estimate_provider_) { | 160 if (external_estimate_provider_) { |
| 159 RecordExternalEstimateProviderMetrics( | 161 RecordExternalEstimateProviderMetrics( |
| 160 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE); | 162 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE); |
| 161 external_estimate_provider_->SetUpdatedEstimateDelegate(this); | 163 external_estimate_provider_->SetUpdatedEstimateDelegate(this); |
| 162 QueryExternalEstimateProvider(); | 164 QueryExternalEstimateProvider(); |
| 163 } else { | 165 } else { |
| 164 RecordExternalEstimateProviderMetrics( | 166 RecordExternalEstimateProviderMetrics( |
| 165 EXTERNAL_ESTIMATE_PROVIDER_STATUS_NOT_AVAILABLE); | 167 EXTERNAL_ESTIMATE_PROVIDER_STATUS_NOT_AVAILABLE); |
| 166 } | 168 } |
| 167 current_network_id_ = GetCurrentNetworkID(); | 169 current_network_id_ = GetCurrentNetworkID(); |
| 168 AddDefaultEstimates(); | 170 AddDefaultEstimates(); |
| 171 | |
| 172 watcher_factory_.reset(new SocketWatcherFactory( | |
| 173 base::ThreadTaskRunnerHandle::Get(), GetWeakPtr())); | |
|
Ryan Sleevi
2016/04/02 00:48:20
s/GetWeakPtr()/weak_factory_.GetWeakPtr())
tbansal1
2016/04/04 16:55:44
Done.
| |
| 169 } | 174 } |
| 170 | 175 |
| 171 // static | 176 // static |
| 172 const base::TimeDelta NetworkQualityEstimator::InvalidRTT() { | 177 const base::TimeDelta NetworkQualityEstimator::InvalidRTT() { |
| 173 return base::TimeDelta::Max(); | 178 return base::TimeDelta::Max(); |
| 174 } | 179 } |
| 175 | 180 |
| 176 void NetworkQualityEstimator::ObtainOperatingParams( | 181 void NetworkQualityEstimator::ObtainOperatingParams( |
| 177 const std::map<std::string, std::string>& variation_params) { | 182 const std::map<std::string, std::string>& variation_params) { |
| 178 DCHECK(thread_checker_.CalledOnValidThread()); | 183 DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 369 DCHECK(thread_checker_.CalledOnValidThread()); | 374 DCHECK(thread_checker_.CalledOnValidThread()); |
| 370 throughput_observer_list_.AddObserver(throughput_observer); | 375 throughput_observer_list_.AddObserver(throughput_observer); |
| 371 } | 376 } |
| 372 | 377 |
| 373 void NetworkQualityEstimator::RemoveThroughputObserver( | 378 void NetworkQualityEstimator::RemoveThroughputObserver( |
| 374 ThroughputObserver* throughput_observer) { | 379 ThroughputObserver* throughput_observer) { |
| 375 DCHECK(thread_checker_.CalledOnValidThread()); | 380 DCHECK(thread_checker_.CalledOnValidThread()); |
| 376 throughput_observer_list_.RemoveObserver(throughput_observer); | 381 throughput_observer_list_.RemoveObserver(throughput_observer); |
| 377 } | 382 } |
| 378 | 383 |
| 384 SocketPerformanceWatcherFactory* | |
| 385 NetworkQualityEstimator::GetSocketPerformanceWatcherFactory() { | |
| 386 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 387 | |
| 388 return watcher_factory_.get(); | |
| 389 } | |
| 390 | |
| 379 void NetworkQualityEstimator::RecordRTTUMA(int32_t estimated_value_msec, | 391 void NetworkQualityEstimator::RecordRTTUMA(int32_t estimated_value_msec, |
| 380 int32_t actual_value_msec) const { | 392 int32_t actual_value_msec) const { |
| 381 DCHECK(thread_checker_.CalledOnValidThread()); | 393 DCHECK(thread_checker_.CalledOnValidThread()); |
| 382 | 394 |
| 383 // Record the difference between the actual and the estimated value. | 395 // Record the difference between the actual and the estimated value. |
| 384 if (estimated_value_msec >= actual_value_msec) { | 396 if (estimated_value_msec >= actual_value_msec) { |
| 385 base::HistogramBase* difference_rtt = | 397 base::HistogramBase* difference_rtt = |
| 386 GetHistogram("DifferenceRTTEstimatedAndActual.", | 398 GetHistogram("DifferenceRTTEstimatedAndActual.", |
| 387 current_network_id_.type, 10 * 1000); // 10 seconds | 399 current_network_id_.type, 10 * 1000); // 10 seconds |
| 388 difference_rtt->Add(estimated_value_msec - actual_value_msec); | 400 difference_rtt->Add(estimated_value_msec - actual_value_msec); |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 626 // a higher percentile RTT will have a longer RTT than a lower percentile. | 638 // a higher percentile RTT will have a longer RTT than a lower percentile. |
| 627 base::TimeDelta rtt = InvalidRTT(); | 639 base::TimeDelta rtt = InvalidRTT(); |
| 628 std::vector<ObservationSource> disallowed_observation_sources; | 640 std::vector<ObservationSource> disallowed_observation_sources; |
| 629 disallowed_observation_sources.push_back(TCP); | 641 disallowed_observation_sources.push_back(TCP); |
| 630 disallowed_observation_sources.push_back(QUIC); | 642 disallowed_observation_sources.push_back(QUIC); |
| 631 rtt_observations_.GetPercentile(begin_timestamp, &rtt, percentile, | 643 rtt_observations_.GetPercentile(begin_timestamp, &rtt, percentile, |
| 632 disallowed_observation_sources); | 644 disallowed_observation_sources); |
| 633 return rtt; | 645 return rtt; |
| 634 } | 646 } |
| 635 | 647 |
| 648 NetworkQualityEstimator::SocketWatcherFactory::SocketWatcherFactory( | |
| 649 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | |
| 650 const base::WeakPtr<NetworkQualityEstimator>& network_quality_estimator) | |
| 651 : task_runner_(task_runner), | |
| 652 network_quality_estimator_(network_quality_estimator) { | |
| 653 DCHECK(task_runner_); | |
| 654 } | |
| 655 | |
| 656 NetworkQualityEstimator::SocketWatcherFactory::~SocketWatcherFactory() {} | |
| 657 | |
| 658 scoped_ptr<SocketPerformanceWatcher> | |
| 659 NetworkQualityEstimator::SocketWatcherFactory::CreateSocketPerformanceWatcher( | |
| 660 SocketPerformanceWatcherFactory::Protocol protocol) { | |
| 661 return scoped_ptr<SocketPerformanceWatcher>( | |
| 662 new SocketWatcher(protocol, task_runner_, network_quality_estimator_)); | |
| 663 } | |
| 664 | |
| 665 NetworkQualityEstimator::SocketWatcher::SocketWatcher( | |
| 666 SocketPerformanceWatcherFactory::Protocol protocol, | |
| 667 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | |
| 668 const base::WeakPtr<NetworkQualityEstimator>& network_quality_estimator) | |
| 669 : protocol_(protocol), | |
| 670 task_runner_(task_runner), | |
| 671 network_quality_estimator_(network_quality_estimator) { | |
| 672 DCHECK(task_runner_); | |
| 673 DCHECK(network_quality_estimator_); | |
| 674 } | |
| 675 | |
| 676 NetworkQualityEstimator::SocketWatcher::~SocketWatcher() {} | |
| 677 | |
| 678 void NetworkQualityEstimator::SocketWatcher::OnUpdatedRTTAvailable( | |
| 679 const base::TimeDelta& rtt) { | |
| 680 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 681 | |
| 682 task_runner_->PostTask( | |
| 683 FROM_HERE, base::Bind(&NetworkQualityEstimator::OnUpdatedRTTAvailable, | |
| 684 network_quality_estimator_, protocol_, rtt)); | |
| 685 } | |
| 686 | |
| 687 bool NetworkQualityEstimator::SocketWatcher::ShouldNotifyUpdatedRTT() const { | |
| 688 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 689 | |
| 690 return true; | |
| 691 } | |
| 692 | |
| 693 void NetworkQualityEstimator::SocketWatcher::Reset() { | |
| 694 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 695 } | |
| 696 | |
| 636 int32_t NetworkQualityEstimator::GetDownlinkThroughputKbpsEstimateInternal( | 697 int32_t NetworkQualityEstimator::GetDownlinkThroughputKbpsEstimateInternal( |
| 637 const base::TimeTicks& begin_timestamp, | 698 const base::TimeTicks& begin_timestamp, |
| 638 int percentile) const { | 699 int percentile) const { |
| 639 DCHECK(thread_checker_.CalledOnValidThread()); | 700 DCHECK(thread_checker_.CalledOnValidThread()); |
| 640 DCHECK_GE(percentile, 0); | 701 DCHECK_GE(percentile, 0); |
| 641 DCHECK_LE(percentile, 100); | 702 DCHECK_LE(percentile, 100); |
| 642 if (downstream_throughput_kbps_observations_.Size() == 0) | 703 if (downstream_throughput_kbps_observations_.Size() == 0) |
| 643 return kInvalidThroughput; | 704 return kInvalidThroughput; |
| 644 | 705 |
| 645 // Throughput observations are sorted by kbps from slowest to fastest, | 706 // Throughput observations are sorted by kbps from slowest to fastest, |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 897 } | 958 } |
| 898 DCHECK_LT(cached_network_qualities_.size(), | 959 DCHECK_LT(cached_network_qualities_.size(), |
| 899 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 960 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
| 900 | 961 |
| 901 cached_network_qualities_.insert(std::make_pair( | 962 cached_network_qualities_.insert(std::make_pair( |
| 902 current_network_id_, CachedNetworkQuality(network_quality))); | 963 current_network_id_, CachedNetworkQuality(network_quality))); |
| 903 DCHECK_LE(cached_network_qualities_.size(), | 964 DCHECK_LE(cached_network_qualities_.size(), |
| 904 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 965 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
| 905 } | 966 } |
| 906 | 967 |
| 907 scoped_ptr<SocketPerformanceWatcher> | |
| 908 NetworkQualityEstimator::CreateSocketPerformanceWatcher( | |
| 909 const Protocol protocol) { | |
| 910 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 911 | |
| 912 return scoped_ptr<SocketPerformanceWatcher>( | |
| 913 new SocketPerformanceWatcher(protocol, this)); | |
| 914 } | |
| 915 | |
| 916 void NetworkQualityEstimator::OnUpdatedRTTAvailable( | 968 void NetworkQualityEstimator::OnUpdatedRTTAvailable( |
| 917 const Protocol protocol, | 969 SocketPerformanceWatcherFactory::Protocol protocol, |
| 918 const base::TimeDelta& rtt) { | 970 const base::TimeDelta& rtt) { |
| 919 DCHECK(thread_checker_.CalledOnValidThread()); | 971 DCHECK(thread_checker_.CalledOnValidThread()); |
| 920 | 972 |
| 921 switch (protocol) { | 973 switch (protocol) { |
| 922 case PROTOCOL_TCP: | 974 case SocketPerformanceWatcherFactory::PROTOCOL_TCP: |
| 923 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), TCP)); | 975 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), TCP)); |
| 924 return; | 976 return; |
| 925 case PROTOCOL_QUIC: | 977 case SocketPerformanceWatcherFactory::PROTOCOL_QUIC: |
| 926 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), QUIC)); | 978 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), QUIC)); |
| 927 return; | 979 return; |
| 928 default: | 980 default: |
| 929 NOTREACHED(); | 981 NOTREACHED(); |
| 930 } | 982 } |
| 931 } | 983 } |
| 932 | 984 |
| 933 void NetworkQualityEstimator::NotifyObserversOfRTT( | 985 void NetworkQualityEstimator::NotifyObserversOfRTT( |
| 934 const RttObservation& observation) { | 986 const RttObservation& observation) { |
| 935 FOR_EACH_OBSERVER( | 987 FOR_EACH_OBSERVER( |
| 936 RTTObserver, rtt_observer_list_, | 988 RTTObserver, rtt_observer_list_, |
| 937 OnRTTObservation(observation.value.InMilliseconds(), | 989 OnRTTObservation(observation.value.InMilliseconds(), |
| 938 observation.timestamp, observation.source)); | 990 observation.timestamp, observation.source)); |
| 939 } | 991 } |
| 940 | 992 |
| 941 void NetworkQualityEstimator::NotifyObserversOfThroughput( | 993 void NetworkQualityEstimator::NotifyObserversOfThroughput( |
| 942 const ThroughputObservation& observation) { | 994 const ThroughputObservation& observation) { |
| 943 FOR_EACH_OBSERVER( | 995 FOR_EACH_OBSERVER( |
| 944 ThroughputObserver, throughput_observer_list_, | 996 ThroughputObserver, throughput_observer_list_, |
| 945 OnThroughputObservation(observation.value, observation.timestamp, | 997 OnThroughputObservation(observation.value, observation.timestamp, |
| 946 observation.source)); | 998 observation.source)); |
| 947 } | 999 } |
| 948 | 1000 |
| 1001 base::WeakPtr<NetworkQualityEstimator> NetworkQualityEstimator::GetWeakPtr() { | |
| 1002 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 1003 | |
| 1004 return weak_ptr_factory_.GetWeakPtr(); | |
| 1005 } | |
| 1006 | |
| 949 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( | 1007 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( |
| 950 const NetworkQuality& network_quality) | 1008 const NetworkQuality& network_quality) |
| 951 : last_update_time_(base::TimeTicks::Now()), | 1009 : last_update_time_(base::TimeTicks::Now()), |
| 952 network_quality_(network_quality) { | 1010 network_quality_(network_quality) { |
| 953 } | 1011 } |
| 954 | 1012 |
| 955 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( | 1013 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( |
| 956 const CachedNetworkQuality& other) | 1014 const CachedNetworkQuality& other) |
| 957 : last_update_time_(other.last_update_time_), | 1015 : last_update_time_(other.last_update_time_), |
| 958 network_quality_(other.network_quality_) { | 1016 network_quality_(other.network_quality_) { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 986 | 1044 |
| 987 NetworkQualityEstimator::NetworkQuality& | 1045 NetworkQualityEstimator::NetworkQuality& |
| 988 NetworkQualityEstimator::NetworkQuality:: | 1046 NetworkQualityEstimator::NetworkQuality:: |
| 989 operator=(const NetworkQuality& other) { | 1047 operator=(const NetworkQuality& other) { |
| 990 rtt_ = other.rtt_; | 1048 rtt_ = other.rtt_; |
| 991 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; | 1049 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; |
| 992 return *this; | 1050 return *this; |
| 993 } | 1051 } |
| 994 | 1052 |
| 995 } // namespace net | 1053 } // namespace net |
| OLD | NEW |