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 |