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" |
23 #include "net/base/socket_performance_watcher.h" | |
22 #include "net/base/url_util.h" | 24 #include "net/base/url_util.h" |
23 #include "net/url_request/url_request.h" | 25 #include "net/url_request/url_request.h" |
24 #include "url/gurl.h" | 26 #include "url/gurl.h" |
25 | 27 |
26 #if defined(OS_ANDROID) | 28 #if defined(OS_ANDROID) |
27 #include "net/android/network_library.h" | 29 #include "net/android/network_library.h" |
28 #endif // OS_ANDROID | 30 #endif // OS_ANDROID |
29 | 31 |
30 namespace { | 32 namespace { |
31 | 33 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
110 const char prefix[] = "NQE."; | 112 const char prefix[] = "NQE."; |
111 return base::Histogram::FactoryGet( | 113 return base::Histogram::FactoryGet( |
112 prefix + statistic_name + GetNameForConnectionType(type), kLowerLimit, | 114 prefix + statistic_name + GetNameForConnectionType(type), kLowerLimit, |
113 max_limit, kBucketCount, base::HistogramBase::kUmaTargetedHistogramFlag); | 115 max_limit, kBucketCount, base::HistogramBase::kUmaTargetedHistogramFlag); |
114 } | 116 } |
115 | 117 |
116 } // namespace | 118 } // namespace |
117 | 119 |
118 namespace net { | 120 namespace net { |
119 | 121 |
122 // SocketWatcher implements SocketPerformanceWatcher, and notifies | |
123 // NetworkQualityEstimator of various socket performance events. SocketWatcher | |
124 // is not thread-safe. | |
125 class NetworkQualityEstimator::SocketWatcher : public SocketPerformanceWatcher { | |
bengr
2016/04/07 00:20:05
Any chance I could convince you to move this to an
Ryan Sleevi
2016/04/07 00:27:53
I specifically asked for this. I don't feel you ca
tbansal1
2016/04/07 01:43:36
Acknowledged.
| |
126 public: | |
127 SocketWatcher( | |
128 SocketPerformanceWatcherFactory::Protocol protocol, | |
Ryan Sleevi
2016/04/04 22:34:04
DESIGN NOTE (Future): As/if you change SocketPerfo
tbansal1
2016/04/04 23:46:32
OK, I will write down a quick design note to see w
| |
129 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
130 const base::WeakPtr<NetworkQualityEstimator>& network_quality_estimator) | |
131 : protocol_(protocol), | |
132 task_runner_(std::move(task_runner)), | |
133 network_quality_estimator_(network_quality_estimator) {} | |
134 | |
135 ~SocketWatcher() override {} | |
136 | |
137 // SocketPerformanceWatcher implementation: | |
138 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override { | |
139 DCHECK(thread_checker_.CalledOnValidThread()); | |
140 | |
141 task_runner_->PostTask( | |
142 FROM_HERE, base::Bind(&NetworkQualityEstimator::OnUpdatedRTTAvailable, | |
143 network_quality_estimator_, protocol_, rtt)); | |
144 } | |
145 | |
146 bool ShouldNotifyUpdatedRTT() const override { | |
147 DCHECK(thread_checker_.CalledOnValidThread()); | |
148 | |
149 return true; | |
150 } | |
151 | |
152 void Reset() override { DCHECK(thread_checker_.CalledOnValidThread()); } | |
153 | |
154 private: | |
155 // Transport layer protocol used by the socket that |this| is watching. | |
156 const SocketPerformanceWatcherFactory::Protocol protocol_; | |
bengr
2016/04/07 00:20:05
I agree with Ryan's design note above.
tbansal1
2016/04/07 01:43:36
I believe the eventual decision was to keep 1 fact
| |
157 | |
158 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | |
159 | |
160 base::WeakPtr<NetworkQualityEstimator> network_quality_estimator_; | |
161 | |
162 base::ThreadChecker thread_checker_; | |
163 | |
164 DISALLOW_COPY_AND_ASSIGN(SocketWatcher); | |
165 }; | |
166 | |
167 // SocketWatcherFactory implements SocketPerformanceWatcherFactory, and is | |
168 // owned by NetworkQualityEstimator. SocketWatcherFactory is thread safe. | |
169 class NetworkQualityEstimator::SocketWatcherFactory | |
170 : public SocketPerformanceWatcherFactory { | |
171 public: | |
172 SocketWatcherFactory( | |
173 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
174 const base::WeakPtr<NetworkQualityEstimator>& network_quality_estimator) | |
175 : task_runner_(std::move(task_runner)), | |
176 network_quality_estimator_(network_quality_estimator) {} | |
177 | |
178 ~SocketWatcherFactory() override {} | |
179 | |
180 // SocketPerformanceWatcherFactory implementation: | |
181 scoped_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher( | |
182 const Protocol protocol) override { | |
183 return scoped_ptr<SocketPerformanceWatcher>( | |
184 new SocketWatcher(protocol, task_runner_, network_quality_estimator_)); | |
185 } | |
186 | |
187 private: | |
188 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | |
189 | |
190 base::WeakPtr<NetworkQualityEstimator> network_quality_estimator_; | |
191 | |
192 DISALLOW_COPY_AND_ASSIGN(SocketWatcherFactory); | |
193 }; | |
194 | |
120 const int32_t NetworkQualityEstimator::kInvalidThroughput = 0; | 195 const int32_t NetworkQualityEstimator::kInvalidThroughput = 0; |
121 | 196 |
122 NetworkQualityEstimator::NetworkQualityEstimator( | 197 NetworkQualityEstimator::NetworkQualityEstimator( |
123 scoped_ptr<ExternalEstimateProvider> external_estimates_provider, | 198 scoped_ptr<ExternalEstimateProvider> external_estimates_provider, |
124 const std::map<std::string, std::string>& variation_params) | 199 const std::map<std::string, std::string>& variation_params) |
125 : NetworkQualityEstimator(std::move(external_estimates_provider), | 200 : NetworkQualityEstimator(std::move(external_estimates_provider), |
126 variation_params, | 201 variation_params, |
127 false, | 202 false, |
128 false) {} | 203 false) {} |
129 | 204 |
130 NetworkQualityEstimator::NetworkQualityEstimator( | 205 NetworkQualityEstimator::NetworkQualityEstimator( |
131 scoped_ptr<ExternalEstimateProvider> external_estimates_provider, | 206 scoped_ptr<ExternalEstimateProvider> external_estimates_provider, |
132 const std::map<std::string, std::string>& variation_params, | 207 const std::map<std::string, std::string>& variation_params, |
133 bool allow_local_host_requests_for_tests, | 208 bool allow_local_host_requests_for_tests, |
134 bool allow_smaller_responses_for_tests) | 209 bool allow_smaller_responses_for_tests) |
135 : allow_localhost_requests_(allow_local_host_requests_for_tests), | 210 : allow_localhost_requests_(allow_local_host_requests_for_tests), |
136 allow_small_responses_(allow_smaller_responses_for_tests), | 211 allow_small_responses_(allow_smaller_responses_for_tests), |
137 last_connection_change_(base::TimeTicks::Now()), | 212 last_connection_change_(base::TimeTicks::Now()), |
138 current_network_id_( | 213 current_network_id_( |
139 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, | 214 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, |
140 std::string())), | 215 std::string())), |
141 downstream_throughput_kbps_observations_( | 216 downstream_throughput_kbps_observations_( |
142 GetWeightMultiplierPerSecond(variation_params)), | 217 GetWeightMultiplierPerSecond(variation_params)), |
143 rtt_observations_(GetWeightMultiplierPerSecond(variation_params)), | 218 rtt_observations_(GetWeightMultiplierPerSecond(variation_params)), |
144 external_estimate_provider_(std::move(external_estimates_provider)) { | 219 external_estimate_provider_(std::move(external_estimates_provider)), |
220 weak_ptr_factory_(this) { | |
145 static_assert(kMinRequestDurationMicroseconds > 0, | 221 static_assert(kMinRequestDurationMicroseconds > 0, |
146 "Minimum request duration must be > 0"); | 222 "Minimum request duration must be > 0"); |
147 static_assert(kDefaultHalfLifeSeconds > 0, | 223 static_assert(kDefaultHalfLifeSeconds > 0, |
148 "Default half life duration must be > 0"); | 224 "Default half life duration must be > 0"); |
149 static_assert(kMaximumNetworkQualityCacheSize > 0, | 225 static_assert(kMaximumNetworkQualityCacheSize > 0, |
150 "Size of the network quality cache must be > 0"); | 226 "Size of the network quality cache must be > 0"); |
151 // This limit should not be increased unless the logic for removing the | 227 // 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. | 228 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. |
153 static_assert(kMaximumNetworkQualityCacheSize <= 10, | 229 static_assert(kMaximumNetworkQualityCacheSize <= 10, |
154 "Size of the network quality cache must <= 10"); | 230 "Size of the network quality cache must <= 10"); |
155 | 231 |
156 ObtainOperatingParams(variation_params); | 232 ObtainOperatingParams(variation_params); |
157 NetworkChangeNotifier::AddConnectionTypeObserver(this); | 233 NetworkChangeNotifier::AddConnectionTypeObserver(this); |
158 if (external_estimate_provider_) { | 234 if (external_estimate_provider_) { |
159 RecordExternalEstimateProviderMetrics( | 235 RecordExternalEstimateProviderMetrics( |
160 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE); | 236 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE); |
161 external_estimate_provider_->SetUpdatedEstimateDelegate(this); | 237 external_estimate_provider_->SetUpdatedEstimateDelegate(this); |
162 QueryExternalEstimateProvider(); | 238 QueryExternalEstimateProvider(); |
163 } else { | 239 } else { |
164 RecordExternalEstimateProviderMetrics( | 240 RecordExternalEstimateProviderMetrics( |
165 EXTERNAL_ESTIMATE_PROVIDER_STATUS_NOT_AVAILABLE); | 241 EXTERNAL_ESTIMATE_PROVIDER_STATUS_NOT_AVAILABLE); |
166 } | 242 } |
167 current_network_id_ = GetCurrentNetworkID(); | 243 current_network_id_ = GetCurrentNetworkID(); |
168 AddDefaultEstimates(); | 244 AddDefaultEstimates(); |
245 | |
246 watcher_factory_.reset(new SocketWatcherFactory( | |
247 base::ThreadTaskRunnerHandle::Get(), weak_ptr_factory_.GetWeakPtr())); | |
169 } | 248 } |
170 | 249 |
171 // static | 250 // static |
172 const base::TimeDelta NetworkQualityEstimator::InvalidRTT() { | 251 const base::TimeDelta NetworkQualityEstimator::InvalidRTT() { |
173 return base::TimeDelta::Max(); | 252 return base::TimeDelta::Max(); |
174 } | 253 } |
175 | 254 |
176 void NetworkQualityEstimator::ObtainOperatingParams( | 255 void NetworkQualityEstimator::ObtainOperatingParams( |
177 const std::map<std::string, std::string>& variation_params) { | 256 const std::map<std::string, std::string>& variation_params) { |
178 DCHECK(thread_checker_.CalledOnValidThread()); | 257 DCHECK(thread_checker_.CalledOnValidThread()); |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
369 DCHECK(thread_checker_.CalledOnValidThread()); | 448 DCHECK(thread_checker_.CalledOnValidThread()); |
370 throughput_observer_list_.AddObserver(throughput_observer); | 449 throughput_observer_list_.AddObserver(throughput_observer); |
371 } | 450 } |
372 | 451 |
373 void NetworkQualityEstimator::RemoveThroughputObserver( | 452 void NetworkQualityEstimator::RemoveThroughputObserver( |
374 ThroughputObserver* throughput_observer) { | 453 ThroughputObserver* throughput_observer) { |
375 DCHECK(thread_checker_.CalledOnValidThread()); | 454 DCHECK(thread_checker_.CalledOnValidThread()); |
376 throughput_observer_list_.RemoveObserver(throughput_observer); | 455 throughput_observer_list_.RemoveObserver(throughput_observer); |
377 } | 456 } |
378 | 457 |
458 SocketPerformanceWatcherFactory* | |
459 NetworkQualityEstimator::GetSocketPerformanceWatcherFactory() { | |
460 DCHECK(thread_checker_.CalledOnValidThread()); | |
461 | |
462 return watcher_factory_.get(); | |
463 } | |
464 | |
379 void NetworkQualityEstimator::RecordRTTUMA(int32_t estimated_value_msec, | 465 void NetworkQualityEstimator::RecordRTTUMA(int32_t estimated_value_msec, |
380 int32_t actual_value_msec) const { | 466 int32_t actual_value_msec) const { |
381 DCHECK(thread_checker_.CalledOnValidThread()); | 467 DCHECK(thread_checker_.CalledOnValidThread()); |
382 | 468 |
383 // Record the difference between the actual and the estimated value. | 469 // Record the difference between the actual and the estimated value. |
384 if (estimated_value_msec >= actual_value_msec) { | 470 if (estimated_value_msec >= actual_value_msec) { |
385 base::HistogramBase* difference_rtt = | 471 base::HistogramBase* difference_rtt = |
386 GetHistogram("DifferenceRTTEstimatedAndActual.", | 472 GetHistogram("DifferenceRTTEstimatedAndActual.", |
387 current_network_id_.type, 10 * 1000); // 10 seconds | 473 current_network_id_.type, 10 * 1000); // 10 seconds |
388 difference_rtt->Add(estimated_value_msec - actual_value_msec); | 474 difference_rtt->Add(estimated_value_msec - actual_value_msec); |
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
897 } | 983 } |
898 DCHECK_LT(cached_network_qualities_.size(), | 984 DCHECK_LT(cached_network_qualities_.size(), |
899 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 985 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
900 | 986 |
901 cached_network_qualities_.insert(std::make_pair( | 987 cached_network_qualities_.insert(std::make_pair( |
902 current_network_id_, CachedNetworkQuality(network_quality))); | 988 current_network_id_, CachedNetworkQuality(network_quality))); |
903 DCHECK_LE(cached_network_qualities_.size(), | 989 DCHECK_LE(cached_network_qualities_.size(), |
904 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 990 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
905 } | 991 } |
906 | 992 |
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( | 993 void NetworkQualityEstimator::OnUpdatedRTTAvailable( |
917 const Protocol protocol, | 994 SocketPerformanceWatcherFactory::Protocol protocol, |
918 const base::TimeDelta& rtt) { | 995 const base::TimeDelta& rtt) { |
919 DCHECK(thread_checker_.CalledOnValidThread()); | 996 DCHECK(thread_checker_.CalledOnValidThread()); |
920 | 997 |
921 switch (protocol) { | 998 switch (protocol) { |
922 case PROTOCOL_TCP: | 999 case SocketPerformanceWatcherFactory::PROTOCOL_TCP: |
923 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), TCP)); | 1000 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), TCP)); |
924 return; | 1001 return; |
925 case PROTOCOL_QUIC: | 1002 case SocketPerformanceWatcherFactory::PROTOCOL_QUIC: |
926 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), QUIC)); | 1003 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), QUIC)); |
927 return; | 1004 return; |
928 default: | 1005 default: |
929 NOTREACHED(); | 1006 NOTREACHED(); |
930 } | 1007 } |
931 } | 1008 } |
932 | 1009 |
933 void NetworkQualityEstimator::NotifyObserversOfRTT( | 1010 void NetworkQualityEstimator::NotifyObserversOfRTT( |
934 const RttObservation& observation) { | 1011 const RttObservation& observation) { |
935 FOR_EACH_OBSERVER( | 1012 FOR_EACH_OBSERVER( |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
986 | 1063 |
987 NetworkQualityEstimator::NetworkQuality& | 1064 NetworkQualityEstimator::NetworkQuality& |
988 NetworkQualityEstimator::NetworkQuality:: | 1065 NetworkQualityEstimator::NetworkQuality:: |
989 operator=(const NetworkQuality& other) { | 1066 operator=(const NetworkQuality& other) { |
990 rtt_ = other.rtt_; | 1067 rtt_ = other.rtt_; |
991 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; | 1068 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; |
992 return *this; | 1069 return *this; |
993 } | 1070 } |
994 | 1071 |
995 } // namespace net | 1072 } // namespace net |
OLD | NEW |