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 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. | 57 // Prefix of network quality estimator histograms. |
| 143 const char prefix[] = "NQE."; | 58 const char prefix[] = "NQE."; |
| 144 return base::Histogram::FactoryGet( | 59 return base::Histogram::FactoryGet( |
| 145 prefix + statistic_name + GetNameForConnectionType(type), kLowerLimit, | 60 prefix + statistic_name + |
|
bengr
2016/10/27 16:12:29
You could just move "NQE." to this line.
tbansal1
2016/10/28 20:26:04
Done.
| |
| 146 max_limit, kBucketCount, base::HistogramBase::kUmaTargetedHistogramFlag); | 61 net::nqe::internal::GetNameForConnectionType(type), |
| 147 } | 62 kLowerLimit, max_limit, kBucketCount, |
| 148 | 63 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 } | 64 } |
| 203 | 65 |
| 204 net::NetworkQualityObservationSource ProtocolSourceToObservationSource( | 66 net::NetworkQualityObservationSource ProtocolSourceToObservationSource( |
| 205 net::SocketPerformanceWatcherFactory::Protocol protocol) { | 67 net::SocketPerformanceWatcherFactory::Protocol protocol) { |
| 206 switch (protocol) { | 68 switch (protocol) { |
| 207 case net::SocketPerformanceWatcherFactory::PROTOCOL_TCP: | 69 case net::SocketPerformanceWatcherFactory::PROTOCOL_TCP: |
| 208 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_TCP; | 70 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_TCP; |
| 209 case net::SocketPerformanceWatcherFactory::PROTOCOL_QUIC: | 71 case net::SocketPerformanceWatcherFactory::PROTOCOL_QUIC: |
| 210 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC; | 72 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC; |
| 211 } | 73 } |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 360 bool use_smaller_responses_for_tests) | 222 bool use_smaller_responses_for_tests) |
| 361 : algorithm_name_to_enum_({{"HttpRTTAndDownstreamThroughput", | 223 : algorithm_name_to_enum_({{"HttpRTTAndDownstreamThroughput", |
| 362 EffectiveConnectionTypeAlgorithm:: | 224 EffectiveConnectionTypeAlgorithm:: |
| 363 HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT}, | 225 HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT}, |
| 364 {"TransportRTTOrDownstreamThroughput", | 226 {"TransportRTTOrDownstreamThroughput", |
| 365 EffectiveConnectionTypeAlgorithm:: | 227 EffectiveConnectionTypeAlgorithm:: |
| 366 TRANSPORT_RTT_OR_DOWNSTREAM_THROUGHOUT}}), | 228 TRANSPORT_RTT_OR_DOWNSTREAM_THROUGHOUT}}), |
| 367 use_localhost_requests_(use_local_host_requests_for_tests), | 229 use_localhost_requests_(use_local_host_requests_for_tests), |
| 368 use_small_responses_(use_smaller_responses_for_tests), | 230 use_small_responses_(use_smaller_responses_for_tests), |
| 369 weight_multiplier_per_second_( | 231 weight_multiplier_per_second_( |
| 370 GetWeightMultiplierPerSecond(variation_params)), | 232 nqe::internal::GetWeightMultiplierPerSecond(variation_params)), |
| 371 effective_connection_type_algorithm_( | 233 effective_connection_type_algorithm_( |
| 372 algorithm_name_to_enum_.find(GetEffectiveConnectionTypeAlgorithm( | 234 algorithm_name_to_enum_.find( |
| 373 variation_params)) == algorithm_name_to_enum_.end() | 235 net::nqe::internal::GetEffectiveConnectionTypeAlgorithm( |
| 236 variation_params)) == algorithm_name_to_enum_.end() | |
| 374 ? kDefaultEffectiveConnectionTypeAlgorithm | 237 ? kDefaultEffectiveConnectionTypeAlgorithm |
| 375 : algorithm_name_to_enum_ | 238 : algorithm_name_to_enum_ |
| 376 .find(GetEffectiveConnectionTypeAlgorithm(variation_params)) | 239 .find( |
| 240 net::nqe::internal::GetEffectiveConnectionTypeAlgorithm( | |
| 241 variation_params)) | |
| 377 ->second), | 242 ->second), |
| 378 tick_clock_(new base::DefaultTickClock()), | 243 tick_clock_(new base::DefaultTickClock()), |
| 379 last_connection_change_(tick_clock_->NowTicks()), | 244 last_connection_change_(tick_clock_->NowTicks()), |
| 380 current_network_id_(nqe::internal::NetworkID( | 245 current_network_id_(nqe::internal::NetworkID( |
| 381 NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, | 246 NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, |
| 382 std::string())), | 247 std::string())), |
| 383 downstream_throughput_kbps_observations_(weight_multiplier_per_second_), | 248 downstream_throughput_kbps_observations_(weight_multiplier_per_second_), |
| 384 rtt_observations_(weight_multiplier_per_second_), | 249 rtt_observations_(weight_multiplier_per_second_), |
| 385 effective_connection_type_at_last_main_frame_( | 250 effective_connection_type_at_last_main_frame_( |
| 386 EFFECTIVE_CONNECTION_TYPE_UNKNOWN), | 251 EFFECTIVE_CONNECTION_TYPE_UNKNOWN), |
| 387 external_estimate_provider_(std::move(external_estimates_provider)), | 252 external_estimate_provider_(std::move(external_estimates_provider)), |
| 388 effective_connection_type_recomputation_interval_( | 253 effective_connection_type_recomputation_interval_( |
| 389 base::TimeDelta::FromSeconds(10)), | 254 base::TimeDelta::FromSeconds(10)), |
| 390 rtt_observations_size_at_last_ect_computation_(0), | 255 rtt_observations_size_at_last_ect_computation_(0), |
| 391 throughput_observations_size_at_last_ect_computation_(0), | 256 throughput_observations_size_at_last_ect_computation_(0), |
| 392 http_rtt_(nqe::internal::InvalidRTT()), | 257 http_rtt_(nqe::internal::InvalidRTT()), |
| 393 transport_rtt_(nqe::internal::InvalidRTT()), | 258 transport_rtt_(nqe::internal::InvalidRTT()), |
| 394 downstream_throughput_kbps_(nqe::internal::kInvalidThroughput), | 259 downstream_throughput_kbps_(nqe::internal::kInvalidThroughput), |
| 395 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), | 260 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), |
| 396 min_signal_strength_since_connection_change_(INT32_MAX), | 261 min_signal_strength_since_connection_change_(INT32_MAX), |
| 397 max_signal_strength_since_connection_change_(INT32_MIN), | 262 max_signal_strength_since_connection_change_(INT32_MIN), |
| 398 correlation_uma_logging_probability_( | 263 correlation_uma_logging_probability_( |
| 399 GetDoubleValueForVariationParamWithDefaultValue( | 264 nqe::internal::correlation_uma_logging_probability(variation_params)), |
| 400 variation_params, | |
| 401 "correlation_logging_probability", | |
| 402 0.0)), | |
| 403 forced_effective_connection_type_set_( | 265 forced_effective_connection_type_set_( |
| 404 !GetStringValueForVariationParamWithDefaultValue( | 266 nqe::internal::forced_effective_connection_type_set( |
| 405 variation_params, | 267 variation_params)), |
| 406 "force_effective_connection_type", | 268 forced_effective_connection_type_( |
| 407 "") | 269 nqe::internal::forced_effective_connection_type(variation_params)), |
| 408 .empty()), | |
| 409 weak_ptr_factory_(this) { | 270 weak_ptr_factory_(this) { |
| 410 static_assert(kDefaultHalfLifeSeconds > 0, | |
| 411 "Default half life duration must be > 0"); | |
| 412 // None of the algorithms can have an empty name. | 271 // None of the algorithms can have an empty name. |
| 413 DCHECK(algorithm_name_to_enum_.end() == | 272 DCHECK(algorithm_name_to_enum_.end() == |
| 414 algorithm_name_to_enum_.find(std::string())); | 273 algorithm_name_to_enum_.find(std::string())); |
| 415 | 274 |
| 416 DCHECK_EQ(algorithm_name_to_enum_.size(), | 275 DCHECK_EQ(algorithm_name_to_enum_.size(), |
| 417 static_cast<size_t>(EffectiveConnectionTypeAlgorithm:: | 276 static_cast<size_t>(EffectiveConnectionTypeAlgorithm:: |
| 418 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST)); | 277 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST)); |
| 419 DCHECK_NE(EffectiveConnectionTypeAlgorithm:: | 278 DCHECK_NE(EffectiveConnectionTypeAlgorithm:: |
| 420 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST, | 279 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST, |
| 421 effective_connection_type_algorithm_); | 280 effective_connection_type_algorithm_); |
| 422 DCHECK_LE(0.0, correlation_uma_logging_probability_); | |
| 423 DCHECK_GE(1.0, correlation_uma_logging_probability_); | |
| 424 | 281 |
| 425 network_quality_store_.reset(new nqe::internal::NetworkQualityStore()); | 282 network_quality_store_.reset(new nqe::internal::NetworkQualityStore()); |
| 426 ObtainOperatingParams(variation_params); | 283 ObtainOperatingParams(variation_params); |
| 427 ObtainEffectiveConnectionTypeModelParams(variation_params); | |
| 428 NetworkChangeNotifier::AddConnectionTypeObserver(this); | 284 NetworkChangeNotifier::AddConnectionTypeObserver(this); |
| 429 if (external_estimate_provider_) { | 285 if (external_estimate_provider_) { |
| 430 RecordExternalEstimateProviderMetrics( | 286 RecordExternalEstimateProviderMetrics( |
| 431 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE); | 287 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE); |
| 432 external_estimate_provider_->SetUpdatedEstimateDelegate(this); | 288 external_estimate_provider_->SetUpdatedEstimateDelegate(this); |
| 433 } else { | 289 } else { |
| 434 RecordExternalEstimateProviderMetrics( | 290 RecordExternalEstimateProviderMetrics( |
| 435 EXTERNAL_ESTIMATE_PROVIDER_STATUS_NOT_AVAILABLE); | 291 EXTERNAL_ESTIMATE_PROVIDER_STATUS_NOT_AVAILABLE); |
| 436 } | 292 } |
| 437 current_network_id_ = GetCurrentNetworkID(); | 293 current_network_id_ = GetCurrentNetworkID(); |
| 438 AddDefaultEstimates(); | 294 AddDefaultEstimates(); |
| 439 | 295 |
| 440 throughput_analyzer_.reset(new nqe::internal::ThroughputAnalyzer( | 296 throughput_analyzer_.reset(new nqe::internal::ThroughputAnalyzer( |
| 441 base::ThreadTaskRunnerHandle::Get(), | 297 base::ThreadTaskRunnerHandle::Get(), |
| 442 base::Bind(&NetworkQualityEstimator::OnNewThroughputObservationAvailable, | 298 base::Bind(&NetworkQualityEstimator::OnNewThroughputObservationAvailable, |
| 443 base::Unretained(this)), | 299 base::Unretained(this)), |
| 444 use_localhost_requests_, use_smaller_responses_for_tests)); | 300 use_localhost_requests_, use_smaller_responses_for_tests)); |
| 445 | 301 |
| 446 watcher_factory_.reset(new nqe::internal::SocketWatcherFactory( | 302 watcher_factory_.reset(new nqe::internal::SocketWatcherFactory( |
| 447 base::ThreadTaskRunnerHandle::Get(), | 303 base::ThreadTaskRunnerHandle::Get(), |
| 448 base::Bind(&NetworkQualityEstimator::OnUpdatedRTTAvailable, | 304 base::Bind(&NetworkQualityEstimator::OnUpdatedRTTAvailable, |
| 449 base::Unretained(this)))); | 305 base::Unretained(this)))); |
| 450 | 306 |
| 451 // Record accuracy at 3 different intervals. The values used here must remain | 307 // Record accuracy at 3 different intervals. The values used here must remain |
| 452 // in sync with the suffixes specified in | 308 // in sync with the suffixes specified in |
| 453 // tools/metrics/histograms/histograms.xml. | 309 // tools/metrics/histograms/histograms.xml. |
| 454 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(15)); | 310 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(15)); |
| 455 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(30)); | 311 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(30)); |
| 456 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(60)); | 312 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(60)); |
| 457 | |
| 458 if (forced_effective_connection_type_set_) { | |
| 459 std::string forced_value = GetStringValueForVariationParamWithDefaultValue( | |
| 460 variation_params, "force_effective_connection_type", | |
| 461 GetNameForEffectiveConnectionType(EFFECTIVE_CONNECTION_TYPE_UNKNOWN)); | |
| 462 DCHECK(!forced_value.empty()); | |
| 463 bool effective_connection_type_available = | |
| 464 GetEffectiveConnectionTypeForName(forced_value, | |
| 465 &forced_effective_connection_type_); | |
| 466 DCHECK(effective_connection_type_available); | |
| 467 | |
| 468 // Silence unused variable warning in release builds. | |
| 469 (void)effective_connection_type_available; | |
| 470 } | |
| 471 } | 313 } |
| 472 | 314 |
| 473 void NetworkQualityEstimator::ObtainOperatingParams( | 315 void NetworkQualityEstimator::ObtainOperatingParams( |
| 474 const std::map<std::string, std::string>& variation_params) { | 316 const std::map<std::string, std::string>& variation_params) { |
| 475 DCHECK(thread_checker_.CalledOnValidThread()); | 317 DCHECK(thread_checker_.CalledOnValidThread()); |
| 476 | 318 nqe::internal::ObtainDefaultObservations(variation_params, |
| 477 for (size_t i = 0; i <= NetworkChangeNotifier::CONNECTION_LAST; ++i) { | 319 default_observations_); |
| 478 NetworkChangeNotifier::ConnectionType type = | 320 nqe::internal::ObtainEffectiveConnectionTypeModelParams( |
| 479 static_cast<NetworkChangeNotifier::ConnectionType>(i); | 321 variation_params, connection_thresholds_); |
| 480 DCHECK_EQ(nqe::internal::InvalidRTT(), default_observations_[i].http_rtt()); | |
| 481 DCHECK_EQ(nqe::internal::InvalidRTT(), | |
| 482 default_observations_[i].transport_rtt()); | |
| 483 DCHECK_EQ(nqe::internal::kInvalidThroughput, | |
| 484 default_observations_[i].downstream_throughput_kbps()); | |
| 485 int32_t variations_value = kMinimumRTTVariationParameterMsec - 1; | |
| 486 // Name of the parameter that holds the RTT value for this connection type. | |
| 487 std::string rtt_parameter_name = | |
| 488 std::string(GetNameForConnectionType(type)) | |
| 489 .append(kDefaultRTTMsecObservationSuffix); | |
| 490 auto it = variation_params.find(rtt_parameter_name); | |
| 491 if (it != variation_params.end() && | |
| 492 base::StringToInt(it->second, &variations_value) && | |
| 493 variations_value >= kMinimumRTTVariationParameterMsec) { | |
| 494 default_observations_[i] = nqe::internal::NetworkQuality( | |
| 495 base::TimeDelta::FromMilliseconds(variations_value), | |
| 496 default_observations_[i].transport_rtt(), | |
| 497 default_observations_[i].downstream_throughput_kbps()); | |
| 498 } | |
| 499 | |
| 500 variations_value = kMinimumThroughputVariationParameterKbps - 1; | |
| 501 // Name of the parameter that holds the Kbps value for this connection | |
| 502 // type. | |
| 503 std::string kbps_parameter_name = | |
| 504 std::string(GetNameForConnectionType(type)) | |
| 505 .append(kDefaultKbpsObservationSuffix); | |
| 506 it = variation_params.find(kbps_parameter_name); | |
| 507 if (it != variation_params.end() && | |
| 508 base::StringToInt(it->second, &variations_value) && | |
| 509 variations_value >= kMinimumThroughputVariationParameterKbps) { | |
| 510 default_observations_[i] = nqe::internal::NetworkQuality( | |
| 511 default_observations_[i].http_rtt(), | |
| 512 default_observations_[i].transport_rtt(), variations_value); | |
| 513 } | |
| 514 } | |
| 515 } | |
| 516 | |
| 517 void NetworkQualityEstimator::ObtainEffectiveConnectionTypeModelParams( | |
| 518 const std::map<std::string, std::string>& variation_params) { | |
| 519 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 520 | |
| 521 default_effective_connection_type_thresholds_ | |
| 522 [EFFECTIVE_CONNECTION_TYPE_SLOW_2G] = nqe::internal::NetworkQuality( | |
| 523 // Set to 2010 milliseconds, which corresponds to the 33rd percentile | |
| 524 // of 2G HTTP RTT observations on Android. | |
| 525 base::TimeDelta::FromMilliseconds(2010), | |
| 526 // Set to 1870 milliseconds, which corresponds to the 33rd percentile | |
| 527 // of 2G transport RTT observations on Android. | |
| 528 base::TimeDelta::FromMilliseconds(1870), | |
| 529 nqe::internal::kInvalidThroughput); | |
| 530 | |
| 531 default_effective_connection_type_thresholds_[EFFECTIVE_CONNECTION_TYPE_2G] = | |
| 532 nqe::internal::NetworkQuality( | |
| 533 // Set to 1420 milliseconds, which corresponds to 50th percentile of | |
| 534 // 2G | |
| 535 // HTTP RTT observations on Android. | |
| 536 base::TimeDelta::FromMilliseconds(1420), | |
| 537 // Set to 1280 milliseconds, which corresponds to 50th percentile of | |
| 538 // 2G | |
| 539 // transport RTT observations on Android. | |
| 540 base::TimeDelta::FromMilliseconds(1280), | |
| 541 nqe::internal::kInvalidThroughput); | |
| 542 | |
| 543 default_effective_connection_type_thresholds_[EFFECTIVE_CONNECTION_TYPE_3G] = | |
| 544 nqe::internal::NetworkQuality( | |
| 545 // Set to 273 milliseconds, which corresponds to 50th percentile of | |
| 546 // 3G HTTP RTT observations on Android. | |
| 547 base::TimeDelta::FromMilliseconds(273), | |
| 548 // Set to 204 milliseconds, which corresponds to 50th percentile of | |
| 549 // 3G transport RTT observations on Android. | |
| 550 base::TimeDelta::FromMilliseconds(204), | |
| 551 nqe::internal::kInvalidThroughput); | |
| 552 | |
| 553 for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) { | |
| 554 EffectiveConnectionType effective_connection_type = | |
| 555 static_cast<EffectiveConnectionType>(i); | |
| 556 DCHECK_EQ(nqe::internal::InvalidRTT(), | |
| 557 connection_thresholds_[i].http_rtt()); | |
| 558 DCHECK_EQ(nqe::internal::InvalidRTT(), | |
| 559 connection_thresholds_[i].transport_rtt()); | |
| 560 DCHECK_EQ(nqe::internal::kInvalidThroughput, | |
| 561 connection_thresholds_[i].downstream_throughput_kbps()); | |
| 562 if (effective_connection_type == EFFECTIVE_CONNECTION_TYPE_UNKNOWN) | |
| 563 continue; | |
| 564 | |
| 565 std::string connection_type_name = std::string( | |
| 566 GetNameForEffectiveConnectionType(effective_connection_type)); | |
| 567 | |
| 568 int64_t variations_value; | |
| 569 GetValueForVariationParam(variation_params, | |
| 570 connection_type_name + kThresholdURLRTTMsecSuffix, | |
| 571 default_effective_connection_type_thresholds_[i] | |
| 572 .http_rtt() | |
| 573 .InMilliseconds(), | |
| 574 &variations_value); | |
| 575 connection_thresholds_[i].set_http_rtt( | |
| 576 base::TimeDelta::FromMilliseconds(variations_value)); | |
| 577 | |
| 578 GetValueForVariationParam( | |
| 579 variation_params, | |
| 580 connection_type_name + kThresholdTransportRTTMsecSuffix, | |
| 581 default_effective_connection_type_thresholds_[i] | |
| 582 .transport_rtt() | |
| 583 .InMilliseconds(), | |
| 584 &variations_value); | |
| 585 connection_thresholds_[i].set_transport_rtt( | |
| 586 base::TimeDelta::FromMilliseconds(variations_value)); | |
| 587 | |
| 588 GetValueForVariationParam(variation_params, | |
| 589 connection_type_name + kThresholdKbpsSuffix, | |
| 590 default_effective_connection_type_thresholds_[i] | |
| 591 .downstream_throughput_kbps(), | |
| 592 &variations_value); | |
| 593 connection_thresholds_[i].set_downstream_throughput_kbps(variations_value); | |
| 594 DCHECK(i == 0 || | |
| 595 connection_thresholds_[i].IsFaster(connection_thresholds_[i - 1])); | |
| 596 } | |
| 597 } | 322 } |
| 598 | 323 |
| 599 void NetworkQualityEstimator::AddDefaultEstimates() { | 324 void NetworkQualityEstimator::AddDefaultEstimates() { |
| 600 DCHECK(thread_checker_.CalledOnValidThread()); | 325 DCHECK(thread_checker_.CalledOnValidThread()); |
| 601 | 326 |
| 602 if (default_observations_[current_network_id_.type].http_rtt() != | 327 if (default_observations_[current_network_id_.type].http_rtt() != |
| 603 nqe::internal::InvalidRTT()) { | 328 nqe::internal::InvalidRTT()) { |
| 604 RttObservation rtt_observation( | 329 RttObservation rtt_observation( |
| 605 default_observations_[current_network_id_.type].http_rtt(), | 330 default_observations_[current_network_id_.type].http_rtt(), |
| 606 tick_clock_->NowTicks(), | 331 tick_clock_->NowTicks(), |
| (...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1193 base::HistogramBase* throughput_percentile = GetHistogram( | 918 base::HistogramBase* throughput_percentile = GetHistogram( |
| 1194 "MainFrame.Kbps.Percentile50.", current_network_id_.type, 1000 * 1000); | 919 "MainFrame.Kbps.Percentile50.", current_network_id_.type, 1000 * 1000); |
| 1195 throughput_percentile->Add(kbps); | 920 throughput_percentile->Add(kbps); |
| 1196 } | 921 } |
| 1197 | 922 |
| 1198 const EffectiveConnectionType effective_connection_type = | 923 const EffectiveConnectionType effective_connection_type = |
| 1199 GetEffectiveConnectionType(); | 924 GetEffectiveConnectionType(); |
| 1200 base::HistogramBase* effective_connection_type_histogram = | 925 base::HistogramBase* effective_connection_type_histogram = |
| 1201 base::Histogram::FactoryGet( | 926 base::Histogram::FactoryGet( |
| 1202 std::string("NQE.MainFrame.EffectiveConnectionType.") + | 927 std::string("NQE.MainFrame.EffectiveConnectionType.") + |
| 1203 GetNameForConnectionType(current_network_id_.type), | 928 nqe::internal::GetNameForConnectionType(current_network_id_.type), |
| 1204 0, EFFECTIVE_CONNECTION_TYPE_LAST, | 929 0, EFFECTIVE_CONNECTION_TYPE_LAST, |
| 1205 EFFECTIVE_CONNECTION_TYPE_LAST /* Number of buckets */, | 930 EFFECTIVE_CONNECTION_TYPE_LAST /* Number of buckets */, |
| 1206 base::HistogramBase::kUmaTargetedHistogramFlag); | 931 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 1207 | 932 |
| 1208 effective_connection_type_histogram->Add(effective_connection_type); | 933 effective_connection_type_histogram->Add(effective_connection_type); |
| 1209 } | 934 } |
| 1210 | 935 |
| 1211 void NetworkQualityEstimator::ComputeEffectiveConnectionType() { | 936 void NetworkQualityEstimator::ComputeEffectiveConnectionType() { |
| 1212 DCHECK(thread_checker_.CalledOnValidThread()); | 937 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1213 | 938 |
| (...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1781 } | 1506 } |
| 1782 | 1507 |
| 1783 void NetworkQualityEstimator::RemoveNetworkQualitiesCacheObserver( | 1508 void NetworkQualityEstimator::RemoveNetworkQualitiesCacheObserver( |
| 1784 nqe::internal::NetworkQualityStore::NetworkQualitiesCacheObserver* | 1509 nqe::internal::NetworkQualityStore::NetworkQualitiesCacheObserver* |
| 1785 observer) { | 1510 observer) { |
| 1786 DCHECK(thread_checker_.CalledOnValidThread()); | 1511 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1787 network_quality_store_->RemoveNetworkQualitiesCacheObserver(observer); | 1512 network_quality_store_->RemoveNetworkQualitiesCacheObserver(observer); |
| 1788 } | 1513 } |
| 1789 | 1514 |
| 1790 } // namespace net | 1515 } // namespace net |
| OLD | NEW |