Chromium Code Reviews| 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/nqe/network_quality_estimator.h" | 5 #include "net/nqe/network_quality_estimator.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 28 #include "net/socket/socket_performance_watcher.h" | 28 #include "net/socket/socket_performance_watcher.h" |
| 29 #include "net/url_request/url_request.h" | 29 #include "net/url_request/url_request.h" |
| 30 #include "url/gurl.h" | 30 #include "url/gurl.h" |
| 31 | 31 |
| 32 #if defined(OS_ANDROID) | 32 #if defined(OS_ANDROID) |
| 33 #include "net/android/network_library.h" | 33 #include "net/android/network_library.h" |
| 34 #endif // OS_ANDROID | 34 #endif // OS_ANDROID |
| 35 | 35 |
| 36 namespace { | 36 namespace { |
| 37 | 37 |
| 38 // The algorithm that uses HTTP RTT and downstream throughput to determine the | |
|
bengr
2016/06/06 20:14:54
Hmm. This will be hard to extend. I think instead
tbansal1
2016/06/08 01:30:53
I wanted to keep |algorithm_| as a const variable.
| |
| 39 // effective connection type. | |
| 40 const char kHttpRTTDownstreamThroughputAlgorithm[] = | |
| 41 "HttpRTTAndDownstreamThroughput"; | |
| 42 | |
| 43 // The default algorithm to be used if the algorithm value is not available | |
| 44 // through field trial parameters. | |
| 45 const char kDefaultEffectiveConnectionTypeAlgorithm[] = | |
| 46 "HttpRTTAndDownstreamThroughput"; | |
| 47 | |
| 38 // Default value of the half life (in seconds) for computing time weighted | 48 // Default value of the half life (in seconds) for computing time weighted |
| 39 // percentiles. Every half life, the weight of all observations reduces by | 49 // percentiles. Every half life, the weight of all observations reduces by |
| 40 // half. Lowering the half life would reduce the weight of older values faster. | 50 // half. Lowering the half life would reduce the weight of older values faster. |
| 41 const int kDefaultHalfLifeSeconds = 60; | 51 const int kDefaultHalfLifeSeconds = 60; |
| 42 | 52 |
| 43 // Name of the variation parameter that holds the value of the half life (in | 53 // Name of the variation parameter that holds the value of the half life (in |
| 44 // seconds) of the observations. | 54 // seconds) of the observations. |
| 45 const char kHalfLifeSecondsParamName[] = "HalfLifeSeconds"; | 55 const char kHalfLifeSecondsParamName[] = "HalfLifeSeconds"; |
| 46 | 56 |
| 47 // Returns a descriptive name corresponding to |connection_type|. | 57 // Returns a descriptive name corresponding to |connection_type|. |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 128 const char prefix[] = "NQE."; | 138 const char prefix[] = "NQE."; |
| 129 return base::Histogram::FactoryGet( | 139 return base::Histogram::FactoryGet( |
| 130 prefix + statistic_name + GetNameForConnectionType(type), kLowerLimit, | 140 prefix + statistic_name + GetNameForConnectionType(type), kLowerLimit, |
| 131 max_limit, kBucketCount, base::HistogramBase::kUmaTargetedHistogramFlag); | 141 max_limit, kBucketCount, base::HistogramBase::kUmaTargetedHistogramFlag); |
| 132 } | 142 } |
| 133 | 143 |
| 134 bool GetValueForVariationParam( | 144 bool GetValueForVariationParam( |
| 135 const std::map<std::string, std::string>& variation_params, | 145 const std::map<std::string, std::string>& variation_params, |
| 136 const std::string& parameter_name, | 146 const std::string& parameter_name, |
| 137 int32_t* variations_value) { | 147 int32_t* variations_value) { |
| 138 auto it = variation_params.find(parameter_name); | 148 const auto it = variation_params.find(parameter_name); |
| 139 return it != variation_params.end() && | 149 return it != variation_params.end() && |
| 140 base::StringToInt(it->second, variations_value); | 150 base::StringToInt(it->second, variations_value); |
| 141 } | 151 } |
| 142 | 152 |
| 153 // Returns the value of the |parameter_name| in |variation_params|. If | |
| 154 // |parameter_name| is not set in |variation_params|, then |default_value| is | |
| 155 // returned. | |
| 156 std::string GetValueForVariationParamWithDefaultValue( | |
| 157 const std::map<std::string, std::string>& variation_params, | |
| 158 const std::string& parameter_name, | |
| 159 const std::string& default_value) { | |
| 160 const auto it = variation_params.find(parameter_name); | |
| 161 return it != variation_params.end() && !it->second.empty() ? it->second | |
| 162 : default_value; | |
| 163 } | |
| 164 | |
| 143 net::NetworkQualityObservationSource ProtocolSourceToObservationSource( | 165 net::NetworkQualityObservationSource ProtocolSourceToObservationSource( |
| 144 net::SocketPerformanceWatcherFactory::Protocol protocol) { | 166 net::SocketPerformanceWatcherFactory::Protocol protocol) { |
| 145 switch (protocol) { | 167 switch (protocol) { |
| 146 case net::SocketPerformanceWatcherFactory::PROTOCOL_TCP: | 168 case net::SocketPerformanceWatcherFactory::PROTOCOL_TCP: |
| 147 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_TCP; | 169 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_TCP; |
| 148 case net::SocketPerformanceWatcherFactory::PROTOCOL_QUIC: | 170 case net::SocketPerformanceWatcherFactory::PROTOCOL_QUIC: |
| 149 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC; | 171 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC; |
| 150 } | 172 } |
| 151 NOTREACHED(); | 173 NOTREACHED(); |
| 152 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_TCP; | 174 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_TCP; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 246 | 268 |
| 247 NetworkQualityEstimator::NetworkQualityEstimator( | 269 NetworkQualityEstimator::NetworkQualityEstimator( |
| 248 std::unique_ptr<ExternalEstimateProvider> external_estimates_provider, | 270 std::unique_ptr<ExternalEstimateProvider> external_estimates_provider, |
| 249 const std::map<std::string, std::string>& variation_params, | 271 const std::map<std::string, std::string>& variation_params, |
| 250 bool use_local_host_requests_for_tests, | 272 bool use_local_host_requests_for_tests, |
| 251 bool use_smaller_responses_for_tests) | 273 bool use_smaller_responses_for_tests) |
| 252 : use_localhost_requests_(use_local_host_requests_for_tests), | 274 : use_localhost_requests_(use_local_host_requests_for_tests), |
| 253 use_small_responses_(use_smaller_responses_for_tests), | 275 use_small_responses_(use_smaller_responses_for_tests), |
| 254 weight_multiplier_per_second_( | 276 weight_multiplier_per_second_( |
| 255 GetWeightMultiplierPerSecond(variation_params)), | 277 GetWeightMultiplierPerSecond(variation_params)), |
| 278 algorithm_(GetValueForVariationParamWithDefaultValue( | |
| 279 variation_params, | |
| 280 "algorithm", | |
| 281 kDefaultEffectiveConnectionTypeAlgorithm)), | |
| 256 tick_clock_(new base::DefaultTickClock()), | 282 tick_clock_(new base::DefaultTickClock()), |
| 257 effective_connection_type_recomputation_interval_( | 283 effective_connection_type_recomputation_interval_( |
| 258 base::TimeDelta::FromSeconds(15)), | 284 base::TimeDelta::FromSeconds(15)), |
| 259 last_connection_change_(tick_clock_->NowTicks()), | 285 last_connection_change_(tick_clock_->NowTicks()), |
| 260 current_network_id_( | 286 current_network_id_( |
| 261 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, | 287 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, |
| 262 std::string())), | 288 std::string())), |
| 263 downstream_throughput_kbps_observations_(weight_multiplier_per_second_), | 289 downstream_throughput_kbps_observations_(weight_multiplier_per_second_), |
| 264 rtt_observations_(weight_multiplier_per_second_), | 290 rtt_observations_(weight_multiplier_per_second_), |
| 265 external_estimate_provider_(std::move(external_estimates_provider)), | 291 external_estimate_provider_(std::move(external_estimates_provider)), |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 748 NetworkQualityEstimator::GetEffectiveConnectionType() const { | 774 NetworkQualityEstimator::GetEffectiveConnectionType() const { |
| 749 DCHECK(thread_checker_.CalledOnValidThread()); | 775 DCHECK(thread_checker_.CalledOnValidThread()); |
| 750 return GetRecentEffectiveConnectionType(base::TimeTicks()); | 776 return GetRecentEffectiveConnectionType(base::TimeTicks()); |
| 751 } | 777 } |
| 752 | 778 |
| 753 NetworkQualityEstimator::EffectiveConnectionType | 779 NetworkQualityEstimator::EffectiveConnectionType |
| 754 NetworkQualityEstimator::GetRecentEffectiveConnectionType( | 780 NetworkQualityEstimator::GetRecentEffectiveConnectionType( |
| 755 const base::TimeTicks& start_time) const { | 781 const base::TimeTicks& start_time) const { |
| 756 DCHECK(thread_checker_.CalledOnValidThread()); | 782 DCHECK(thread_checker_.CalledOnValidThread()); |
| 757 | 783 |
| 784 if (algorithm_ == kHttpRTTDownstreamThroughputAlgorithm) { | |
| 785 return GetRecentEffectiveConnectionTypeHttpRTTAndDownstreamThroughput( | |
| 786 start_time); | |
| 787 } | |
| 788 // Add additional algorithms here. | |
| 789 NOTREACHED(); | |
| 790 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; | |
| 791 } | |
| 792 | |
| 793 NetworkQualityEstimator::EffectiveConnectionType NetworkQualityEstimator:: | |
| 794 GetRecentEffectiveConnectionTypeHttpRTTAndDownstreamThroughput( | |
| 795 const base::TimeTicks& start_time) const { | |
| 796 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 797 | |
| 758 // If the device is currently offline, then return | 798 // If the device is currently offline, then return |
| 759 // EFFECTIVE_CONNECTION_TYPE_OFFLINE. | 799 // EFFECTIVE_CONNECTION_TYPE_OFFLINE. |
| 760 if (GetCurrentNetworkID().type == NetworkChangeNotifier::CONNECTION_NONE) | 800 if (GetCurrentNetworkID().type == NetworkChangeNotifier::CONNECTION_NONE) |
| 761 return EFFECTIVE_CONNECTION_TYPE_OFFLINE; | 801 return EFFECTIVE_CONNECTION_TYPE_OFFLINE; |
| 762 | 802 |
| 763 base::TimeDelta http_rtt = nqe::internal::InvalidRTT(); | 803 base::TimeDelta http_rtt = nqe::internal::InvalidRTT(); |
| 764 if (!GetRecentHttpRTTMedian(start_time, &http_rtt)) | 804 if (!GetRecentHttpRTTMedian(start_time, &http_rtt)) |
| 765 http_rtt = nqe::internal::InvalidRTT(); | 805 http_rtt = nqe::internal::InvalidRTT(); |
| 766 | 806 |
| 767 int32_t kbps = nqe::internal::kInvalidThroughput; | 807 int32_t kbps = nqe::internal::kInvalidThroughput; |
| 768 if (!GetRecentMedianDownlinkThroughputKbps(start_time, &kbps)) | 808 if (!GetRecentMedianDownlinkThroughputKbps(start_time, &kbps)) |
| 769 kbps = nqe::internal::kInvalidThroughput; | 809 kbps = nqe::internal::kInvalidThroughput; |
| 770 | 810 |
| 771 if (http_rtt == nqe::internal::InvalidRTT() && | 811 if (http_rtt == nqe::internal::InvalidRTT() || |
| 772 kbps == nqe::internal::kInvalidThroughput) { | 812 kbps == nqe::internal::kInvalidThroughput) { |
| 773 // Quality of the current network is unknown. | 813 // Quality of the current network is unknown. |
| 774 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; | 814 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; |
| 775 } | 815 } |
| 776 | 816 |
| 777 // Search from the slowest connection type to the fastest to find the | 817 // Search from the slowest connection type to the fastest to find the |
| 778 // EffectiveConnectionType that best matches the current connection's | 818 // EffectiveConnectionType that best matches the current connection's |
| 779 // performance. The match is done by comparing RTT and throughput. | 819 // performance. The match is done by comparing RTT and throughput. |
| 780 for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) { | 820 for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) { |
| 781 EffectiveConnectionType type = static_cast<EffectiveConnectionType>(i); | 821 EffectiveConnectionType type = static_cast<EffectiveConnectionType>(i); |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1190 NotifyObserversOfEffectiveConnectionTypeChanged() { | 1230 NotifyObserversOfEffectiveConnectionTypeChanged() { |
| 1191 DCHECK(thread_checker_.CalledOnValidThread()); | 1231 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1192 | 1232 |
| 1193 // TODO(tbansal): Add hysteresis in the notification. | 1233 // TODO(tbansal): Add hysteresis in the notification. |
| 1194 FOR_EACH_OBSERVER( | 1234 FOR_EACH_OBSERVER( |
| 1195 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, | 1235 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, |
| 1196 OnEffectiveConnectionTypeChanged(effective_connection_type_)); | 1236 OnEffectiveConnectionTypeChanged(effective_connection_type_)); |
| 1197 } | 1237 } |
| 1198 | 1238 |
| 1199 } // namespace net | 1239 } // namespace net |
| OLD | NEW |