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 "build/build_config.h" | 18 #include "build/build_config.h" |
19 #include "net/base/load_flags.h" | 19 #include "net/base/load_flags.h" |
20 #include "net/base/load_timing_info.h" | 20 #include "net/base/load_timing_info.h" |
21 #include "net/base/network_interfaces.h" | 21 #include "net/base/network_interfaces.h" |
| 22 #include "net/base/network_quality_estimator_watcher_factory.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" |
28 #endif // OS_ANDROID | 29 #endif // OS_ANDROID |
29 | 30 |
30 namespace { | 31 namespace { |
31 | 32 |
(...skipping 102 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_msec_observations_(GetWeightMultiplierPerSecond(variation_params)), | 144 rtt_msec_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 socket_performance_watcher_factory_.reset( |
| 173 new NetworkQualityEstimatorWatcherFactory( |
| 174 GetWeakPtr(), base::ThreadTaskRunnerHandle::Get())); |
169 } | 175 } |
170 | 176 |
171 // static | 177 // static |
172 const base::TimeDelta NetworkQualityEstimator::InvalidRTT() { | 178 const base::TimeDelta NetworkQualityEstimator::InvalidRTT() { |
173 return base::TimeDelta::Max(); | 179 return base::TimeDelta::Max(); |
174 } | 180 } |
175 | 181 |
176 void NetworkQualityEstimator::ObtainOperatingParams( | 182 void NetworkQualityEstimator::ObtainOperatingParams( |
177 const std::map<std::string, std::string>& variation_params) { | 183 const std::map<std::string, std::string>& variation_params) { |
178 DCHECK(thread_checker_.CalledOnValidThread()); | 184 DCHECK(thread_checker_.CalledOnValidThread()); |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 DCHECK(thread_checker_.CalledOnValidThread()); | 375 DCHECK(thread_checker_.CalledOnValidThread()); |
370 throughput_observer_list_.AddObserver(throughput_observer); | 376 throughput_observer_list_.AddObserver(throughput_observer); |
371 } | 377 } |
372 | 378 |
373 void NetworkQualityEstimator::RemoveThroughputObserver( | 379 void NetworkQualityEstimator::RemoveThroughputObserver( |
374 ThroughputObserver* throughput_observer) { | 380 ThroughputObserver* throughput_observer) { |
375 DCHECK(thread_checker_.CalledOnValidThread()); | 381 DCHECK(thread_checker_.CalledOnValidThread()); |
376 throughput_observer_list_.RemoveObserver(throughput_observer); | 382 throughput_observer_list_.RemoveObserver(throughput_observer); |
377 } | 383 } |
378 | 384 |
| 385 SocketPerformanceWatcherFactory* |
| 386 NetworkQualityEstimator::GetSocketPerformanceWatcherFactory() { |
| 387 DCHECK(thread_checker_.CalledOnValidThread()); |
| 388 |
| 389 return socket_performance_watcher_factory_.get(); |
| 390 } |
| 391 |
379 void NetworkQualityEstimator::RecordRTTUMA(int32_t estimated_value_msec, | 392 void NetworkQualityEstimator::RecordRTTUMA(int32_t estimated_value_msec, |
380 int32_t actual_value_msec) const { | 393 int32_t actual_value_msec) const { |
381 DCHECK(thread_checker_.CalledOnValidThread()); | 394 DCHECK(thread_checker_.CalledOnValidThread()); |
382 | 395 |
383 // Record the difference between the actual and the estimated value. | 396 // Record the difference between the actual and the estimated value. |
384 if (estimated_value_msec >= actual_value_msec) { | 397 if (estimated_value_msec >= actual_value_msec) { |
385 base::HistogramBase* difference_rtt = | 398 base::HistogramBase* difference_rtt = |
386 GetHistogram("DifferenceRTTEstimatedAndActual.", | 399 GetHistogram("DifferenceRTTEstimatedAndActual.", |
387 current_network_id_.type, 10 * 1000); // 10 seconds | 400 current_network_id_.type, 10 * 1000); // 10 seconds |
388 difference_rtt->Add(estimated_value_msec - actual_value_msec); | 401 difference_rtt->Add(estimated_value_msec - actual_value_msec); |
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
879 } | 892 } |
880 DCHECK_LT(cached_network_qualities_.size(), | 893 DCHECK_LT(cached_network_qualities_.size(), |
881 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 894 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
882 | 895 |
883 cached_network_qualities_.insert(std::make_pair( | 896 cached_network_qualities_.insert(std::make_pair( |
884 current_network_id_, CachedNetworkQuality(network_quality))); | 897 current_network_id_, CachedNetworkQuality(network_quality))); |
885 DCHECK_LE(cached_network_qualities_.size(), | 898 DCHECK_LE(cached_network_qualities_.size(), |
886 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 899 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
887 } | 900 } |
888 | 901 |
889 scoped_ptr<SocketPerformanceWatcher> | |
890 NetworkQualityEstimator::CreateSocketPerformanceWatcher( | |
891 const Protocol protocol) { | |
892 DCHECK(thread_checker_.CalledOnValidThread()); | |
893 | |
894 return scoped_ptr<SocketPerformanceWatcher>( | |
895 new SocketPerformanceWatcher(protocol, this)); | |
896 } | |
897 | |
898 void NetworkQualityEstimator::OnUpdatedRTTAvailable( | 902 void NetworkQualityEstimator::OnUpdatedRTTAvailable( |
899 const Protocol protocol, | 903 SocketPerformanceWatcherFactory::Protocol protocol, |
900 const base::TimeDelta& rtt) { | 904 const base::TimeDelta& rtt) { |
901 DCHECK(thread_checker_.CalledOnValidThread()); | 905 DCHECK(thread_checker_.CalledOnValidThread()); |
902 | 906 |
903 switch (protocol) { | 907 switch (protocol) { |
904 case PROTOCOL_TCP: | 908 case SocketPerformanceWatcherFactory::PROTOCOL_TCP: |
905 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), TCP)); | 909 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), TCP)); |
906 return; | 910 return; |
907 case PROTOCOL_QUIC: | 911 case SocketPerformanceWatcherFactory::PROTOCOL_QUIC: |
908 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), QUIC)); | 912 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), QUIC)); |
909 return; | 913 return; |
910 default: | 914 default: |
911 NOTREACHED(); | 915 NOTREACHED(); |
912 } | 916 } |
913 } | 917 } |
914 | 918 |
| 919 void NetworkQualityEstimator::OnWatcherReset() { |
| 920 DCHECK(thread_checker_.CalledOnValidThread()); |
| 921 // Nothing needs to be done for RTT observations since NetworkQualityEstimator |
| 922 // does not maintain any watcher-specific state. |
| 923 } |
| 924 |
915 void NetworkQualityEstimator::NotifyObserversOfRTT( | 925 void NetworkQualityEstimator::NotifyObserversOfRTT( |
916 const RttObservation& observation) { | 926 const RttObservation& observation) { |
917 FOR_EACH_OBSERVER( | 927 FOR_EACH_OBSERVER( |
918 RTTObserver, rtt_observer_list_, | 928 RTTObserver, rtt_observer_list_, |
919 OnRTTObservation(observation.value.InMilliseconds(), | 929 OnRTTObservation(observation.value.InMilliseconds(), |
920 observation.timestamp, observation.source)); | 930 observation.timestamp, observation.source)); |
921 } | 931 } |
922 | 932 |
923 void NetworkQualityEstimator::NotifyObserversOfThroughput( | 933 void NetworkQualityEstimator::NotifyObserversOfThroughput( |
924 const ThroughputObservation& observation) { | 934 const ThroughputObservation& observation) { |
925 FOR_EACH_OBSERVER( | 935 FOR_EACH_OBSERVER( |
926 ThroughputObserver, throughput_observer_list_, | 936 ThroughputObserver, throughput_observer_list_, |
927 OnThroughputObservation(observation.value, observation.timestamp, | 937 OnThroughputObservation(observation.value, observation.timestamp, |
928 observation.source)); | 938 observation.source)); |
929 } | 939 } |
930 | 940 |
| 941 base::WeakPtr<NetworkQualityEstimator> NetworkQualityEstimator::GetWeakPtr() { |
| 942 DCHECK(thread_checker_.CalledOnValidThread()); |
| 943 |
| 944 return weak_ptr_factory_.GetWeakPtr(); |
| 945 } |
| 946 |
931 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( | 947 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( |
932 const NetworkQuality& network_quality) | 948 const NetworkQuality& network_quality) |
933 : last_update_time_(base::TimeTicks::Now()), | 949 : last_update_time_(base::TimeTicks::Now()), |
934 network_quality_(network_quality) { | 950 network_quality_(network_quality) { |
935 } | 951 } |
936 | 952 |
937 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( | 953 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( |
938 const CachedNetworkQuality& other) | 954 const CachedNetworkQuality& other) |
939 : last_update_time_(other.last_update_time_), | 955 : last_update_time_(other.last_update_time_), |
940 network_quality_(other.network_quality_) { | 956 network_quality_(other.network_quality_) { |
(...skipping 27 matching lines...) Expand all Loading... |
968 | 984 |
969 NetworkQualityEstimator::NetworkQuality& | 985 NetworkQualityEstimator::NetworkQuality& |
970 NetworkQualityEstimator::NetworkQuality:: | 986 NetworkQualityEstimator::NetworkQuality:: |
971 operator=(const NetworkQuality& other) { | 987 operator=(const NetworkQuality& other) { |
972 rtt_ = other.rtt_; | 988 rtt_ = other.rtt_; |
973 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; | 989 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; |
974 return *this; | 990 return *this; |
975 } | 991 } |
976 | 992 |
977 } // namespace net | 993 } // namespace net |
OLD | NEW |