| 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 "base/trace_event/trace_event.h" | 19 #include "base/trace_event/trace_event.h" |
| 19 #include "build/build_config.h" | 20 #include "build/build_config.h" |
| 20 #include "net/base/load_flags.h" | 21 #include "net/base/load_flags.h" |
| 21 #include "net/base/load_timing_info.h" | 22 #include "net/base/load_timing_info.h" |
| 22 #include "net/base/network_interfaces.h" | 23 #include "net/base/network_interfaces.h" |
| 24 #include "net/base/socket_performance_watcher.h" |
| 23 #include "net/base/url_util.h" | 25 #include "net/base/url_util.h" |
| 24 #include "net/url_request/url_request.h" | 26 #include "net/url_request/url_request.h" |
| 25 #include "url/gurl.h" | 27 #include "url/gurl.h" |
| 26 | 28 |
| 27 #if defined(OS_ANDROID) | 29 #if defined(OS_ANDROID) |
| 28 #include "net/android/network_library.h" | 30 #include "net/android/network_library.h" |
| 29 #endif // OS_ANDROID | 31 #endif // OS_ANDROID |
| 30 | 32 |
| 31 namespace { | 33 namespace { |
| 32 | 34 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 const char prefix[] = "NQE."; | 113 const char prefix[] = "NQE."; |
| 112 return base::Histogram::FactoryGet( | 114 return base::Histogram::FactoryGet( |
| 113 prefix + statistic_name + GetNameForConnectionType(type), kLowerLimit, | 115 prefix + statistic_name + GetNameForConnectionType(type), kLowerLimit, |
| 114 max_limit, kBucketCount, base::HistogramBase::kUmaTargetedHistogramFlag); | 116 max_limit, kBucketCount, base::HistogramBase::kUmaTargetedHistogramFlag); |
| 115 } | 117 } |
| 116 | 118 |
| 117 } // namespace | 119 } // namespace |
| 118 | 120 |
| 119 namespace net { | 121 namespace net { |
| 120 | 122 |
| 123 // SocketWatcher implements SocketPerformanceWatcher, and notifies |
| 124 // NetworkQualityEstimator of various socket performance events. SocketWatcher |
| 125 // is not thread-safe. |
| 126 class NetworkQualityEstimator::SocketWatcher : public SocketPerformanceWatcher { |
| 127 public: |
| 128 SocketWatcher( |
| 129 SocketPerformanceWatcherFactory::Protocol protocol, |
| 130 scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| 131 const base::WeakPtr<NetworkQualityEstimator>& network_quality_estimator) |
| 132 : protocol_(protocol), |
| 133 task_runner_(std::move(task_runner)), |
| 134 network_quality_estimator_(network_quality_estimator) {} |
| 135 |
| 136 ~SocketWatcher() override {} |
| 137 |
| 138 // SocketPerformanceWatcher implementation: |
| 139 bool ShouldNotifyUpdatedRTT() const override { |
| 140 DCHECK(thread_checker_.CalledOnValidThread()); |
| 141 |
| 142 return true; |
| 143 } |
| 144 |
| 145 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override { |
| 146 DCHECK(thread_checker_.CalledOnValidThread()); |
| 147 |
| 148 task_runner_->PostTask( |
| 149 FROM_HERE, base::Bind(&NetworkQualityEstimator::OnUpdatedRTTAvailable, |
| 150 network_quality_estimator_, protocol_, rtt)); |
| 151 } |
| 152 |
| 153 void OnConnectionChanged() override { |
| 154 DCHECK(thread_checker_.CalledOnValidThread()); |
| 155 } |
| 156 |
| 157 private: |
| 158 // Transport layer protocol used by the socket that |this| is watching. |
| 159 const SocketPerformanceWatcherFactory::Protocol protocol_; |
| 160 |
| 161 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 162 |
| 163 base::WeakPtr<NetworkQualityEstimator> network_quality_estimator_; |
| 164 |
| 165 base::ThreadChecker thread_checker_; |
| 166 |
| 167 DISALLOW_COPY_AND_ASSIGN(SocketWatcher); |
| 168 }; |
| 169 |
| 170 // SocketWatcherFactory implements SocketPerformanceWatcherFactory, and is |
| 171 // owned by NetworkQualityEstimator. SocketWatcherFactory is thread safe. |
| 172 class NetworkQualityEstimator::SocketWatcherFactory |
| 173 : public SocketPerformanceWatcherFactory { |
| 174 public: |
| 175 SocketWatcherFactory( |
| 176 scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| 177 const base::WeakPtr<NetworkQualityEstimator>& network_quality_estimator) |
| 178 : task_runner_(std::move(task_runner)), |
| 179 network_quality_estimator_(network_quality_estimator) {} |
| 180 |
| 181 ~SocketWatcherFactory() override {} |
| 182 |
| 183 // SocketPerformanceWatcherFactory implementation: |
| 184 scoped_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher( |
| 185 const Protocol protocol) override { |
| 186 return scoped_ptr<SocketPerformanceWatcher>( |
| 187 new SocketWatcher(protocol, task_runner_, network_quality_estimator_)); |
| 188 } |
| 189 |
| 190 private: |
| 191 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 192 |
| 193 base::WeakPtr<NetworkQualityEstimator> network_quality_estimator_; |
| 194 |
| 195 DISALLOW_COPY_AND_ASSIGN(SocketWatcherFactory); |
| 196 }; |
| 197 |
| 121 const int32_t NetworkQualityEstimator::kInvalidThroughput = 0; | 198 const int32_t NetworkQualityEstimator::kInvalidThroughput = 0; |
| 122 | 199 |
| 123 NetworkQualityEstimator::NetworkQualityEstimator( | 200 NetworkQualityEstimator::NetworkQualityEstimator( |
| 124 scoped_ptr<ExternalEstimateProvider> external_estimates_provider, | 201 scoped_ptr<ExternalEstimateProvider> external_estimates_provider, |
| 125 const std::map<std::string, std::string>& variation_params) | 202 const std::map<std::string, std::string>& variation_params) |
| 126 : NetworkQualityEstimator(std::move(external_estimates_provider), | 203 : NetworkQualityEstimator(std::move(external_estimates_provider), |
| 127 variation_params, | 204 variation_params, |
| 128 false, | 205 false, |
| 129 false) {} | 206 false) {} |
| 130 | 207 |
| 131 NetworkQualityEstimator::NetworkQualityEstimator( | 208 NetworkQualityEstimator::NetworkQualityEstimator( |
| 132 scoped_ptr<ExternalEstimateProvider> external_estimates_provider, | 209 scoped_ptr<ExternalEstimateProvider> external_estimates_provider, |
| 133 const std::map<std::string, std::string>& variation_params, | 210 const std::map<std::string, std::string>& variation_params, |
| 134 bool allow_local_host_requests_for_tests, | 211 bool allow_local_host_requests_for_tests, |
| 135 bool allow_smaller_responses_for_tests) | 212 bool allow_smaller_responses_for_tests) |
| 136 : allow_localhost_requests_(allow_local_host_requests_for_tests), | 213 : allow_localhost_requests_(allow_local_host_requests_for_tests), |
| 137 allow_small_responses_(allow_smaller_responses_for_tests), | 214 allow_small_responses_(allow_smaller_responses_for_tests), |
| 138 last_connection_change_(base::TimeTicks::Now()), | 215 last_connection_change_(base::TimeTicks::Now()), |
| 139 current_network_id_( | 216 current_network_id_( |
| 140 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, | 217 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, |
| 141 std::string())), | 218 std::string())), |
| 142 downstream_throughput_kbps_observations_( | 219 downstream_throughput_kbps_observations_( |
| 143 GetWeightMultiplierPerSecond(variation_params)), | 220 GetWeightMultiplierPerSecond(variation_params)), |
| 144 rtt_observations_(GetWeightMultiplierPerSecond(variation_params)), | 221 rtt_observations_(GetWeightMultiplierPerSecond(variation_params)), |
| 145 external_estimate_provider_(std::move(external_estimates_provider)) { | 222 external_estimate_provider_(std::move(external_estimates_provider)), |
| 223 weak_ptr_factory_(this) { |
| 146 static_assert(kMinRequestDurationMicroseconds > 0, | 224 static_assert(kMinRequestDurationMicroseconds > 0, |
| 147 "Minimum request duration must be > 0"); | 225 "Minimum request duration must be > 0"); |
| 148 static_assert(kDefaultHalfLifeSeconds > 0, | 226 static_assert(kDefaultHalfLifeSeconds > 0, |
| 149 "Default half life duration must be > 0"); | 227 "Default half life duration must be > 0"); |
| 150 static_assert(kMaximumNetworkQualityCacheSize > 0, | 228 static_assert(kMaximumNetworkQualityCacheSize > 0, |
| 151 "Size of the network quality cache must be > 0"); | 229 "Size of the network quality cache must be > 0"); |
| 152 // This limit should not be increased unless the logic for removing the | 230 // This limit should not be increased unless the logic for removing the |
| 153 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. | 231 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. |
| 154 static_assert(kMaximumNetworkQualityCacheSize <= 10, | 232 static_assert(kMaximumNetworkQualityCacheSize <= 10, |
| 155 "Size of the network quality cache must <= 10"); | 233 "Size of the network quality cache must <= 10"); |
| 156 | 234 |
| 157 ObtainOperatingParams(variation_params); | 235 ObtainOperatingParams(variation_params); |
| 158 NetworkChangeNotifier::AddConnectionTypeObserver(this); | 236 NetworkChangeNotifier::AddConnectionTypeObserver(this); |
| 159 if (external_estimate_provider_) { | 237 if (external_estimate_provider_) { |
| 160 RecordExternalEstimateProviderMetrics( | 238 RecordExternalEstimateProviderMetrics( |
| 161 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE); | 239 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE); |
| 162 external_estimate_provider_->SetUpdatedEstimateDelegate(this); | 240 external_estimate_provider_->SetUpdatedEstimateDelegate(this); |
| 163 QueryExternalEstimateProvider(); | 241 QueryExternalEstimateProvider(); |
| 164 } else { | 242 } else { |
| 165 RecordExternalEstimateProviderMetrics( | 243 RecordExternalEstimateProviderMetrics( |
| 166 EXTERNAL_ESTIMATE_PROVIDER_STATUS_NOT_AVAILABLE); | 244 EXTERNAL_ESTIMATE_PROVIDER_STATUS_NOT_AVAILABLE); |
| 167 } | 245 } |
| 168 current_network_id_ = GetCurrentNetworkID(); | 246 current_network_id_ = GetCurrentNetworkID(); |
| 169 AddDefaultEstimates(); | 247 AddDefaultEstimates(); |
| 248 |
| 249 watcher_factory_.reset(new SocketWatcherFactory( |
| 250 base::ThreadTaskRunnerHandle::Get(), weak_ptr_factory_.GetWeakPtr())); |
| 170 } | 251 } |
| 171 | 252 |
| 172 // static | 253 // static |
| 173 const base::TimeDelta NetworkQualityEstimator::InvalidRTT() { | 254 const base::TimeDelta NetworkQualityEstimator::InvalidRTT() { |
| 174 return base::TimeDelta::Max(); | 255 return base::TimeDelta::Max(); |
| 175 } | 256 } |
| 176 | 257 |
| 177 void NetworkQualityEstimator::ObtainOperatingParams( | 258 void NetworkQualityEstimator::ObtainOperatingParams( |
| 178 const std::map<std::string, std::string>& variation_params) { | 259 const std::map<std::string, std::string>& variation_params) { |
| 179 DCHECK(thread_checker_.CalledOnValidThread()); | 260 DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 DCHECK(thread_checker_.CalledOnValidThread()); | 455 DCHECK(thread_checker_.CalledOnValidThread()); |
| 375 throughput_observer_list_.AddObserver(throughput_observer); | 456 throughput_observer_list_.AddObserver(throughput_observer); |
| 376 } | 457 } |
| 377 | 458 |
| 378 void NetworkQualityEstimator::RemoveThroughputObserver( | 459 void NetworkQualityEstimator::RemoveThroughputObserver( |
| 379 ThroughputObserver* throughput_observer) { | 460 ThroughputObserver* throughput_observer) { |
| 380 DCHECK(thread_checker_.CalledOnValidThread()); | 461 DCHECK(thread_checker_.CalledOnValidThread()); |
| 381 throughput_observer_list_.RemoveObserver(throughput_observer); | 462 throughput_observer_list_.RemoveObserver(throughput_observer); |
| 382 } | 463 } |
| 383 | 464 |
| 465 SocketPerformanceWatcherFactory* |
| 466 NetworkQualityEstimator::GetSocketPerformanceWatcherFactory() { |
| 467 DCHECK(thread_checker_.CalledOnValidThread()); |
| 468 |
| 469 return watcher_factory_.get(); |
| 470 } |
| 471 |
| 384 void NetworkQualityEstimator::RecordRTTUMA(int32_t estimated_value_msec, | 472 void NetworkQualityEstimator::RecordRTTUMA(int32_t estimated_value_msec, |
| 385 int32_t actual_value_msec) const { | 473 int32_t actual_value_msec) const { |
| 386 DCHECK(thread_checker_.CalledOnValidThread()); | 474 DCHECK(thread_checker_.CalledOnValidThread()); |
| 387 | 475 |
| 388 // Record the difference between the actual and the estimated value. | 476 // Record the difference between the actual and the estimated value. |
| 389 if (estimated_value_msec >= actual_value_msec) { | 477 if (estimated_value_msec >= actual_value_msec) { |
| 390 base::HistogramBase* difference_rtt = | 478 base::HistogramBase* difference_rtt = |
| 391 GetHistogram("DifferenceRTTEstimatedAndActual.", | 479 GetHistogram("DifferenceRTTEstimatedAndActual.", |
| 392 current_network_id_.type, 10 * 1000); // 10 seconds | 480 current_network_id_.type, 10 * 1000); // 10 seconds |
| 393 difference_rtt->Add(estimated_value_msec - actual_value_msec); | 481 difference_rtt->Add(estimated_value_msec - actual_value_msec); |
| (...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 902 } | 990 } |
| 903 DCHECK_LT(cached_network_qualities_.size(), | 991 DCHECK_LT(cached_network_qualities_.size(), |
| 904 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 992 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
| 905 | 993 |
| 906 cached_network_qualities_.insert(std::make_pair( | 994 cached_network_qualities_.insert(std::make_pair( |
| 907 current_network_id_, CachedNetworkQuality(network_quality))); | 995 current_network_id_, CachedNetworkQuality(network_quality))); |
| 908 DCHECK_LE(cached_network_qualities_.size(), | 996 DCHECK_LE(cached_network_qualities_.size(), |
| 909 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 997 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
| 910 } | 998 } |
| 911 | 999 |
| 912 scoped_ptr<SocketPerformanceWatcher> | |
| 913 NetworkQualityEstimator::CreateSocketPerformanceWatcher( | |
| 914 const Protocol protocol) { | |
| 915 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 916 | |
| 917 return scoped_ptr<SocketPerformanceWatcher>( | |
| 918 new SocketPerformanceWatcher(protocol, this)); | |
| 919 } | |
| 920 | |
| 921 void NetworkQualityEstimator::OnUpdatedRTTAvailable( | 1000 void NetworkQualityEstimator::OnUpdatedRTTAvailable( |
| 922 const Protocol protocol, | 1001 SocketPerformanceWatcherFactory::Protocol protocol, |
| 923 const base::TimeDelta& rtt) { | 1002 const base::TimeDelta& rtt) { |
| 924 DCHECK(thread_checker_.CalledOnValidThread()); | 1003 DCHECK(thread_checker_.CalledOnValidThread()); |
| 925 | 1004 |
| 926 switch (protocol) { | 1005 switch (protocol) { |
| 927 case PROTOCOL_TCP: | 1006 case SocketPerformanceWatcherFactory::PROTOCOL_TCP: |
| 928 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), TCP)); | 1007 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), TCP)); |
| 929 return; | 1008 return; |
| 930 case PROTOCOL_QUIC: | 1009 case SocketPerformanceWatcherFactory::PROTOCOL_QUIC: |
| 931 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), QUIC)); | 1010 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), QUIC)); |
| 932 return; | 1011 return; |
| 933 default: | 1012 default: |
| 934 NOTREACHED(); | 1013 NOTREACHED(); |
| 935 } | 1014 } |
| 936 } | 1015 } |
| 937 | 1016 |
| 938 void NetworkQualityEstimator::NotifyObserversOfRTT( | 1017 void NetworkQualityEstimator::NotifyObserversOfRTT( |
| 939 const RttObservation& observation) { | 1018 const RttObservation& observation) { |
| 940 FOR_EACH_OBSERVER( | 1019 FOR_EACH_OBSERVER( |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 991 | 1070 |
| 992 NetworkQualityEstimator::NetworkQuality& | 1071 NetworkQualityEstimator::NetworkQuality& |
| 993 NetworkQualityEstimator::NetworkQuality:: | 1072 NetworkQualityEstimator::NetworkQuality:: |
| 994 operator=(const NetworkQuality& other) { | 1073 operator=(const NetworkQuality& other) { |
| 995 rtt_ = other.rtt_; | 1074 rtt_ = other.rtt_; |
| 996 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; | 1075 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; |
| 997 return *this; | 1076 return *this; |
| 998 } | 1077 } |
| 999 | 1078 |
| 1000 } // namespace net | 1079 } // namespace net |
| OLD | NEW |