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> |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 bool allow_smaller_responses_for_tests) | 171 bool allow_smaller_responses_for_tests) |
172 : allow_localhost_requests_(allow_local_host_requests_for_tests), | 172 : allow_localhost_requests_(allow_local_host_requests_for_tests), |
173 allow_small_responses_(allow_smaller_responses_for_tests), | 173 allow_small_responses_(allow_smaller_responses_for_tests), |
174 last_connection_change_(base::TimeTicks::Now()), | 174 last_connection_change_(base::TimeTicks::Now()), |
175 current_network_id_( | 175 current_network_id_( |
176 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, | 176 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, |
177 std::string())), | 177 std::string())), |
178 downstream_throughput_kbps_observations_( | 178 downstream_throughput_kbps_observations_( |
179 GetWeightMultiplierPerSecond(variation_params)), | 179 GetWeightMultiplierPerSecond(variation_params)), |
180 rtt_msec_observations_(GetWeightMultiplierPerSecond(variation_params)), | 180 rtt_msec_observations_(GetWeightMultiplierPerSecond(variation_params)), |
181 external_estimate_provider_(external_estimates_provider.Pass()) { | 181 external_estimates_provider_(external_estimates_provider.Pass()) { |
182 static_assert(kMinRequestDurationMicroseconds > 0, | 182 static_assert(kMinRequestDurationMicroseconds > 0, |
183 "Minimum request duration must be > 0"); | 183 "Minimum request duration must be > 0"); |
184 static_assert(kDefaultHalfLifeSeconds > 0, | 184 static_assert(kDefaultHalfLifeSeconds > 0, |
185 "Default half life duration must be > 0"); | 185 "Default half life duration must be > 0"); |
186 static_assert(kMaximumNetworkQualityCacheSize > 0, | 186 static_assert(kMaximumNetworkQualityCacheSize > 0, |
187 "Size of the network quality cache must be > 0"); | 187 "Size of the network quality cache must be > 0"); |
188 // This limit should not be increased unless the logic for removing the | 188 // This limit should not be increased unless the logic for removing the |
189 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. | 189 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. |
190 static_assert(kMaximumNetworkQualityCacheSize <= 10, | 190 static_assert(kMaximumNetworkQualityCacheSize <= 10, |
191 "Size of the network quality cache must <= 10"); | 191 "Size of the network quality cache must <= 10"); |
192 | 192 |
193 ObtainOperatingParams(variation_params); | 193 ObtainOperatingParams(variation_params); |
194 NetworkChangeNotifier::AddConnectionTypeObserver(this); | 194 NetworkChangeNotifier::AddConnectionTypeObserver(this); |
195 if (external_estimate_provider_) { | 195 if (external_estimates_provider_) |
196 RecordExternalEstimateProviderMetrics( | 196 external_estimates_provider_->SetUpdatedEstimateDelegate(this); |
197 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE); | |
198 external_estimate_provider_->SetUpdatedEstimateDelegate(this); | |
199 QueryExternalEstimateProvider(); | |
200 } else { | |
201 RecordExternalEstimateProviderMetrics( | |
202 EXTERNAL_ESTIMATE_PROVIDER_STATUS_NOT_AVAILABLE); | |
203 } | |
204 current_network_id_ = GetCurrentNetworkID(); | 197 current_network_id_ = GetCurrentNetworkID(); |
205 AddDefaultEstimates(); | 198 AddDefaultEstimates(); |
206 } | 199 } |
207 | 200 |
208 // static | 201 // static |
209 const base::TimeDelta NetworkQualityEstimator::InvalidRTT() { | 202 const base::TimeDelta NetworkQualityEstimator::InvalidRTT() { |
210 return base::TimeDelta::Max(); | 203 return base::TimeDelta::Max(); |
211 } | 204 } |
212 | 205 |
213 void NetworkQualityEstimator::ObtainOperatingParams( | 206 void NetworkQualityEstimator::ObtainOperatingParams( |
214 const std::map<std::string, std::string>& variation_params) { | 207 const std::map<std::string, std::string>& variation_params) { |
215 DCHECK(thread_checker_.CalledOnValidThread()); | 208 DCHECK(thread_checker_.CalledOnValidThread()); |
216 | 209 |
217 for (size_t i = 0; i <= NetworkChangeNotifier::CONNECTION_LAST; ++i) { | 210 for (size_t i = 0; i <= NetworkChangeNotifier::CONNECTION_LAST; ++i) { |
218 NetworkChangeNotifier::ConnectionType type = | 211 NetworkChangeNotifier::ConnectionType type = |
219 static_cast<NetworkChangeNotifier::ConnectionType>(i); | 212 static_cast<NetworkChangeNotifier::ConnectionType>(i); |
220 DCHECK_EQ(InvalidRTT(), default_observations_[i].rtt()); | |
221 DCHECK_EQ(kInvalidThroughput, | |
222 default_observations_[i].downstream_throughput_kbps()); | |
223 int32_t variations_value = kMinimumRTTVariationParameterMsec - 1; | 213 int32_t variations_value = kMinimumRTTVariationParameterMsec - 1; |
224 // Name of the parameter that holds the RTT value for this connection type. | 214 // Name of the parameter that holds the RTT value for this connection type. |
225 std::string rtt_parameter_name = | 215 std::string rtt_parameter_name = |
226 std::string(GetNameForConnectionType(type)) | 216 std::string(GetNameForConnectionType(type)) |
227 .append(kDefaultRTTMsecObservationSuffix); | 217 .append(kDefaultRTTMsecObservationSuffix); |
228 auto it = variation_params.find(rtt_parameter_name); | 218 auto it = variation_params.find(rtt_parameter_name); |
229 if (it != variation_params.end() && | 219 if (it != variation_params.end() && |
230 base::StringToInt(it->second, &variations_value) && | 220 base::StringToInt(it->second, &variations_value) && |
231 variations_value >= kMinimumRTTVariationParameterMsec) { | 221 variations_value >= kMinimumRTTVariationParameterMsec) { |
232 default_observations_[i] = | 222 default_observations_[i] = |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 return request.url().is_valid() && | 412 return request.url().is_valid() && |
423 (allow_localhost_requests_ || !IsLocalhost(request.url().host())) && | 413 (allow_localhost_requests_ || !IsLocalhost(request.url().host())) && |
424 request.url().SchemeIsHTTPOrHTTPS() && | 414 request.url().SchemeIsHTTPOrHTTPS() && |
425 // Verify that response headers are received, so it can be ensured that | 415 // Verify that response headers are received, so it can be ensured that |
426 // response is not cached. | 416 // response is not cached. |
427 !request.response_info().response_time.is_null() && | 417 !request.response_info().response_time.is_null() && |
428 !request.was_cached() && | 418 !request.was_cached() && |
429 request.creation_time() >= last_connection_change_; | 419 request.creation_time() >= last_connection_change_; |
430 } | 420 } |
431 | 421 |
432 void NetworkQualityEstimator::RecordExternalEstimateProviderMetrics( | |
433 NQEExternalEstimateProviderStatus status) const { | |
434 UMA_HISTOGRAM_ENUMERATION("NQE.ExternalEstimateProviderStatus", status, | |
435 EXTERNAL_ESTIMATE_PROVIDER_STATUS_BOUNDARY); | |
436 } | |
437 | |
438 void NetworkQualityEstimator::OnConnectionTypeChanged( | 422 void NetworkQualityEstimator::OnConnectionTypeChanged( |
439 NetworkChangeNotifier::ConnectionType type) { | 423 NetworkChangeNotifier::ConnectionType type) { |
440 DCHECK(thread_checker_.CalledOnValidThread()); | 424 DCHECK(thread_checker_.CalledOnValidThread()); |
441 if (peak_network_quality_.rtt() != InvalidRTT()) { | 425 if (peak_network_quality_.rtt() != InvalidRTT()) { |
442 switch (current_network_id_.type) { | 426 switch (current_network_id_.type) { |
443 case NetworkChangeNotifier::CONNECTION_UNKNOWN: | 427 case NetworkChangeNotifier::CONNECTION_UNKNOWN: |
444 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Unknown", | 428 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Unknown", |
445 peak_network_quality_.rtt()); | 429 peak_network_quality_.rtt()); |
446 break; | 430 break; |
447 case NetworkChangeNotifier::CONNECTION_ETHERNET: | 431 case NetworkChangeNotifier::CONNECTION_ETHERNET: |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 // Write the estimates of the previous network to the cache. | 531 // Write the estimates of the previous network to the cache. |
548 CacheNetworkQualityEstimate(); | 532 CacheNetworkQualityEstimate(); |
549 | 533 |
550 // Clear the local state. | 534 // Clear the local state. |
551 last_connection_change_ = base::TimeTicks::Now(); | 535 last_connection_change_ = base::TimeTicks::Now(); |
552 peak_network_quality_ = NetworkQuality(); | 536 peak_network_quality_ = NetworkQuality(); |
553 downstream_throughput_kbps_observations_.Clear(); | 537 downstream_throughput_kbps_observations_.Clear(); |
554 rtt_msec_observations_.Clear(); | 538 rtt_msec_observations_.Clear(); |
555 current_network_id_ = GetCurrentNetworkID(); | 539 current_network_id_ = GetCurrentNetworkID(); |
556 | 540 |
557 QueryExternalEstimateProvider(); | |
558 | |
559 // Read any cached estimates for the new network. If cached estimates are | 541 // Read any cached estimates for the new network. If cached estimates are |
560 // unavailable, add the default estimates. | 542 // unavailable, add the default estimates. |
561 if (!ReadCachedNetworkQualityEstimate()) | 543 if (!ReadCachedNetworkQualityEstimate()) |
562 AddDefaultEstimates(); | 544 AddDefaultEstimates(); |
563 estimated_median_network_quality_ = NetworkQuality(); | 545 estimated_median_network_quality_ = NetworkQuality(); |
564 } | 546 } |
565 | 547 |
566 bool NetworkQualityEstimator::GetRTTEstimate(base::TimeDelta* rtt) const { | 548 bool NetworkQualityEstimator::GetRTTEstimate(base::TimeDelta* rtt) const { |
567 DCHECK(thread_checker_.CalledOnValidThread()); | 549 DCHECK(thread_checker_.CalledOnValidThread()); |
568 DCHECK(rtt); | 550 DCHECK(rtt); |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 | 805 |
824 downstream_throughput_kbps_observations_.AddObservation(Observation( | 806 downstream_throughput_kbps_observations_.AddObservation(Observation( |
825 network_quality.downstream_throughput_kbps(), base::TimeTicks::Now())); | 807 network_quality.downstream_throughput_kbps(), base::TimeTicks::Now())); |
826 rtt_msec_observations_.AddObservation(Observation( | 808 rtt_msec_observations_.AddObservation(Observation( |
827 network_quality.rtt().InMilliseconds(), base::TimeTicks::Now())); | 809 network_quality.rtt().InMilliseconds(), base::TimeTicks::Now())); |
828 return true; | 810 return true; |
829 } | 811 } |
830 | 812 |
831 void NetworkQualityEstimator::OnUpdatedEstimateAvailable() { | 813 void NetworkQualityEstimator::OnUpdatedEstimateAvailable() { |
832 DCHECK(thread_checker_.CalledOnValidThread()); | 814 DCHECK(thread_checker_.CalledOnValidThread()); |
833 DCHECK(external_estimate_provider_); | 815 DCHECK(external_estimates_provider_); |
834 | 816 // TODO(tbansal): Query provider for the recent value. |
835 RecordExternalEstimateProviderMetrics( | |
836 EXTERNAL_ESTIMATE_PROVIDER_STATUS_CALLBACK); | |
837 QueryExternalEstimateProvider(); | |
838 } | |
839 | |
840 void NetworkQualityEstimator::QueryExternalEstimateProvider() { | |
841 DCHECK(thread_checker_.CalledOnValidThread()); | |
842 | |
843 if (!external_estimate_provider_) | |
844 return; | |
845 RecordExternalEstimateProviderMetrics( | |
846 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERIED); | |
847 | |
848 base::TimeDelta time_since_last_update; | |
849 | |
850 // Request a new estimate if estimate is not available, or if the available | |
851 // estimate is not fresh. | |
852 if (!external_estimate_provider_->GetTimeSinceLastUpdate( | |
853 &time_since_last_update) || | |
854 time_since_last_update > | |
855 base::TimeDelta::FromMilliseconds( | |
856 kExternalEstimateProviderFreshnessDurationMsec)) { | |
857 // Request the external estimate provider for updated estimates. When the | |
858 // updates estimates are available, OnUpdatedEstimateAvailable() will be | |
859 // called. | |
860 external_estimate_provider_->Update(); | |
861 return; | |
862 } | |
863 | |
864 RecordExternalEstimateProviderMetrics( | |
865 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERY_SUCCESSFUL); | |
866 base::TimeDelta rtt; | |
867 if (external_estimate_provider_->GetRTT(&rtt)) { | |
868 rtt_msec_observations_.AddObservation( | |
869 Observation(rtt.InMilliseconds(), base::TimeTicks::Now())); | |
870 } | |
871 | |
872 int32_t downstream_throughput_kbps; | |
873 if (external_estimate_provider_->GetDownstreamThroughputKbps( | |
874 &downstream_throughput_kbps)) { | |
875 downstream_throughput_kbps_observations_.AddObservation( | |
876 Observation(downstream_throughput_kbps, base::TimeTicks::Now())); | |
877 } | |
878 } | 817 } |
879 | 818 |
880 void NetworkQualityEstimator::CacheNetworkQualityEstimate() { | 819 void NetworkQualityEstimator::CacheNetworkQualityEstimate() { |
881 DCHECK(thread_checker_.CalledOnValidThread()); | 820 DCHECK(thread_checker_.CalledOnValidThread()); |
882 DCHECK_LE(cached_network_qualities_.size(), | 821 DCHECK_LE(cached_network_qualities_.size(), |
883 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 822 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
884 | 823 |
885 // If the network name is unavailable, caching should not be performed. | 824 // If the network name is unavailable, caching should not be performed. |
886 if (current_network_id_.id.empty()) | 825 if (current_network_id_.id.empty()) |
887 return; | 826 return; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
970 | 909 |
971 NetworkQualityEstimator::NetworkQuality& | 910 NetworkQualityEstimator::NetworkQuality& |
972 NetworkQualityEstimator::NetworkQuality:: | 911 NetworkQualityEstimator::NetworkQuality:: |
973 operator=(const NetworkQuality& other) { | 912 operator=(const NetworkQuality& other) { |
974 rtt_ = other.rtt_; | 913 rtt_ = other.rtt_; |
975 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; | 914 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; |
976 return *this; | 915 return *this; |
977 } | 916 } |
978 | 917 |
979 } // namespace net | 918 } // namespace net |
OLD | NEW |