| 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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 DCHECK_GT(max_limit, kLowerLimit); | 138 DCHECK_GT(max_limit, kLowerLimit); |
| 139 const size_t kBucketCount = 50; | 139 const size_t kBucketCount = 50; |
| 140 | 140 |
| 141 // Prefix of network quality estimator histograms. | 141 // Prefix of network quality estimator histograms. |
| 142 const char prefix[] = "NQE."; | 142 const char prefix[] = "NQE."; |
| 143 return base::Histogram::FactoryGet( | 143 return base::Histogram::FactoryGet( |
| 144 prefix + statistic_name + GetNameForConnectionType(type), kLowerLimit, | 144 prefix + statistic_name + GetNameForConnectionType(type), kLowerLimit, |
| 145 max_limit, kBucketCount, base::HistogramBase::kUmaTargetedHistogramFlag); | 145 max_limit, kBucketCount, base::HistogramBase::kUmaTargetedHistogramFlag); |
| 146 } | 146 } |
| 147 | 147 |
| 148 bool GetValueForVariationParam( | 148 // Sets |variations_value| to the value of |parameter_name| read from |
| 149 // |variation_params|. If the value is unavailable from |variation_params|, then |
| 150 // |variations_value| is set to |default_value|. |
| 151 void GetValueForVariationParam( |
| 149 const std::map<std::string, std::string>& variation_params, | 152 const std::map<std::string, std::string>& variation_params, |
| 150 const std::string& parameter_name, | 153 const std::string& parameter_name, |
| 151 int32_t* variations_value) { | 154 int64_t default_value, |
| 155 int64_t* variations_value) { |
| 152 const auto it = variation_params.find(parameter_name); | 156 const auto it = variation_params.find(parameter_name); |
| 153 return it != variation_params.end() && | 157 if (it != variation_params.end() && |
| 154 base::StringToInt(it->second, variations_value); | 158 base::StringToInt64(it->second, variations_value)) { |
| 159 return; |
| 160 } |
| 161 *variations_value = default_value; |
| 155 } | 162 } |
| 156 | 163 |
| 157 // Returns the variation value for |parameter_name|. If the value is | 164 // Returns the variation value for |parameter_name|. If the value is |
| 158 // unavailable, |default_value| is returned. | 165 // unavailable, |default_value| is returned. |
| 159 double GetDoubleValueForVariationParamWithDefaultValue( | 166 double GetDoubleValueForVariationParamWithDefaultValue( |
| 160 const std::map<std::string, std::string>& variation_params, | 167 const std::map<std::string, std::string>& variation_params, |
| 161 const std::string& parameter_name, | 168 const std::string& parameter_name, |
| 162 double default_value) { | 169 double default_value) { |
| 163 const auto it = variation_params.find(parameter_name); | 170 const auto it = variation_params.find(parameter_name); |
| 164 if (it == variation_params.end()) | 171 if (it == variation_params.end()) |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 default_observations_[i].http_rtt(), | 475 default_observations_[i].http_rtt(), |
| 469 default_observations_[i].transport_rtt(), variations_value); | 476 default_observations_[i].transport_rtt(), variations_value); |
| 470 } | 477 } |
| 471 } | 478 } |
| 472 } | 479 } |
| 473 | 480 |
| 474 void NetworkQualityEstimator::ObtainEffectiveConnectionTypeModelParams( | 481 void NetworkQualityEstimator::ObtainEffectiveConnectionTypeModelParams( |
| 475 const std::map<std::string, std::string>& variation_params) { | 482 const std::map<std::string, std::string>& variation_params) { |
| 476 DCHECK(thread_checker_.CalledOnValidThread()); | 483 DCHECK(thread_checker_.CalledOnValidThread()); |
| 477 | 484 |
| 485 default_effective_connection_type_thresholds_ |
| 486 [EFFECTIVE_CONNECTION_TYPE_SLOW_2G] = nqe::internal::NetworkQuality( |
| 487 // Set to 2010 milliseconds, which corresponds to the 33rd percentile |
| 488 // of 2G HTTP RTT observations on Android. |
| 489 base::TimeDelta::FromMilliseconds(2010), |
| 490 // Set to 1870 milliseconds, which corresponds to the 33rd percentile |
| 491 // of 2G transport RTT observations on Android. |
| 492 base::TimeDelta::FromMilliseconds(1870), |
| 493 nqe::internal::kInvalidThroughput); |
| 494 |
| 495 default_effective_connection_type_thresholds_[EFFECTIVE_CONNECTION_TYPE_2G] = |
| 496 nqe::internal::NetworkQuality( |
| 497 // Set to 1420 milliseconds, which corresponds to 50th percentile of |
| 498 // 2G |
| 499 // HTTP RTT observations on Android. |
| 500 base::TimeDelta::FromMilliseconds(1420), |
| 501 // Set to 1280 milliseconds, which corresponds to 50th percentile of |
| 502 // 2G |
| 503 // transport RTT observations on Android. |
| 504 base::TimeDelta::FromMilliseconds(1280), |
| 505 nqe::internal::kInvalidThroughput); |
| 506 |
| 478 for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) { | 507 for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) { |
| 479 EffectiveConnectionType effective_connection_type = | 508 EffectiveConnectionType effective_connection_type = |
| 480 static_cast<EffectiveConnectionType>(i); | 509 static_cast<EffectiveConnectionType>(i); |
| 481 DCHECK_EQ(nqe::internal::InvalidRTT(), | 510 DCHECK_EQ(nqe::internal::InvalidRTT(), |
| 482 connection_thresholds_[i].http_rtt()); | 511 connection_thresholds_[i].http_rtt()); |
| 483 DCHECK_EQ(nqe::internal::InvalidRTT(), | 512 DCHECK_EQ(nqe::internal::InvalidRTT(), |
| 484 connection_thresholds_[i].transport_rtt()); | 513 connection_thresholds_[i].transport_rtt()); |
| 485 DCHECK_EQ(nqe::internal::kInvalidThroughput, | 514 DCHECK_EQ(nqe::internal::kInvalidThroughput, |
| 486 connection_thresholds_[i].downstream_throughput_kbps()); | 515 connection_thresholds_[i].downstream_throughput_kbps()); |
| 487 if (effective_connection_type == EFFECTIVE_CONNECTION_TYPE_UNKNOWN) | 516 if (effective_connection_type == EFFECTIVE_CONNECTION_TYPE_UNKNOWN) |
| 488 continue; | 517 continue; |
| 489 | 518 |
| 490 std::string connection_type_name = std::string( | 519 std::string connection_type_name = std::string( |
| 491 GetNameForEffectiveConnectionType(effective_connection_type)); | 520 GetNameForEffectiveConnectionType(effective_connection_type)); |
| 492 | 521 |
| 493 int32_t variations_value = kMinimumRTTVariationParameterMsec - 1; | 522 int64_t variations_value; |
| 494 if (GetValueForVariationParam( | 523 GetValueForVariationParam(variation_params, |
| 495 variation_params, connection_type_name + kThresholdURLRTTMsecSuffix, | 524 connection_type_name + kThresholdURLRTTMsecSuffix, |
| 496 &variations_value) && | 525 default_effective_connection_type_thresholds_[i] |
| 497 variations_value >= kMinimumRTTVariationParameterMsec) { | 526 .http_rtt() |
| 498 connection_thresholds_[i].set_http_rtt( | 527 .InMilliseconds(), |
| 499 base::TimeDelta(base::TimeDelta::FromMilliseconds(variations_value))); | 528 &variations_value); |
| 529 connection_thresholds_[i].set_http_rtt( |
| 530 base::TimeDelta::FromMilliseconds(variations_value)); |
| 500 | 531 |
| 501 // Verify that the RTT values are in decreasing order as the network | 532 GetValueForVariationParam( |
| 502 // quality improves. | 533 variation_params, |
| 503 DCHECK(i == 0 || | 534 connection_type_name + kThresholdTransportRTTMsecSuffix, |
| 504 connection_thresholds_[i - 1].http_rtt() == | 535 default_effective_connection_type_thresholds_[i] |
| 505 nqe::internal::InvalidRTT() || | 536 .transport_rtt() |
| 506 connection_thresholds_[i].http_rtt() <= | 537 .InMilliseconds(), |
| 507 connection_thresholds_[i - 1].http_rtt()); | 538 &variations_value); |
| 508 } | 539 connection_thresholds_[i].set_transport_rtt( |
| 540 base::TimeDelta::FromMilliseconds(variations_value)); |
| 509 | 541 |
| 510 variations_value = kMinimumRTTVariationParameterMsec - 1; | 542 GetValueForVariationParam(variation_params, |
| 511 if (GetValueForVariationParam( | 543 connection_type_name + kThresholdKbpsSuffix, |
| 512 variation_params, | 544 default_effective_connection_type_thresholds_[i] |
| 513 connection_type_name + kThresholdTransportRTTMsecSuffix, | 545 .downstream_throughput_kbps(), |
| 514 &variations_value) && | 546 &variations_value); |
| 515 variations_value >= kMinimumRTTVariationParameterMsec) { | 547 connection_thresholds_[i].set_downstream_throughput_kbps(variations_value); |
| 516 connection_thresholds_[i].set_transport_rtt( | 548 DCHECK(i == 0 || |
| 517 base::TimeDelta(base::TimeDelta::FromMilliseconds(variations_value))); | 549 connection_thresholds_[i].IsFaster(connection_thresholds_[i - 1])); |
| 518 | |
| 519 // Verify that the transport RTT values are in decreasing order as the | |
| 520 // network quality improves. | |
| 521 DCHECK(i == 0 || | |
| 522 connection_thresholds_[i - 1].transport_rtt() == | |
| 523 nqe::internal::InvalidRTT() || | |
| 524 connection_thresholds_[i].transport_rtt() <= | |
| 525 connection_thresholds_[i - 1].transport_rtt()); | |
| 526 } | |
| 527 | |
| 528 variations_value = kMinimumThroughputVariationParameterKbps - 1; | |
| 529 if (GetValueForVariationParam(variation_params, | |
| 530 connection_type_name + kThresholdKbpsSuffix, | |
| 531 &variations_value) && | |
| 532 variations_value >= kMinimumThroughputVariationParameterKbps) { | |
| 533 connection_thresholds_[i].set_downstream_throughput_kbps( | |
| 534 variations_value); | |
| 535 | |
| 536 // Verify that the throughput values are in increasing order as the | |
| 537 // network quality improves. | |
| 538 DCHECK(i == 0 || | |
| 539 connection_thresholds_[i - 1].downstream_throughput_kbps() == | |
| 540 kMinimumThroughputVariationParameterKbps || | |
| 541 connection_thresholds_[i].downstream_throughput_kbps() >= | |
| 542 connection_thresholds_[i - 1].downstream_throughput_kbps()); | |
| 543 } | |
| 544 } | 550 } |
| 545 } | 551 } |
| 546 | 552 |
| 547 void NetworkQualityEstimator::AddDefaultEstimates() { | 553 void NetworkQualityEstimator::AddDefaultEstimates() { |
| 548 DCHECK(thread_checker_.CalledOnValidThread()); | 554 DCHECK(thread_checker_.CalledOnValidThread()); |
| 549 | 555 |
| 550 if (default_observations_[current_network_id_.type].http_rtt() != | 556 if (default_observations_[current_network_id_.type].http_rtt() != |
| 551 nqe::internal::InvalidRTT()) { | 557 nqe::internal::InvalidRTT()) { |
| 552 RttObservation rtt_observation( | 558 RttObservation rtt_observation( |
| 553 default_observations_[current_network_id_.type].http_rtt(), | 559 default_observations_[current_network_id_.type].http_rtt(), |
| (...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1659 NotifyObserversOfEffectiveConnectionTypeChanged() { | 1665 NotifyObserversOfEffectiveConnectionTypeChanged() { |
| 1660 DCHECK(thread_checker_.CalledOnValidThread()); | 1666 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1661 | 1667 |
| 1662 // TODO(tbansal): Add hysteresis in the notification. | 1668 // TODO(tbansal): Add hysteresis in the notification. |
| 1663 FOR_EACH_OBSERVER( | 1669 FOR_EACH_OBSERVER( |
| 1664 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, | 1670 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, |
| 1665 OnEffectiveConnectionTypeChanged(effective_connection_type_)); | 1671 OnEffectiveConnectionTypeChanged(effective_connection_type_)); |
| 1666 } | 1672 } |
| 1667 | 1673 |
| 1668 } // namespace net | 1674 } // namespace net |
| OLD | NEW |