| 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_estimates_provider_(external_estimates_provider.Pass()) { | 181 external_estimate_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_estimates_provider_) | 195 if (external_estimate_provider_) { |
| 196 external_estimates_provider_->SetUpdatedEstimateDelegate(this); | 196 RecordExternalEstimateProviderMetrics( |
| 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 } |
| 197 current_network_id_ = GetCurrentNetworkID(); | 204 current_network_id_ = GetCurrentNetworkID(); |
| 198 AddDefaultEstimates(); | 205 AddDefaultEstimates(); |
| 199 } | 206 } |
| 200 | 207 |
| 201 // static | 208 // static |
| 202 const base::TimeDelta NetworkQualityEstimator::InvalidRTT() { | 209 const base::TimeDelta NetworkQualityEstimator::InvalidRTT() { |
| 203 return base::TimeDelta::Max(); | 210 return base::TimeDelta::Max(); |
| 204 } | 211 } |
| 205 | 212 |
| 206 void NetworkQualityEstimator::ObtainOperatingParams( | 213 void NetworkQualityEstimator::ObtainOperatingParams( |
| 207 const std::map<std::string, std::string>& variation_params) { | 214 const std::map<std::string, std::string>& variation_params) { |
| 208 DCHECK(thread_checker_.CalledOnValidThread()); | 215 DCHECK(thread_checker_.CalledOnValidThread()); |
| 209 | 216 |
| 210 for (size_t i = 0; i <= NetworkChangeNotifier::CONNECTION_LAST; ++i) { | 217 for (size_t i = 0; i <= NetworkChangeNotifier::CONNECTION_LAST; ++i) { |
| 211 NetworkChangeNotifier::ConnectionType type = | 218 NetworkChangeNotifier::ConnectionType type = |
| 212 static_cast<NetworkChangeNotifier::ConnectionType>(i); | 219 static_cast<NetworkChangeNotifier::ConnectionType>(i); |
| 220 DCHECK_EQ(InvalidRTT(), default_observations_[i].rtt()); |
| 221 DCHECK_EQ(kInvalidThroughput, |
| 222 default_observations_[i].downstream_throughput_kbps()); |
| 213 int32_t variations_value = kMinimumRTTVariationParameterMsec - 1; | 223 int32_t variations_value = kMinimumRTTVariationParameterMsec - 1; |
| 214 // Name of the parameter that holds the RTT value for this connection type. | 224 // Name of the parameter that holds the RTT value for this connection type. |
| 215 std::string rtt_parameter_name = | 225 std::string rtt_parameter_name = |
| 216 std::string(GetNameForConnectionType(type)) | 226 std::string(GetNameForConnectionType(type)) |
| 217 .append(kDefaultRTTMsecObservationSuffix); | 227 .append(kDefaultRTTMsecObservationSuffix); |
| 218 auto it = variation_params.find(rtt_parameter_name); | 228 auto it = variation_params.find(rtt_parameter_name); |
| 219 if (it != variation_params.end() && | 229 if (it != variation_params.end() && |
| 220 base::StringToInt(it->second, &variations_value) && | 230 base::StringToInt(it->second, &variations_value) && |
| 221 variations_value >= kMinimumRTTVariationParameterMsec) { | 231 variations_value >= kMinimumRTTVariationParameterMsec) { |
| 222 default_observations_[i] = | 232 default_observations_[i] = |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 return request.url().is_valid() && | 422 return request.url().is_valid() && |
| 413 (allow_localhost_requests_ || !IsLocalhost(request.url().host())) && | 423 (allow_localhost_requests_ || !IsLocalhost(request.url().host())) && |
| 414 request.url().SchemeIsHTTPOrHTTPS() && | 424 request.url().SchemeIsHTTPOrHTTPS() && |
| 415 // Verify that response headers are received, so it can be ensured that | 425 // Verify that response headers are received, so it can be ensured that |
| 416 // response is not cached. | 426 // response is not cached. |
| 417 !request.response_info().response_time.is_null() && | 427 !request.response_info().response_time.is_null() && |
| 418 !request.was_cached() && | 428 !request.was_cached() && |
| 419 request.creation_time() >= last_connection_change_; | 429 request.creation_time() >= last_connection_change_; |
| 420 } | 430 } |
| 421 | 431 |
| 432 void NetworkQualityEstimator::RecordExternalEstimateProviderMetrics( |
| 433 NQEExternalEstimateProviderStatus status) const { |
| 434 UMA_HISTOGRAM_ENUMERATION("NQE.ExternalEstimateProviderStatus", status, |
| 435 EXTERNAL_ESTIMATE_PROVIDER_STATUS_BOUNDARY); |
| 436 } |
| 437 |
| 422 void NetworkQualityEstimator::OnConnectionTypeChanged( | 438 void NetworkQualityEstimator::OnConnectionTypeChanged( |
| 423 NetworkChangeNotifier::ConnectionType type) { | 439 NetworkChangeNotifier::ConnectionType type) { |
| 424 DCHECK(thread_checker_.CalledOnValidThread()); | 440 DCHECK(thread_checker_.CalledOnValidThread()); |
| 425 if (peak_network_quality_.rtt() != InvalidRTT()) { | 441 if (peak_network_quality_.rtt() != InvalidRTT()) { |
| 426 switch (current_network_id_.type) { | 442 switch (current_network_id_.type) { |
| 427 case NetworkChangeNotifier::CONNECTION_UNKNOWN: | 443 case NetworkChangeNotifier::CONNECTION_UNKNOWN: |
| 428 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Unknown", | 444 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Unknown", |
| 429 peak_network_quality_.rtt()); | 445 peak_network_quality_.rtt()); |
| 430 break; | 446 break; |
| 431 case NetworkChangeNotifier::CONNECTION_ETHERNET: | 447 case NetworkChangeNotifier::CONNECTION_ETHERNET: |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 // Write the estimates of the previous network to the cache. | 547 // Write the estimates of the previous network to the cache. |
| 532 CacheNetworkQualityEstimate(); | 548 CacheNetworkQualityEstimate(); |
| 533 | 549 |
| 534 // Clear the local state. | 550 // Clear the local state. |
| 535 last_connection_change_ = base::TimeTicks::Now(); | 551 last_connection_change_ = base::TimeTicks::Now(); |
| 536 peak_network_quality_ = NetworkQuality(); | 552 peak_network_quality_ = NetworkQuality(); |
| 537 downstream_throughput_kbps_observations_.Clear(); | 553 downstream_throughput_kbps_observations_.Clear(); |
| 538 rtt_msec_observations_.Clear(); | 554 rtt_msec_observations_.Clear(); |
| 539 current_network_id_ = GetCurrentNetworkID(); | 555 current_network_id_ = GetCurrentNetworkID(); |
| 540 | 556 |
| 557 QueryExternalEstimateProvider(); |
| 558 |
| 541 // Read any cached estimates for the new network. If cached estimates are | 559 // Read any cached estimates for the new network. If cached estimates are |
| 542 // unavailable, add the default estimates. | 560 // unavailable, add the default estimates. |
| 543 if (!ReadCachedNetworkQualityEstimate()) | 561 if (!ReadCachedNetworkQualityEstimate()) |
| 544 AddDefaultEstimates(); | 562 AddDefaultEstimates(); |
| 545 estimated_median_network_quality_ = NetworkQuality(); | 563 estimated_median_network_quality_ = NetworkQuality(); |
| 546 } | 564 } |
| 547 | 565 |
| 548 bool NetworkQualityEstimator::GetRTTEstimate(base::TimeDelta* rtt) const { | 566 bool NetworkQualityEstimator::GetRTTEstimate(base::TimeDelta* rtt) const { |
| 549 DCHECK(thread_checker_.CalledOnValidThread()); | 567 DCHECK(thread_checker_.CalledOnValidThread()); |
| 550 DCHECK(rtt); | 568 DCHECK(rtt); |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 805 | 823 |
| 806 downstream_throughput_kbps_observations_.AddObservation(Observation( | 824 downstream_throughput_kbps_observations_.AddObservation(Observation( |
| 807 network_quality.downstream_throughput_kbps(), base::TimeTicks::Now())); | 825 network_quality.downstream_throughput_kbps(), base::TimeTicks::Now())); |
| 808 rtt_msec_observations_.AddObservation(Observation( | 826 rtt_msec_observations_.AddObservation(Observation( |
| 809 network_quality.rtt().InMilliseconds(), base::TimeTicks::Now())); | 827 network_quality.rtt().InMilliseconds(), base::TimeTicks::Now())); |
| 810 return true; | 828 return true; |
| 811 } | 829 } |
| 812 | 830 |
| 813 void NetworkQualityEstimator::OnUpdatedEstimateAvailable() { | 831 void NetworkQualityEstimator::OnUpdatedEstimateAvailable() { |
| 814 DCHECK(thread_checker_.CalledOnValidThread()); | 832 DCHECK(thread_checker_.CalledOnValidThread()); |
| 815 DCHECK(external_estimates_provider_); | 833 DCHECK(external_estimate_provider_); |
| 816 // TODO(tbansal): Query provider for the recent value. | 834 |
| 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 } |
| 817 } | 878 } |
| 818 | 879 |
| 819 void NetworkQualityEstimator::CacheNetworkQualityEstimate() { | 880 void NetworkQualityEstimator::CacheNetworkQualityEstimate() { |
| 820 DCHECK(thread_checker_.CalledOnValidThread()); | 881 DCHECK(thread_checker_.CalledOnValidThread()); |
| 821 DCHECK_LE(cached_network_qualities_.size(), | 882 DCHECK_LE(cached_network_qualities_.size(), |
| 822 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 883 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
| 823 | 884 |
| 824 // If the network name is unavailable, caching should not be performed. | 885 // If the network name is unavailable, caching should not be performed. |
| 825 if (current_network_id_.id.empty()) | 886 if (current_network_id_.id.empty()) |
| 826 return; | 887 return; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 909 | 970 |
| 910 NetworkQualityEstimator::NetworkQuality& | 971 NetworkQualityEstimator::NetworkQuality& |
| 911 NetworkQualityEstimator::NetworkQuality:: | 972 NetworkQualityEstimator::NetworkQuality:: |
| 912 operator=(const NetworkQuality& other) { | 973 operator=(const NetworkQuality& other) { |
| 913 rtt_ = other.rtt_; | 974 rtt_ = other.rtt_; |
| 914 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; | 975 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; |
| 915 return *this; | 976 return *this; |
| 916 } | 977 } |
| 917 | 978 |
| 918 } // namespace net | 979 } // namespace net |
| OLD | NEW |