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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 133 DCHECK_GT(max_limit, kLowerLimit); | 133 DCHECK_GT(max_limit, kLowerLimit); |
| 134 const size_t kBucketCount = 50; | 134 const size_t kBucketCount = 50; |
| 135 | 135 |
| 136 // Prefix of network quality estimator histograms. | 136 // Prefix of network quality estimator histograms. |
| 137 const char prefix[] = "NQE."; | 137 const char prefix[] = "NQE."; |
| 138 return base::Histogram::FactoryGet( | 138 return base::Histogram::FactoryGet( |
| 139 prefix + statistic_name + GetNameForConnectionType(type), kLowerLimit, | 139 prefix + statistic_name + GetNameForConnectionType(type), kLowerLimit, |
| 140 max_limit, kBucketCount, base::HistogramBase::kUmaTargetedHistogramFlag); | 140 max_limit, kBucketCount, base::HistogramBase::kUmaTargetedHistogramFlag); |
| 141 } | 141 } |
| 142 | 142 |
| 143 bool GetValueForVariationParam( | 143 // Sets |variations_value| to the value of |parameter_name| read from |
| 144 // |variation_params|. If the value is unavailable from |variation_params|, then | |
| 145 // |variations_value| is set to |default_value|. | |
| 146 void GetValueForVariationParam( | |
| 144 const std::map<std::string, std::string>& variation_params, | 147 const std::map<std::string, std::string>& variation_params, |
| 145 const std::string& parameter_name, | 148 const std::string& parameter_name, |
| 146 int32_t* variations_value) { | 149 int64_t default_value, |
| 150 int64_t* variations_value) { | |
| 147 const auto it = variation_params.find(parameter_name); | 151 const auto it = variation_params.find(parameter_name); |
| 148 return it != variation_params.end() && | 152 if (it != variation_params.end() && |
| 149 base::StringToInt(it->second, variations_value); | 153 base::StringToInt64(it->second, variations_value)) { |
| 154 return; | |
| 155 } | |
| 156 *variations_value = default_value; | |
| 150 } | 157 } |
| 151 | 158 |
| 152 // Returns the algorithm that should be used for computing effective connection | 159 // Returns the algorithm that should be used for computing effective connection |
| 153 // type based on field trial params. Returns an empty string if a valid | 160 // type based on field trial params. Returns an empty string if a valid |
| 154 // algorithm paramter is not present in the field trial params. | 161 // algorithm paramter is not present in the field trial params. |
| 155 std::string GetEffectiveConnectionTypeAlgorithm( | 162 std::string GetEffectiveConnectionTypeAlgorithm( |
| 156 const std::map<std::string, std::string>& variation_params) { | 163 const std::map<std::string, std::string>& variation_params) { |
| 157 const auto it = variation_params.find("effective_connection_type_algorithm"); | 164 const auto it = variation_params.find("effective_connection_type_algorithm"); |
| 158 if (it == variation_params.end()) | 165 if (it == variation_params.end()) |
| 159 return std::string(); | 166 return std::string(); |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 359 default_observations_[i].http_rtt(), | 366 default_observations_[i].http_rtt(), |
| 360 default_observations_[i].transport_rtt(), variations_value); | 367 default_observations_[i].transport_rtt(), variations_value); |
| 361 } | 368 } |
| 362 } | 369 } |
| 363 } | 370 } |
| 364 | 371 |
| 365 void NetworkQualityEstimator::ObtainEffectiveConnectionTypeModelParams( | 372 void NetworkQualityEstimator::ObtainEffectiveConnectionTypeModelParams( |
| 366 const std::map<std::string, std::string>& variation_params) { | 373 const std::map<std::string, std::string>& variation_params) { |
| 367 DCHECK(thread_checker_.CalledOnValidThread()); | 374 DCHECK(thread_checker_.CalledOnValidThread()); |
| 368 | 375 |
| 376 default_ect_thresholds_[EFFECTIVE_CONNECTION_TYPE_SLOW_2G] = | |
| 377 nqe::internal::NetworkQuality( | |
| 378 // Set to 2010 milliseconds which corresponds to the 33rd percentile | |
| 379 // of 2G HTTP RTT observations on Android. | |
| 380 base::TimeDelta::FromMilliseconds(2010), | |
| 381 // Set to 1870 milliseconds which corresponds to the below 33rd | |
|
RyanSturm
2016/07/22 21:01:16
s/the below 33rd/the 33rd/
tbansal1
2016/07/22 21:35:50
Done.
| |
| 382 // percentile of 2G transport RTT observations on Android. | |
| 383 base::TimeDelta::FromMilliseconds(1870), | |
| 384 nqe::internal::kInvalidThroughput); | |
| 385 | |
| 386 default_ect_thresholds_[EFFECTIVE_CONNECTION_TYPE_2G] = | |
| 387 nqe::internal::NetworkQuality( | |
| 388 // Set to 1420 milliseconds which corresponds to 50th percentile of 2G | |
| 389 // HTTP RTT observations on Android. | |
| 390 base::TimeDelta::FromMilliseconds(1420), | |
| 391 // Set to 1280 milliseconds which corresponds to 50th percentile of 2G | |
| 392 // transport RTT observations on Android. | |
| 393 base::TimeDelta::FromMilliseconds(1280), | |
| 394 nqe::internal::kInvalidThroughput); | |
| 395 | |
| 369 for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) { | 396 for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) { |
| 370 EffectiveConnectionType effective_connection_type = | 397 EffectiveConnectionType effective_connection_type = |
| 371 static_cast<EffectiveConnectionType>(i); | 398 static_cast<EffectiveConnectionType>(i); |
| 372 DCHECK_EQ(nqe::internal::InvalidRTT(), | 399 DCHECK_EQ(nqe::internal::InvalidRTT(), |
| 373 connection_thresholds_[i].http_rtt()); | 400 connection_thresholds_[i].http_rtt()); |
| 374 DCHECK_EQ(nqe::internal::InvalidRTT(), | 401 DCHECK_EQ(nqe::internal::InvalidRTT(), |
| 375 connection_thresholds_[i].transport_rtt()); | 402 connection_thresholds_[i].transport_rtt()); |
| 376 DCHECK_EQ(nqe::internal::kInvalidThroughput, | 403 DCHECK_EQ(nqe::internal::kInvalidThroughput, |
| 377 connection_thresholds_[i].downstream_throughput_kbps()); | 404 connection_thresholds_[i].downstream_throughput_kbps()); |
| 378 if (effective_connection_type == EFFECTIVE_CONNECTION_TYPE_UNKNOWN) | 405 if (effective_connection_type == EFFECTIVE_CONNECTION_TYPE_UNKNOWN) |
| 379 continue; | 406 continue; |
| 380 | 407 |
| 381 std::string connection_type_name = std::string( | 408 std::string connection_type_name = std::string( |
| 382 GetNameForEffectiveConnectionType(effective_connection_type)); | 409 GetNameForEffectiveConnectionType(effective_connection_type)); |
| 383 | 410 |
| 384 int32_t variations_value = kMinimumRTTVariationParameterMsec - 1; | 411 int64_t variations_value; |
| 385 if (GetValueForVariationParam( | 412 GetValueForVariationParam( |
| 386 variation_params, connection_type_name + kThresholdURLRTTMsecSuffix, | 413 variation_params, connection_type_name + kThresholdURLRTTMsecSuffix, |
| 387 &variations_value) && | 414 default_ect_thresholds_[i].http_rtt().InMilliseconds(), |
| 388 variations_value >= kMinimumRTTVariationParameterMsec) { | 415 &variations_value); |
| 389 connection_thresholds_[i].set_http_rtt( | 416 connection_thresholds_[i].set_http_rtt( |
| 390 base::TimeDelta(base::TimeDelta::FromMilliseconds(variations_value))); | 417 base::TimeDelta(base::TimeDelta::FromMilliseconds(variations_value))); |
|
RyanSturm
2016/07/22 21:01:16
Why are you constructing a TimeDelta from a TimeDe
tbansal1
2016/07/22 21:35:50
Done.
| |
| 418 // Verify that the RTT values are in decreasing order as the network | |
| 419 // quality improves. | |
| 420 DCHECK(i == 0 || | |
| 421 connection_thresholds_[i].http_rtt() == | |
| 422 nqe::internal::InvalidRTT() || | |
| 423 connection_thresholds_[i - 1].http_rtt() == | |
| 424 nqe::internal::InvalidRTT() || | |
| 425 connection_thresholds_[i].http_rtt() <= | |
| 426 connection_thresholds_[i - 1].http_rtt()); | |
| 391 | 427 |
| 392 // Verify that the RTT values are in decreasing order as the network | 428 GetValueForVariationParam( |
| 393 // quality improves. | 429 variation_params, |
| 394 DCHECK(i == 0 || | 430 connection_type_name + kThresholdTransportRTTMsecSuffix, |
| 395 connection_thresholds_[i - 1].http_rtt() == | 431 default_ect_thresholds_[i].transport_rtt().InMilliseconds(), |
| 396 nqe::internal::InvalidRTT() || | 432 &variations_value); |
| 397 connection_thresholds_[i].http_rtt() <= | 433 connection_thresholds_[i].set_transport_rtt( |
| 398 connection_thresholds_[i - 1].http_rtt()); | 434 base::TimeDelta(base::TimeDelta::FromMilliseconds(variations_value))); |
| 399 } | 435 // Verify that the transport RTT values are in decreasing order as the |
| 436 // network quality improves. | |
| 437 DCHECK(i == 0 || | |
| 438 connection_thresholds_[i].transport_rtt() == | |
| 439 nqe::internal::InvalidRTT() || | |
| 440 connection_thresholds_[i - 1].transport_rtt() == | |
| 441 nqe::internal::InvalidRTT() || | |
| 442 connection_thresholds_[i].transport_rtt() <= | |
| 443 connection_thresholds_[i - 1].transport_rtt()); | |
| 400 | 444 |
| 401 variations_value = kMinimumRTTVariationParameterMsec - 1; | 445 GetValueForVariationParam( |
| 402 if (GetValueForVariationParam( | 446 variation_params, connection_type_name + kThresholdKbpsSuffix, |
| 403 variation_params, | 447 default_ect_thresholds_[i].downstream_throughput_kbps(), |
| 404 connection_type_name + kThresholdTransportRTTMsecSuffix, | 448 &variations_value); |
| 405 &variations_value) && | 449 connection_thresholds_[i].set_downstream_throughput_kbps(variations_value); |
| 406 variations_value >= kMinimumRTTVariationParameterMsec) { | 450 // Verify that the throughput values are in increasing order as the |
| 407 connection_thresholds_[i].set_transport_rtt( | 451 // network quality improves. |
| 408 base::TimeDelta(base::TimeDelta::FromMilliseconds(variations_value))); | 452 DCHECK(i == 0 || |
| 409 | 453 connection_thresholds_[i].downstream_throughput_kbps() == |
| 410 // Verify that the transport RTT values are in decreasing order as the | 454 kMinimumThroughputVariationParameterKbps || |
| 411 // network quality improves. | 455 connection_thresholds_[i - 1].downstream_throughput_kbps() == |
| 412 DCHECK(i == 0 || | 456 kMinimumThroughputVariationParameterKbps || |
| 413 connection_thresholds_[i - 1].transport_rtt() == | 457 connection_thresholds_[i].downstream_throughput_kbps() >= |
| 414 nqe::internal::InvalidRTT() || | 458 connection_thresholds_[i - 1].downstream_throughput_kbps()); |
| 415 connection_thresholds_[i].transport_rtt() <= | |
| 416 connection_thresholds_[i - 1].transport_rtt()); | |
| 417 } | |
| 418 | |
| 419 variations_value = kMinimumThroughputVariationParameterKbps - 1; | |
| 420 if (GetValueForVariationParam(variation_params, | |
| 421 connection_type_name + kThresholdKbpsSuffix, | |
| 422 &variations_value) && | |
| 423 variations_value >= kMinimumThroughputVariationParameterKbps) { | |
| 424 connection_thresholds_[i].set_downstream_throughput_kbps( | |
| 425 variations_value); | |
| 426 | |
| 427 // Verify that the throughput values are in increasing order as the | |
| 428 // network quality improves. | |
| 429 DCHECK(i == 0 || | |
| 430 connection_thresholds_[i - 1].downstream_throughput_kbps() == | |
| 431 kMinimumThroughputVariationParameterKbps || | |
| 432 connection_thresholds_[i].downstream_throughput_kbps() >= | |
| 433 connection_thresholds_[i - 1].downstream_throughput_kbps()); | |
| 434 } | |
| 435 } | 459 } |
| 436 } | 460 } |
| 437 | 461 |
| 438 void NetworkQualityEstimator::AddDefaultEstimates() { | 462 void NetworkQualityEstimator::AddDefaultEstimates() { |
| 439 DCHECK(thread_checker_.CalledOnValidThread()); | 463 DCHECK(thread_checker_.CalledOnValidThread()); |
| 440 | 464 |
| 441 if (default_observations_[current_network_id_.type].http_rtt() != | 465 if (default_observations_[current_network_id_.type].http_rtt() != |
| 442 nqe::internal::InvalidRTT()) { | 466 nqe::internal::InvalidRTT()) { |
| 443 RttObservation rtt_observation( | 467 RttObservation rtt_observation( |
| 444 default_observations_[current_network_id_.type].http_rtt(), | 468 default_observations_[current_network_id_.type].http_rtt(), |
| (...skipping 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1492 NotifyObserversOfEffectiveConnectionTypeChanged() { | 1516 NotifyObserversOfEffectiveConnectionTypeChanged() { |
| 1493 DCHECK(thread_checker_.CalledOnValidThread()); | 1517 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1494 | 1518 |
| 1495 // TODO(tbansal): Add hysteresis in the notification. | 1519 // TODO(tbansal): Add hysteresis in the notification. |
| 1496 FOR_EACH_OBSERVER( | 1520 FOR_EACH_OBSERVER( |
| 1497 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, | 1521 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, |
| 1498 OnEffectiveConnectionTypeChanged(effective_connection_type_)); | 1522 OnEffectiveConnectionTypeChanged(effective_connection_type_)); |
| 1499 } | 1523 } |
| 1500 | 1524 |
| 1501 } // namespace net | 1525 } // namespace net |
| OLD | NEW |