| 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 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 "TransportRTT.Percentile" + base::IntToString(kPercentiles[i]) + ".", | 693 "TransportRTT.Percentile" + base::IntToString(kPercentiles[i]) + ".", |
| 694 current_network_id_.type, 10 * 1000); // 10 seconds | 694 current_network_id_.type, 10 * 1000); // 10 seconds |
| 695 transport_rtt_percentile->Add(rtt.InMilliseconds()); | 695 transport_rtt_percentile->Add(rtt.InMilliseconds()); |
| 696 } | 696 } |
| 697 } | 697 } |
| 698 } | 698 } |
| 699 | 699 |
| 700 NetworkQualityEstimator::EffectiveConnectionType | 700 NetworkQualityEstimator::EffectiveConnectionType |
| 701 NetworkQualityEstimator::GetEffectiveConnectionType() const { | 701 NetworkQualityEstimator::GetEffectiveConnectionType() const { |
| 702 DCHECK(thread_checker_.CalledOnValidThread()); | 702 DCHECK(thread_checker_.CalledOnValidThread()); |
| 703 return GetRecentEffectiveConnectionType(base::TimeTicks()); |
| 704 } |
| 705 |
| 706 NetworkQualityEstimator::EffectiveConnectionType |
| 707 NetworkQualityEstimator::GetRecentEffectiveConnectionType( |
| 708 const base::TimeTicks& start_time) const { |
| 709 DCHECK(thread_checker_.CalledOnValidThread()); |
| 703 | 710 |
| 704 // If the device is currently offline, then return | 711 // If the device is currently offline, then return |
| 705 // EFFECTIVE_CONNECTION_TYPE_OFFLINE. | 712 // EFFECTIVE_CONNECTION_TYPE_OFFLINE. |
| 706 if (GetCurrentNetworkID().type == NetworkChangeNotifier::CONNECTION_NONE) | 713 if (GetCurrentNetworkID().type == NetworkChangeNotifier::CONNECTION_NONE) |
| 707 return EFFECTIVE_CONNECTION_TYPE_OFFLINE; | 714 return EFFECTIVE_CONNECTION_TYPE_OFFLINE; |
| 708 | 715 |
| 709 base::TimeDelta http_rtt = nqe::internal::InvalidRTT(); | 716 base::TimeDelta http_rtt = nqe::internal::InvalidRTT(); |
| 710 if (!GetHttpRTTEstimate(&http_rtt)) | 717 if (!GetRecentHttpRTTMedian(start_time, &http_rtt)) |
| 711 http_rtt = nqe::internal::InvalidRTT(); | 718 http_rtt = nqe::internal::InvalidRTT(); |
| 712 | 719 |
| 713 int32_t kbps = nqe::internal::kInvalidThroughput; | 720 int32_t kbps = nqe::internal::kInvalidThroughput; |
| 714 if (!GetDownlinkThroughputKbpsEstimate(&kbps)) | 721 if (!GetRecentMedianDownlinkThroughputKbps(start_time, &kbps)) |
| 715 kbps = nqe::internal::kInvalidThroughput; | 722 kbps = nqe::internal::kInvalidThroughput; |
| 716 | 723 |
| 717 if (http_rtt == nqe::internal::InvalidRTT() && | 724 if (http_rtt == nqe::internal::InvalidRTT() && |
| 718 kbps == nqe::internal::kInvalidThroughput) { | 725 kbps == nqe::internal::kInvalidThroughput) { |
| 719 // Quality of the current network is unknown. | 726 // Quality of the current network is unknown. |
| 720 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; | 727 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; |
| 721 } | 728 } |
| 722 | 729 |
| 723 // Search from the slowest connection type to the fastest to find the | 730 // Search from the slowest connection type to the fastest to find the |
| 724 // EffectiveConnectionType that best matches the current connection's | 731 // EffectiveConnectionType that best matches the current connection's |
| 725 // performance. The match is done by comparing RTT and throughput. | 732 // performance. The match is done by comparing RTT and throughput. |
| 726 for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) { | 733 for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) { |
| 727 EffectiveConnectionType type = static_cast<EffectiveConnectionType>(i); | 734 EffectiveConnectionType type = static_cast<EffectiveConnectionType>(i); |
| 728 if (i == EFFECTIVE_CONNECTION_TYPE_UNKNOWN) | 735 if (i == EFFECTIVE_CONNECTION_TYPE_UNKNOWN) |
| 729 continue; | 736 continue; |
| 730 bool estimated_http_rtt_is_higher_than_threshold = | 737 bool estimated_http_rtt_is_higher_than_threshold = |
| 731 http_rtt != nqe::internal::InvalidRTT() && | 738 http_rtt != nqe::internal::InvalidRTT() && |
| 732 connection_thresholds_[i].http_rtt() != nqe::internal::InvalidRTT() && | 739 connection_thresholds_[i].http_rtt() != nqe::internal::InvalidRTT() && |
| 733 http_rtt >= connection_thresholds_[i].http_rtt(); | 740 http_rtt >= connection_thresholds_[i].http_rtt(); |
| 734 bool estimated_throughput_is_lower_than_threshold = | 741 bool estimated_throughput_is_lower_than_threshold = |
| 735 kbps != nqe::internal::kInvalidThroughput && | 742 kbps != nqe::internal::kInvalidThroughput && |
| 736 connection_thresholds_[i].downstream_throughput_kbps() != | 743 connection_thresholds_[i].downstream_throughput_kbps() != |
| 737 nqe::internal::kInvalidThroughput && | 744 nqe::internal::kInvalidThroughput && |
| 738 kbps <= connection_thresholds_[i].downstream_throughput_kbps(); | 745 kbps <= connection_thresholds_[i].downstream_throughput_kbps(); |
| 746 |
| 739 // Return |type| as the effective connection type if the current network's | 747 // Return |type| as the effective connection type if the current network's |
| 740 // RTT is worse than the threshold RTT for |type|, or if the current | 748 // RTT is worse than the threshold RTT for |type|, or if the current |
| 741 // network's throughput is lower than the threshold throughput for |type|. | 749 // network's throughput is lower than the threshold throughput for |type|. |
| 742 if (estimated_http_rtt_is_higher_than_threshold || | 750 if (estimated_http_rtt_is_higher_than_threshold || |
| 743 estimated_throughput_is_lower_than_threshold) { | 751 estimated_throughput_is_lower_than_threshold) { |
| 744 return type; | 752 return type; |
| 745 } | 753 } |
| 746 } | 754 } |
| 747 // Return the fastest connection type. | 755 // Return the fastest connection type. |
| 748 return static_cast<EffectiveConnectionType>(EFFECTIVE_CONNECTION_TYPE_LAST - | 756 return static_cast<EffectiveConnectionType>(EFFECTIVE_CONNECTION_TYPE_LAST - |
| 749 1); | 757 1); |
| 750 } | 758 } |
| 751 | 759 |
| 752 bool NetworkQualityEstimator::GetHttpRTTEstimate(base::TimeDelta* rtt) const { | 760 bool NetworkQualityEstimator::GetHttpRTTEstimate(base::TimeDelta* rtt) const { |
| 753 DCHECK(thread_checker_.CalledOnValidThread()); | 761 DCHECK(thread_checker_.CalledOnValidThread()); |
| 754 std::vector<NetworkQualityObservationSource> disallowed_observation_sources; | 762 return GetRecentHttpRTTMedian(base::TimeTicks(), rtt); |
| 755 disallowed_observation_sources.push_back( | |
| 756 NETWORK_QUALITY_OBSERVATION_SOURCE_TCP); | |
| 757 disallowed_observation_sources.push_back( | |
| 758 NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC); | |
| 759 *rtt = GetRTTEstimateInternal(disallowed_observation_sources, | |
| 760 base::TimeTicks(), 50); | |
| 761 return (*rtt != nqe::internal::InvalidRTT()); | |
| 762 } | 763 } |
| 763 | 764 |
| 764 bool NetworkQualityEstimator::GetTransportRTTEstimate( | 765 bool NetworkQualityEstimator::GetTransportRTTEstimate( |
| 765 base::TimeDelta* rtt) const { | 766 base::TimeDelta* rtt) const { |
| 766 DCHECK(thread_checker_.CalledOnValidThread()); | 767 DCHECK(thread_checker_.CalledOnValidThread()); |
| 767 std::vector<NetworkQualityObservationSource> disallowed_observation_sources; | 768 return GetRecentTransportRTTMedian(base::TimeTicks(), rtt); |
| 768 disallowed_observation_sources.push_back( | |
| 769 NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST); | |
| 770 // Disallow external estimate provider since it provides RTT at HTTP layer. | |
| 771 disallowed_observation_sources.push_back( | |
| 772 NETWORK_QUALITY_OBSERVATION_SOURCE_EXTERNAL_ESTIMATE); | |
| 773 disallowed_observation_sources.push_back( | |
| 774 NETWORK_QUALITY_OBSERVATION_SOURCE_CACHED_ESTIMATE); | |
| 775 disallowed_observation_sources.push_back( | |
| 776 NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_FROM_PLATFORM); | |
| 777 | |
| 778 *rtt = GetRTTEstimateInternal(disallowed_observation_sources, | |
| 779 base::TimeTicks(), 50); | |
| 780 return (*rtt != nqe::internal::InvalidRTT()); | |
| 781 } | 769 } |
| 782 | 770 |
| 783 bool NetworkQualityEstimator::GetDownlinkThroughputKbpsEstimate( | 771 bool NetworkQualityEstimator::GetDownlinkThroughputKbpsEstimate( |
| 784 int32_t* kbps) const { | 772 int32_t* kbps) const { |
| 785 DCHECK(thread_checker_.CalledOnValidThread()); | 773 DCHECK(thread_checker_.CalledOnValidThread()); |
| 786 *kbps = GetDownlinkThroughputKbpsEstimateInternal(base::TimeTicks(), 50); | 774 return GetRecentMedianDownlinkThroughputKbps(base::TimeTicks(), kbps); |
| 787 return (*kbps != nqe::internal::kInvalidThroughput); | |
| 788 } | 775 } |
| 789 | 776 |
| 790 bool NetworkQualityEstimator::GetRecentHttpRTTMedian( | 777 bool NetworkQualityEstimator::GetRecentHttpRTTMedian( |
| 791 const base::TimeTicks& start_time, | 778 const base::TimeTicks& start_time, |
| 792 base::TimeDelta* rtt) const { | 779 base::TimeDelta* rtt) const { |
| 793 DCHECK(thread_checker_.CalledOnValidThread()); | 780 DCHECK(thread_checker_.CalledOnValidThread()); |
| 794 std::vector<NetworkQualityObservationSource> disallowed_observation_sources; | 781 std::vector<NetworkQualityObservationSource> disallowed_observation_sources; |
| 795 disallowed_observation_sources.push_back( | 782 disallowed_observation_sources.push_back( |
| 796 NETWORK_QUALITY_OBSERVATION_SOURCE_TCP); | 783 NETWORK_QUALITY_OBSERVATION_SOURCE_TCP); |
| 797 disallowed_observation_sources.push_back( | 784 disallowed_observation_sources.push_back( |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1126 } | 1113 } |
| 1127 ThroughputObservation throughput_observation( | 1114 ThroughputObservation throughput_observation( |
| 1128 downstream_kbps, base::TimeTicks::Now(), | 1115 downstream_kbps, base::TimeTicks::Now(), |
| 1129 NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST); | 1116 NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST); |
| 1130 downstream_throughput_kbps_observations_.AddObservation( | 1117 downstream_throughput_kbps_observations_.AddObservation( |
| 1131 throughput_observation); | 1118 throughput_observation); |
| 1132 NotifyObserversOfThroughput(throughput_observation); | 1119 NotifyObserversOfThroughput(throughput_observation); |
| 1133 } | 1120 } |
| 1134 | 1121 |
| 1135 } // namespace net | 1122 } // namespace net |
| OLD | NEW |