| 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 12 matching lines...) Expand all Loading... |
| 23 #include "base/strings/stringprintf.h" | 23 #include "base/strings/stringprintf.h" |
| 24 #include "base/threading/thread_task_runner_handle.h" | 24 #include "base/threading/thread_task_runner_handle.h" |
| 25 #include "base/time/default_tick_clock.h" | 25 #include "base/time/default_tick_clock.h" |
| 26 #include "base/trace_event/trace_event.h" | 26 #include "base/trace_event/trace_event.h" |
| 27 #include "build/build_config.h" | 27 #include "build/build_config.h" |
| 28 #include "net/base/load_flags.h" | 28 #include "net/base/load_flags.h" |
| 29 #include "net/base/load_timing_info.h" | 29 #include "net/base/load_timing_info.h" |
| 30 #include "net/base/network_interfaces.h" | 30 #include "net/base/network_interfaces.h" |
| 31 #include "net/base/url_util.h" | 31 #include "net/base/url_util.h" |
| 32 #include "net/http/http_status_code.h" | 32 #include "net/http/http_status_code.h" |
| 33 #include "net/nqe/network_quality_estimator_params.h" |
| 33 #include "net/nqe/socket_watcher_factory.h" | 34 #include "net/nqe/socket_watcher_factory.h" |
| 34 #include "net/nqe/throughput_analyzer.h" | 35 #include "net/nqe/throughput_analyzer.h" |
| 35 #include "net/url_request/url_request.h" | 36 #include "net/url_request/url_request.h" |
| 36 #include "net/url_request/url_request_status.h" | 37 #include "net/url_request/url_request_status.h" |
| 37 #include "url/gurl.h" | 38 #include "url/gurl.h" |
| 38 | 39 |
| 39 #if defined(OS_ANDROID) | 40 #if defined(OS_ANDROID) |
| 40 #include "net/android/cellular_signal_strength.h" | 41 #include "net/android/cellular_signal_strength.h" |
| 41 #include "net/android/network_library.h" | 42 #include "net/android/network_library.h" |
| 42 #endif // OS_ANDROID | 43 #endif // OS_ANDROID |
| 43 | 44 |
| 44 namespace { | 45 namespace { |
| 45 | 46 |
| 46 // Default value of the half life (in seconds) for computing time weighted | |
| 47 // percentiles. Every half life, the weight of all observations reduces by | |
| 48 // half. Lowering the half life would reduce the weight of older values faster. | |
| 49 const int kDefaultHalfLifeSeconds = 60; | |
| 50 | |
| 51 // Name of the variation parameter that holds the value of the half life (in | |
| 52 // seconds) of the observations. | |
| 53 const char kHalfLifeSecondsParamName[] = "HalfLifeSeconds"; | |
| 54 | |
| 55 // Returns a descriptive name corresponding to |connection_type|. | |
| 56 const char* GetNameForConnectionType( | |
| 57 net::NetworkChangeNotifier::ConnectionType connection_type) { | |
| 58 switch (connection_type) { | |
| 59 case net::NetworkChangeNotifier::CONNECTION_UNKNOWN: | |
| 60 return "Unknown"; | |
| 61 case net::NetworkChangeNotifier::CONNECTION_ETHERNET: | |
| 62 return "Ethernet"; | |
| 63 case net::NetworkChangeNotifier::CONNECTION_WIFI: | |
| 64 return "WiFi"; | |
| 65 case net::NetworkChangeNotifier::CONNECTION_2G: | |
| 66 return "2G"; | |
| 67 case net::NetworkChangeNotifier::CONNECTION_3G: | |
| 68 return "3G"; | |
| 69 case net::NetworkChangeNotifier::CONNECTION_4G: | |
| 70 return "4G"; | |
| 71 case net::NetworkChangeNotifier::CONNECTION_NONE: | |
| 72 return "None"; | |
| 73 case net::NetworkChangeNotifier::CONNECTION_BLUETOOTH: | |
| 74 return "Bluetooth"; | |
| 75 default: | |
| 76 NOTREACHED(); | |
| 77 break; | |
| 78 } | |
| 79 return ""; | |
| 80 } | |
| 81 | |
| 82 // Suffix of the name of the variation parameter that contains the default RTT | |
| 83 // observation (in milliseconds). Complete name of the variation parameter | |
| 84 // would be |ConnectionType|.|kDefaultRTTMsecObservationSuffix| where | |
| 85 // |ConnectionType| is from |kConnectionTypeNames|. For example, variation | |
| 86 // parameter for Wi-Fi would be "WiFi.DefaultMedianRTTMsec". | |
| 87 const char kDefaultRTTMsecObservationSuffix[] = ".DefaultMedianRTTMsec"; | |
| 88 | |
| 89 // Suffix of the name of the variation parameter that contains the default | |
| 90 // downstream throughput observation (in Kbps). Complete name of the variation | |
| 91 // parameter would be |ConnectionType|.|kDefaultKbpsObservationSuffix| where | |
| 92 // |ConnectionType| is from |kConnectionTypeNames|. For example, variation | |
| 93 // parameter for Wi-Fi would be "WiFi.DefaultMedianKbps". | |
| 94 const char kDefaultKbpsObservationSuffix[] = ".DefaultMedianKbps"; | |
| 95 | |
| 96 // Suffix of the name of the variation parameter that contains the threshold | |
| 97 // HTTP RTTs (in milliseconds) for different effective connection types. | |
| 98 // Complete name of the variation parameter would be | |
| 99 // |EffectiveConnectionType|.|kThresholdURLRTTMsecSuffix|. | |
| 100 const char kThresholdURLRTTMsecSuffix[] = ".ThresholdMedianHttpRTTMsec"; | |
| 101 | |
| 102 // Suffix of the name of the variation parameter that contains the threshold | |
| 103 // transport RTTs (in milliseconds) for different effective connection types. | |
| 104 // Complete name of the variation parameter would be | |
| 105 // |EffectiveConnectionType|.|kThresholdTransportRTTMsecSuffix|. | |
| 106 const char kThresholdTransportRTTMsecSuffix[] = | |
| 107 ".ThresholdMedianTransportRTTMsec"; | |
| 108 | |
| 109 // Suffix of the name of the variation parameter that contains the threshold | |
| 110 // downlink throughput (in kbps) for different effective connection types. | |
| 111 // Complete name of the variation parameter would be | |
| 112 // |EffectiveConnectionType|.|kThresholdKbpsSuffix|. | |
| 113 const char kThresholdKbpsSuffix[] = ".ThresholdMedianKbps"; | |
| 114 | |
| 115 // Computes and returns the weight multiplier per second. | |
| 116 // |variation_params| is the map containing all field trial parameters | |
| 117 // related to NetworkQualityEstimator field trial. | |
| 118 double GetWeightMultiplierPerSecond( | |
| 119 const std::map<std::string, std::string>& variation_params) { | |
| 120 int half_life_seconds = kDefaultHalfLifeSeconds; | |
| 121 int32_t variations_value = 0; | |
| 122 auto it = variation_params.find(kHalfLifeSecondsParamName); | |
| 123 if (it != variation_params.end() && | |
| 124 base::StringToInt(it->second, &variations_value) && | |
| 125 variations_value >= 1) { | |
| 126 half_life_seconds = variations_value; | |
| 127 } | |
| 128 DCHECK_GT(half_life_seconds, 0); | |
| 129 return exp(log(0.5) / half_life_seconds); | |
| 130 } | |
| 131 | |
| 132 // Returns the histogram that should be used to record the given statistic. | 47 // Returns the histogram that should be used to record the given statistic. |
| 133 // |max_limit| is the maximum value that can be stored in the histogram. | 48 // |max_limit| is the maximum value that can be stored in the histogram. |
| 134 base::HistogramBase* GetHistogram( | 49 base::HistogramBase* GetHistogram( |
| 135 const std::string& statistic_name, | 50 const std::string& statistic_name, |
| 136 net::NetworkChangeNotifier::ConnectionType type, | 51 net::NetworkChangeNotifier::ConnectionType type, |
| 137 int32_t max_limit) { | 52 int32_t max_limit) { |
| 138 const base::LinearHistogram::Sample kLowerLimit = 1; | 53 const base::LinearHistogram::Sample kLowerLimit = 1; |
| 139 DCHECK_GT(max_limit, kLowerLimit); | 54 DCHECK_GT(max_limit, kLowerLimit); |
| 140 const size_t kBucketCount = 50; | 55 const size_t kBucketCount = 50; |
| 141 | 56 |
| 142 // Prefix of network quality estimator histograms. | |
| 143 const char prefix[] = "NQE."; | |
| 144 return base::Histogram::FactoryGet( | 57 return base::Histogram::FactoryGet( |
| 145 prefix + statistic_name + GetNameForConnectionType(type), kLowerLimit, | 58 "NQE." + statistic_name + |
| 146 max_limit, kBucketCount, base::HistogramBase::kUmaTargetedHistogramFlag); | 59 net::nqe::internal::GetNameForConnectionType(type), |
| 147 } | 60 kLowerLimit, max_limit, kBucketCount, |
| 148 | 61 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 149 // Sets |variations_value| to the value of |parameter_name| read from | |
| 150 // |variation_params|. If the value is unavailable from |variation_params|, then | |
| 151 // |variations_value| is set to |default_value|. | |
| 152 void GetValueForVariationParam( | |
| 153 const std::map<std::string, std::string>& variation_params, | |
| 154 const std::string& parameter_name, | |
| 155 int64_t default_value, | |
| 156 int64_t* variations_value) { | |
| 157 const auto it = variation_params.find(parameter_name); | |
| 158 if (it != variation_params.end() && | |
| 159 base::StringToInt64(it->second, variations_value)) { | |
| 160 return; | |
| 161 } | |
| 162 *variations_value = default_value; | |
| 163 } | |
| 164 | |
| 165 // Returns the variation value for |parameter_name|. If the value is | |
| 166 // unavailable, |default_value| is returned. | |
| 167 double GetDoubleValueForVariationParamWithDefaultValue( | |
| 168 const std::map<std::string, std::string>& variation_params, | |
| 169 const std::string& parameter_name, | |
| 170 double default_value) { | |
| 171 const auto it = variation_params.find(parameter_name); | |
| 172 if (it == variation_params.end()) | |
| 173 return default_value; | |
| 174 | |
| 175 double variations_value = default_value; | |
| 176 if (!base::StringToDouble(it->second, &variations_value)) | |
| 177 return default_value; | |
| 178 return variations_value; | |
| 179 } | |
| 180 | |
| 181 // Returns the variation value for |parameter_name|. If the value is | |
| 182 // unavailable, |default_value| is returned. | |
| 183 std::string GetStringValueForVariationParamWithDefaultValue( | |
| 184 const std::map<std::string, std::string>& variation_params, | |
| 185 const std::string& parameter_name, | |
| 186 const std::string& default_value) { | |
| 187 const auto it = variation_params.find(parameter_name); | |
| 188 if (it == variation_params.end()) | |
| 189 return default_value; | |
| 190 return it->second; | |
| 191 } | |
| 192 | |
| 193 // Returns the algorithm that should be used for computing effective connection | |
| 194 // type based on field trial params. Returns an empty string if a valid | |
| 195 // algorithm paramter is not present in the field trial params. | |
| 196 std::string GetEffectiveConnectionTypeAlgorithm( | |
| 197 const std::map<std::string, std::string>& variation_params) { | |
| 198 const auto it = variation_params.find("effective_connection_type_algorithm"); | |
| 199 if (it == variation_params.end()) | |
| 200 return std::string(); | |
| 201 return it->second; | |
| 202 } | 62 } |
| 203 | 63 |
| 204 net::NetworkQualityObservationSource ProtocolSourceToObservationSource( | 64 net::NetworkQualityObservationSource ProtocolSourceToObservationSource( |
| 205 net::SocketPerformanceWatcherFactory::Protocol protocol) { | 65 net::SocketPerformanceWatcherFactory::Protocol protocol) { |
| 206 switch (protocol) { | 66 switch (protocol) { |
| 207 case net::SocketPerformanceWatcherFactory::PROTOCOL_TCP: | 67 case net::SocketPerformanceWatcherFactory::PROTOCOL_TCP: |
| 208 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_TCP; | 68 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_TCP; |
| 209 case net::SocketPerformanceWatcherFactory::PROTOCOL_QUIC: | 69 case net::SocketPerformanceWatcherFactory::PROTOCOL_QUIC: |
| 210 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC; | 70 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC; |
| 211 } | 71 } |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 bool use_smaller_responses_for_tests) | 220 bool use_smaller_responses_for_tests) |
| 361 : algorithm_name_to_enum_({{"HttpRTTAndDownstreamThroughput", | 221 : algorithm_name_to_enum_({{"HttpRTTAndDownstreamThroughput", |
| 362 EffectiveConnectionTypeAlgorithm:: | 222 EffectiveConnectionTypeAlgorithm:: |
| 363 HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT}, | 223 HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT}, |
| 364 {"TransportRTTOrDownstreamThroughput", | 224 {"TransportRTTOrDownstreamThroughput", |
| 365 EffectiveConnectionTypeAlgorithm:: | 225 EffectiveConnectionTypeAlgorithm:: |
| 366 TRANSPORT_RTT_OR_DOWNSTREAM_THROUGHOUT}}), | 226 TRANSPORT_RTT_OR_DOWNSTREAM_THROUGHOUT}}), |
| 367 use_localhost_requests_(use_local_host_requests_for_tests), | 227 use_localhost_requests_(use_local_host_requests_for_tests), |
| 368 use_small_responses_(use_smaller_responses_for_tests), | 228 use_small_responses_(use_smaller_responses_for_tests), |
| 369 weight_multiplier_per_second_( | 229 weight_multiplier_per_second_( |
| 370 GetWeightMultiplierPerSecond(variation_params)), | 230 nqe::internal::GetWeightMultiplierPerSecond(variation_params)), |
| 371 effective_connection_type_algorithm_( | 231 effective_connection_type_algorithm_( |
| 372 algorithm_name_to_enum_.find(GetEffectiveConnectionTypeAlgorithm( | 232 algorithm_name_to_enum_.find( |
| 373 variation_params)) == algorithm_name_to_enum_.end() | 233 net::nqe::internal::GetEffectiveConnectionTypeAlgorithm( |
| 234 variation_params)) == algorithm_name_to_enum_.end() |
| 374 ? kDefaultEffectiveConnectionTypeAlgorithm | 235 ? kDefaultEffectiveConnectionTypeAlgorithm |
| 375 : algorithm_name_to_enum_ | 236 : algorithm_name_to_enum_ |
| 376 .find(GetEffectiveConnectionTypeAlgorithm(variation_params)) | 237 .find( |
| 238 net::nqe::internal::GetEffectiveConnectionTypeAlgorithm( |
| 239 variation_params)) |
| 377 ->second), | 240 ->second), |
| 378 tick_clock_(new base::DefaultTickClock()), | 241 tick_clock_(new base::DefaultTickClock()), |
| 379 last_connection_change_(tick_clock_->NowTicks()), | 242 last_connection_change_(tick_clock_->NowTicks()), |
| 380 current_network_id_(nqe::internal::NetworkID( | 243 current_network_id_(nqe::internal::NetworkID( |
| 381 NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, | 244 NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, |
| 382 std::string())), | 245 std::string())), |
| 383 downstream_throughput_kbps_observations_(weight_multiplier_per_second_), | 246 downstream_throughput_kbps_observations_(weight_multiplier_per_second_), |
| 384 rtt_observations_(weight_multiplier_per_second_), | 247 rtt_observations_(weight_multiplier_per_second_), |
| 385 effective_connection_type_at_last_main_frame_( | 248 effective_connection_type_at_last_main_frame_( |
| 386 EFFECTIVE_CONNECTION_TYPE_UNKNOWN), | 249 EFFECTIVE_CONNECTION_TYPE_UNKNOWN), |
| 387 external_estimate_provider_(std::move(external_estimates_provider)), | 250 external_estimate_provider_(std::move(external_estimates_provider)), |
| 388 effective_connection_type_recomputation_interval_( | 251 effective_connection_type_recomputation_interval_( |
| 389 base::TimeDelta::FromSeconds(10)), | 252 base::TimeDelta::FromSeconds(10)), |
| 390 rtt_observations_size_at_last_ect_computation_(0), | 253 rtt_observations_size_at_last_ect_computation_(0), |
| 391 throughput_observations_size_at_last_ect_computation_(0), | 254 throughput_observations_size_at_last_ect_computation_(0), |
| 392 http_rtt_(nqe::internal::InvalidRTT()), | 255 http_rtt_(nqe::internal::InvalidRTT()), |
| 393 transport_rtt_(nqe::internal::InvalidRTT()), | 256 transport_rtt_(nqe::internal::InvalidRTT()), |
| 394 downstream_throughput_kbps_(nqe::internal::kInvalidThroughput), | 257 downstream_throughput_kbps_(nqe::internal::kInvalidThroughput), |
| 395 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), | 258 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), |
| 396 min_signal_strength_since_connection_change_(INT32_MAX), | 259 min_signal_strength_since_connection_change_(INT32_MAX), |
| 397 max_signal_strength_since_connection_change_(INT32_MIN), | 260 max_signal_strength_since_connection_change_(INT32_MIN), |
| 398 correlation_uma_logging_probability_( | 261 correlation_uma_logging_probability_( |
| 399 GetDoubleValueForVariationParamWithDefaultValue( | 262 nqe::internal::correlation_uma_logging_probability(variation_params)), |
| 400 variation_params, | |
| 401 "correlation_logging_probability", | |
| 402 0.0)), | |
| 403 forced_effective_connection_type_set_( | 263 forced_effective_connection_type_set_( |
| 404 !GetStringValueForVariationParamWithDefaultValue( | 264 nqe::internal::forced_effective_connection_type_set( |
| 405 variation_params, | 265 variation_params)), |
| 406 "force_effective_connection_type", | 266 forced_effective_connection_type_( |
| 407 "") | 267 nqe::internal::forced_effective_connection_type(variation_params)), |
| 408 .empty()), | |
| 409 weak_ptr_factory_(this) { | 268 weak_ptr_factory_(this) { |
| 410 static_assert(kDefaultHalfLifeSeconds > 0, | |
| 411 "Default half life duration must be > 0"); | |
| 412 static_assert(kMinimumRTTVariationParameterMsec > 0 && | |
| 413 kMinimumRTTVariationParameterMsec > | |
| 414 nqe::internal::INVALID_RTT_THROUGHPUT, | |
| 415 "kMinimumRTTVariationParameterMsec is set incorrectly"); | |
| 416 static_assert(kMinimumThroughputVariationParameterKbps > 0 && | |
| 417 kMinimumThroughputVariationParameterKbps > | |
| 418 nqe::internal::kInvalidThroughput, | |
| 419 "kMinimumThroughputVariationParameterKbps is set incorrectly"); | |
| 420 // None of the algorithms can have an empty name. | 269 // None of the algorithms can have an empty name. |
| 421 DCHECK(algorithm_name_to_enum_.end() == | 270 DCHECK(algorithm_name_to_enum_.end() == |
| 422 algorithm_name_to_enum_.find(std::string())); | 271 algorithm_name_to_enum_.find(std::string())); |
| 423 | 272 |
| 424 DCHECK_EQ(algorithm_name_to_enum_.size(), | 273 DCHECK_EQ(algorithm_name_to_enum_.size(), |
| 425 static_cast<size_t>(EffectiveConnectionTypeAlgorithm:: | 274 static_cast<size_t>(EffectiveConnectionTypeAlgorithm:: |
| 426 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST)); | 275 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST)); |
| 427 DCHECK_NE(EffectiveConnectionTypeAlgorithm:: | 276 DCHECK_NE(EffectiveConnectionTypeAlgorithm:: |
| 428 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST, | 277 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST, |
| 429 effective_connection_type_algorithm_); | 278 effective_connection_type_algorithm_); |
| 430 DCHECK_LE(0.0, correlation_uma_logging_probability_); | |
| 431 DCHECK_GE(1.0, correlation_uma_logging_probability_); | |
| 432 | 279 |
| 433 network_quality_store_.reset(new nqe::internal::NetworkQualityStore()); | 280 network_quality_store_.reset(new nqe::internal::NetworkQualityStore()); |
| 434 ObtainOperatingParams(variation_params); | 281 ObtainOperatingParams(variation_params); |
| 435 ObtainEffectiveConnectionTypeModelParams(variation_params); | |
| 436 NetworkChangeNotifier::AddConnectionTypeObserver(this); | 282 NetworkChangeNotifier::AddConnectionTypeObserver(this); |
| 437 if (external_estimate_provider_) { | 283 if (external_estimate_provider_) { |
| 438 RecordExternalEstimateProviderMetrics( | 284 RecordExternalEstimateProviderMetrics( |
| 439 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE); | 285 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE); |
| 440 external_estimate_provider_->SetUpdatedEstimateDelegate(this); | 286 external_estimate_provider_->SetUpdatedEstimateDelegate(this); |
| 441 } else { | 287 } else { |
| 442 RecordExternalEstimateProviderMetrics( | 288 RecordExternalEstimateProviderMetrics( |
| 443 EXTERNAL_ESTIMATE_PROVIDER_STATUS_NOT_AVAILABLE); | 289 EXTERNAL_ESTIMATE_PROVIDER_STATUS_NOT_AVAILABLE); |
| 444 } | 290 } |
| 445 current_network_id_ = GetCurrentNetworkID(); | 291 current_network_id_ = GetCurrentNetworkID(); |
| 446 AddDefaultEstimates(); | 292 AddDefaultEstimates(); |
| 447 | 293 |
| 448 throughput_analyzer_.reset(new nqe::internal::ThroughputAnalyzer( | 294 throughput_analyzer_.reset(new nqe::internal::ThroughputAnalyzer( |
| 449 base::ThreadTaskRunnerHandle::Get(), | 295 base::ThreadTaskRunnerHandle::Get(), |
| 450 base::Bind(&NetworkQualityEstimator::OnNewThroughputObservationAvailable, | 296 base::Bind(&NetworkQualityEstimator::OnNewThroughputObservationAvailable, |
| 451 base::Unretained(this)), | 297 base::Unretained(this)), |
| 452 use_localhost_requests_, use_smaller_responses_for_tests)); | 298 use_localhost_requests_, use_smaller_responses_for_tests)); |
| 453 | 299 |
| 454 watcher_factory_.reset(new nqe::internal::SocketWatcherFactory( | 300 watcher_factory_.reset(new nqe::internal::SocketWatcherFactory( |
| 455 base::ThreadTaskRunnerHandle::Get(), | 301 base::ThreadTaskRunnerHandle::Get(), |
| 456 base::Bind(&NetworkQualityEstimator::OnUpdatedRTTAvailable, | 302 base::Bind(&NetworkQualityEstimator::OnUpdatedRTTAvailable, |
| 457 base::Unretained(this)))); | 303 base::Unretained(this)))); |
| 458 | 304 |
| 459 // Record accuracy at 3 different intervals. The values used here must remain | 305 // Record accuracy at 3 different intervals. The values used here must remain |
| 460 // in sync with the suffixes specified in | 306 // in sync with the suffixes specified in |
| 461 // tools/metrics/histograms/histograms.xml. | 307 // tools/metrics/histograms/histograms.xml. |
| 462 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(15)); | 308 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(15)); |
| 463 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(30)); | 309 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(30)); |
| 464 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(60)); | 310 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(60)); |
| 465 | |
| 466 if (forced_effective_connection_type_set_) { | |
| 467 std::string forced_value = GetStringValueForVariationParamWithDefaultValue( | |
| 468 variation_params, "force_effective_connection_type", | |
| 469 GetNameForEffectiveConnectionType(EFFECTIVE_CONNECTION_TYPE_UNKNOWN)); | |
| 470 DCHECK(!forced_value.empty()); | |
| 471 bool effective_connection_type_available = | |
| 472 GetEffectiveConnectionTypeForName(forced_value, | |
| 473 &forced_effective_connection_type_); | |
| 474 DCHECK(effective_connection_type_available); | |
| 475 | |
| 476 // Silence unused variable warning in release builds. | |
| 477 (void)effective_connection_type_available; | |
| 478 } | |
| 479 } | 311 } |
| 480 | 312 |
| 481 void NetworkQualityEstimator::ObtainOperatingParams( | 313 void NetworkQualityEstimator::ObtainOperatingParams( |
| 482 const std::map<std::string, std::string>& variation_params) { | 314 const std::map<std::string, std::string>& variation_params) { |
| 483 DCHECK(thread_checker_.CalledOnValidThread()); | 315 DCHECK(thread_checker_.CalledOnValidThread()); |
| 484 | 316 nqe::internal::ObtainDefaultObservations(variation_params, |
| 485 for (size_t i = 0; i <= NetworkChangeNotifier::CONNECTION_LAST; ++i) { | 317 default_observations_); |
| 486 NetworkChangeNotifier::ConnectionType type = | 318 nqe::internal::ObtainEffectiveConnectionTypeModelParams( |
| 487 static_cast<NetworkChangeNotifier::ConnectionType>(i); | 319 variation_params, connection_thresholds_); |
| 488 DCHECK_EQ(nqe::internal::InvalidRTT(), default_observations_[i].http_rtt()); | |
| 489 DCHECK_EQ(nqe::internal::InvalidRTT(), | |
| 490 default_observations_[i].transport_rtt()); | |
| 491 DCHECK_EQ(nqe::internal::kInvalidThroughput, | |
| 492 default_observations_[i].downstream_throughput_kbps()); | |
| 493 int32_t variations_value = kMinimumRTTVariationParameterMsec - 1; | |
| 494 // Name of the parameter that holds the RTT value for this connection type. | |
| 495 std::string rtt_parameter_name = | |
| 496 std::string(GetNameForConnectionType(type)) | |
| 497 .append(kDefaultRTTMsecObservationSuffix); | |
| 498 auto it = variation_params.find(rtt_parameter_name); | |
| 499 if (it != variation_params.end() && | |
| 500 base::StringToInt(it->second, &variations_value) && | |
| 501 variations_value >= kMinimumRTTVariationParameterMsec) { | |
| 502 default_observations_[i] = nqe::internal::NetworkQuality( | |
| 503 base::TimeDelta::FromMilliseconds(variations_value), | |
| 504 default_observations_[i].transport_rtt(), | |
| 505 default_observations_[i].downstream_throughput_kbps()); | |
| 506 } | |
| 507 | |
| 508 variations_value = kMinimumThroughputVariationParameterKbps - 1; | |
| 509 // Name of the parameter that holds the Kbps value for this connection | |
| 510 // type. | |
| 511 std::string kbps_parameter_name = | |
| 512 std::string(GetNameForConnectionType(type)) | |
| 513 .append(kDefaultKbpsObservationSuffix); | |
| 514 it = variation_params.find(kbps_parameter_name); | |
| 515 if (it != variation_params.end() && | |
| 516 base::StringToInt(it->second, &variations_value) && | |
| 517 variations_value >= kMinimumThroughputVariationParameterKbps) { | |
| 518 default_observations_[i] = nqe::internal::NetworkQuality( | |
| 519 default_observations_[i].http_rtt(), | |
| 520 default_observations_[i].transport_rtt(), variations_value); | |
| 521 } | |
| 522 } | |
| 523 } | |
| 524 | |
| 525 void NetworkQualityEstimator::ObtainEffectiveConnectionTypeModelParams( | |
| 526 const std::map<std::string, std::string>& variation_params) { | |
| 527 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 528 | |
| 529 default_effective_connection_type_thresholds_ | |
| 530 [EFFECTIVE_CONNECTION_TYPE_SLOW_2G] = nqe::internal::NetworkQuality( | |
| 531 // Set to 2010 milliseconds, which corresponds to the 33rd percentile | |
| 532 // of 2G HTTP RTT observations on Android. | |
| 533 base::TimeDelta::FromMilliseconds(2010), | |
| 534 // Set to 1870 milliseconds, which corresponds to the 33rd percentile | |
| 535 // of 2G transport RTT observations on Android. | |
| 536 base::TimeDelta::FromMilliseconds(1870), | |
| 537 nqe::internal::kInvalidThroughput); | |
| 538 | |
| 539 default_effective_connection_type_thresholds_[EFFECTIVE_CONNECTION_TYPE_2G] = | |
| 540 nqe::internal::NetworkQuality( | |
| 541 // Set to 1420 milliseconds, which corresponds to 50th percentile of | |
| 542 // 2G | |
| 543 // HTTP RTT observations on Android. | |
| 544 base::TimeDelta::FromMilliseconds(1420), | |
| 545 // Set to 1280 milliseconds, which corresponds to 50th percentile of | |
| 546 // 2G | |
| 547 // transport RTT observations on Android. | |
| 548 base::TimeDelta::FromMilliseconds(1280), | |
| 549 nqe::internal::kInvalidThroughput); | |
| 550 | |
| 551 default_effective_connection_type_thresholds_[EFFECTIVE_CONNECTION_TYPE_3G] = | |
| 552 nqe::internal::NetworkQuality( | |
| 553 // Set to 273 milliseconds, which corresponds to 50th percentile of | |
| 554 // 3G HTTP RTT observations on Android. | |
| 555 base::TimeDelta::FromMilliseconds(273), | |
| 556 // Set to 204 milliseconds, which corresponds to 50th percentile of | |
| 557 // 3G transport RTT observations on Android. | |
| 558 base::TimeDelta::FromMilliseconds(204), | |
| 559 nqe::internal::kInvalidThroughput); | |
| 560 | |
| 561 for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) { | |
| 562 EffectiveConnectionType effective_connection_type = | |
| 563 static_cast<EffectiveConnectionType>(i); | |
| 564 DCHECK_EQ(nqe::internal::InvalidRTT(), | |
| 565 connection_thresholds_[i].http_rtt()); | |
| 566 DCHECK_EQ(nqe::internal::InvalidRTT(), | |
| 567 connection_thresholds_[i].transport_rtt()); | |
| 568 DCHECK_EQ(nqe::internal::kInvalidThroughput, | |
| 569 connection_thresholds_[i].downstream_throughput_kbps()); | |
| 570 if (effective_connection_type == EFFECTIVE_CONNECTION_TYPE_UNKNOWN) | |
| 571 continue; | |
| 572 | |
| 573 std::string connection_type_name = std::string( | |
| 574 GetNameForEffectiveConnectionType(effective_connection_type)); | |
| 575 | |
| 576 int64_t variations_value; | |
| 577 GetValueForVariationParam(variation_params, | |
| 578 connection_type_name + kThresholdURLRTTMsecSuffix, | |
| 579 default_effective_connection_type_thresholds_[i] | |
| 580 .http_rtt() | |
| 581 .InMilliseconds(), | |
| 582 &variations_value); | |
| 583 connection_thresholds_[i].set_http_rtt( | |
| 584 base::TimeDelta::FromMilliseconds(variations_value)); | |
| 585 | |
| 586 GetValueForVariationParam( | |
| 587 variation_params, | |
| 588 connection_type_name + kThresholdTransportRTTMsecSuffix, | |
| 589 default_effective_connection_type_thresholds_[i] | |
| 590 .transport_rtt() | |
| 591 .InMilliseconds(), | |
| 592 &variations_value); | |
| 593 connection_thresholds_[i].set_transport_rtt( | |
| 594 base::TimeDelta::FromMilliseconds(variations_value)); | |
| 595 | |
| 596 GetValueForVariationParam(variation_params, | |
| 597 connection_type_name + kThresholdKbpsSuffix, | |
| 598 default_effective_connection_type_thresholds_[i] | |
| 599 .downstream_throughput_kbps(), | |
| 600 &variations_value); | |
| 601 connection_thresholds_[i].set_downstream_throughput_kbps(variations_value); | |
| 602 DCHECK(i == 0 || | |
| 603 connection_thresholds_[i].IsFaster(connection_thresholds_[i - 1])); | |
| 604 } | |
| 605 } | 320 } |
| 606 | 321 |
| 607 void NetworkQualityEstimator::AddDefaultEstimates() { | 322 void NetworkQualityEstimator::AddDefaultEstimates() { |
| 608 DCHECK(thread_checker_.CalledOnValidThread()); | 323 DCHECK(thread_checker_.CalledOnValidThread()); |
| 609 | 324 |
| 610 if (default_observations_[current_network_id_.type].http_rtt() != | 325 if (default_observations_[current_network_id_.type].http_rtt() != |
| 611 nqe::internal::InvalidRTT()) { | 326 nqe::internal::InvalidRTT()) { |
| 612 RttObservation rtt_observation( | 327 RttObservation rtt_observation( |
| 613 default_observations_[current_network_id_.type].http_rtt(), | 328 default_observations_[current_network_id_.type].http_rtt(), |
| 614 tick_clock_->NowTicks(), | 329 tick_clock_->NowTicks(), |
| (...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1215 } | 930 } |
| 1216 | 931 |
| 1217 const EffectiveConnectionType effective_connection_type = | 932 const EffectiveConnectionType effective_connection_type = |
| 1218 GetEffectiveConnectionType(); | 933 GetEffectiveConnectionType(); |
| 1219 UMA_HISTOGRAM_ENUMERATION("NQE.MainFrame.EffectiveConnectionType", | 934 UMA_HISTOGRAM_ENUMERATION("NQE.MainFrame.EffectiveConnectionType", |
| 1220 effective_connection_type, | 935 effective_connection_type, |
| 1221 EFFECTIVE_CONNECTION_TYPE_LAST); | 936 EFFECTIVE_CONNECTION_TYPE_LAST); |
| 1222 base::HistogramBase* effective_connection_type_histogram = | 937 base::HistogramBase* effective_connection_type_histogram = |
| 1223 base::Histogram::FactoryGet( | 938 base::Histogram::FactoryGet( |
| 1224 std::string("NQE.MainFrame.EffectiveConnectionType.") + | 939 std::string("NQE.MainFrame.EffectiveConnectionType.") + |
| 1225 GetNameForConnectionType(current_network_id_.type), | 940 nqe::internal::GetNameForConnectionType(current_network_id_.type), |
| 1226 0, EFFECTIVE_CONNECTION_TYPE_LAST, | 941 0, EFFECTIVE_CONNECTION_TYPE_LAST, |
| 1227 EFFECTIVE_CONNECTION_TYPE_LAST /* Number of buckets */, | 942 EFFECTIVE_CONNECTION_TYPE_LAST /* Number of buckets */, |
| 1228 base::HistogramBase::kUmaTargetedHistogramFlag); | 943 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 1229 | 944 |
| 1230 effective_connection_type_histogram->Add(effective_connection_type); | 945 effective_connection_type_histogram->Add(effective_connection_type); |
| 1231 } | 946 } |
| 1232 | 947 |
| 1233 void NetworkQualityEstimator::ComputeEffectiveConnectionType() { | 948 void NetworkQualityEstimator::ComputeEffectiveConnectionType() { |
| 1234 DCHECK(thread_checker_.CalledOnValidThread()); | 949 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1235 | 950 |
| (...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1814 void NetworkQualityEstimator::OnPrefsRead( | 1529 void NetworkQualityEstimator::OnPrefsRead( |
| 1815 const std::map<nqe::internal::NetworkID, | 1530 const std::map<nqe::internal::NetworkID, |
| 1816 nqe::internal::CachedNetworkQuality> read_prefs) { | 1531 nqe::internal::CachedNetworkQuality> read_prefs) { |
| 1817 DCHECK(thread_checker_.CalledOnValidThread()); | 1532 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1818 UMA_HISTOGRAM_COUNTS("NQE.Prefs.ReadSize", read_prefs.size()); | 1533 UMA_HISTOGRAM_COUNTS("NQE.Prefs.ReadSize", read_prefs.size()); |
| 1819 // TODO(tbansal): crbug.com/490870. Incorporate the network quality into the | 1534 // TODO(tbansal): crbug.com/490870. Incorporate the network quality into the |
| 1820 // current estimates. | 1535 // current estimates. |
| 1821 } | 1536 } |
| 1822 | 1537 |
| 1823 } // namespace net | 1538 } // namespace net |
| OLD | NEW |