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> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/bind_helpers.h" | 13 #include "base/bind_helpers.h" |
14 #include "base/location.h" | 14 #include "base/location.h" |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
16 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
17 #include "base/metrics/histogram_base.h" | 17 #include "base/metrics/histogram_base.h" |
| 18 #include "base/metrics/sparse_histogram.h" |
| 19 #include "base/rand_util.h" |
18 #include "base/single_thread_task_runner.h" | 20 #include "base/single_thread_task_runner.h" |
19 #include "base/strings/string_number_conversions.h" | 21 #include "base/strings/string_number_conversions.h" |
20 #include "base/threading/thread_task_runner_handle.h" | 22 #include "base/threading/thread_task_runner_handle.h" |
21 #include "base/time/default_tick_clock.h" | 23 #include "base/time/default_tick_clock.h" |
22 #include "base/trace_event/trace_event.h" | 24 #include "base/trace_event/trace_event.h" |
23 #include "build/build_config.h" | 25 #include "build/build_config.h" |
24 #include "net/base/load_flags.h" | 26 #include "net/base/load_flags.h" |
25 #include "net/base/load_timing_info.h" | 27 #include "net/base/load_timing_info.h" |
26 #include "net/base/network_interfaces.h" | 28 #include "net/base/network_interfaces.h" |
27 #include "net/base/url_util.h" | 29 #include "net/base/url_util.h" |
| 30 #include "net/http/http_status_code.h" |
28 #include "net/nqe/socket_watcher_factory.h" | 31 #include "net/nqe/socket_watcher_factory.h" |
29 #include "net/nqe/throughput_analyzer.h" | 32 #include "net/nqe/throughput_analyzer.h" |
30 #include "net/url_request/url_request.h" | 33 #include "net/url_request/url_request.h" |
| 34 #include "net/url_request/url_request_status.h" |
31 #include "url/gurl.h" | 35 #include "url/gurl.h" |
32 | 36 |
33 #if defined(OS_ANDROID) | 37 #if defined(OS_ANDROID) |
34 #include "net/android/cellular_signal_strength.h" | 38 #include "net/android/cellular_signal_strength.h" |
35 #include "net/android/network_library.h" | 39 #include "net/android/network_library.h" |
36 #endif // OS_ANDROID | 40 #endif // OS_ANDROID |
37 | 41 |
38 namespace { | 42 namespace { |
39 | 43 |
40 // Default value of the half life (in seconds) for computing time weighted | 44 // Default value of the half life (in seconds) for computing time weighted |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 | 146 |
143 bool GetValueForVariationParam( | 147 bool GetValueForVariationParam( |
144 const std::map<std::string, std::string>& variation_params, | 148 const std::map<std::string, std::string>& variation_params, |
145 const std::string& parameter_name, | 149 const std::string& parameter_name, |
146 int32_t* variations_value) { | 150 int32_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 return it != variation_params.end() && |
149 base::StringToInt(it->second, variations_value); | 153 base::StringToInt(it->second, variations_value); |
150 } | 154 } |
151 | 155 |
| 156 // Returns the variation value for |parameter_name|. If the value is |
| 157 // unavailable, |default_value| is returned. |
| 158 double GetDoubleValueForVariationParamWithDefaultValue( |
| 159 const std::map<std::string, std::string>& variation_params, |
| 160 const std::string& parameter_name, |
| 161 double default_value) { |
| 162 const auto it = variation_params.find(parameter_name); |
| 163 if (it == variation_params.end()) |
| 164 return default_value; |
| 165 |
| 166 double variations_value = default_value; |
| 167 if (!base::StringToDouble(it->second, &variations_value)) |
| 168 return default_value; |
| 169 return variations_value; |
| 170 } |
| 171 |
152 // Returns the algorithm that should be used for computing effective connection | 172 // 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 | 173 // type based on field trial params. Returns an empty string if a valid |
154 // algorithm paramter is not present in the field trial params. | 174 // algorithm paramter is not present in the field trial params. |
155 std::string GetEffectiveConnectionTypeAlgorithm( | 175 std::string GetEffectiveConnectionTypeAlgorithm( |
156 const std::map<std::string, std::string>& variation_params) { | 176 const std::map<std::string, std::string>& variation_params) { |
157 const auto it = variation_params.find("effective_connection_type_algorithm"); | 177 const auto it = variation_params.find("effective_connection_type_algorithm"); |
158 if (it == variation_params.end()) | 178 if (it == variation_params.end()) |
159 return std::string(); | 179 return std::string(); |
160 return it->second; | 180 return it->second; |
161 } | 181 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 static const char* const kSuffixes[] = { | 229 static const char* const kSuffixes[] = { |
210 "0_20", "20_60", "60_140", "140_300", "300_620", | 230 "0_20", "20_60", "60_140", "140_300", "300_620", |
211 "620_1260", "1260_2540", "2540_5100", "5100_Infinity"}; | 231 "620_1260", "1260_2540", "2540_5100", "5100_Infinity"}; |
212 for (size_t i = 0; i < arraysize(kSuffixes) - 1; ++i) { | 232 for (size_t i = 0; i < arraysize(kSuffixes) - 1; ++i) { |
213 if (observed_throughput_kbps <= static_cast<float>((20 * (2 << i) - 20))) | 233 if (observed_throughput_kbps <= static_cast<float>((20 * (2 << i) - 20))) |
214 return kSuffixes[i]; | 234 return kSuffixes[i]; |
215 } | 235 } |
216 return kSuffixes[arraysize(kSuffixes) - 1]; | 236 return kSuffixes[arraysize(kSuffixes) - 1]; |
217 } | 237 } |
218 | 238 |
| 239 // The least significant kTrimBits of the metric will be discarded. If the |
| 240 // trimmed metric value is greater than what can be fit in kBitsPerMetric bits, |
| 241 // then the largest value that can be represented in kBitsPerMetric bits is |
| 242 // returned. |
| 243 const int32_t kTrimBits = 5; |
| 244 |
| 245 // Maximum number of bits in which one metric should fit. Restricting the amount |
| 246 // of space allocated to a single metric makes it possile to fit multiple |
| 247 // metrics in a single histogram sample, and ensures that all those metrics |
| 248 // are recorded together as a single tuple. |
| 249 const int32_t kBitsPerMetric = 7; |
| 250 |
| 251 static_assert(32 >= kBitsPerMetric * 4, |
| 252 "Four metrics would not fit in a 32-bit int"); |
| 253 |
| 254 // Trims the |metric| by removing the last kTrimBits, and then rounding down |
| 255 // the |metric| such that the |metric| fits in kBitsPerMetric. |
| 256 int32_t FitInKBitsPerMetricBits(int32_t metric) { |
| 257 // Remove the last kTrimBits. This will allow the metric to fit within |
| 258 // kBitsPerMetric while losing only the least significant bits. |
| 259 metric = metric >> kTrimBits; |
| 260 |
| 261 // kLargestValuePossible is the largest value that can be recorded using |
| 262 // kBitsPerMetric. |
| 263 static const int32_t kLargestValuePossible = (1 << kBitsPerMetric) - 1; |
| 264 if (metric > kLargestValuePossible) { |
| 265 // Fit |metric| in kBitsPerMetric by clamping it down. |
| 266 metric = kLargestValuePossible; |
| 267 } |
| 268 DCHECK_EQ(0, metric >> kBitsPerMetric); |
| 269 return metric; |
| 270 } |
| 271 |
219 } // namespace | 272 } // namespace |
220 | 273 |
221 namespace net { | 274 namespace net { |
222 | 275 |
223 NetworkQualityEstimator::NetworkQualityEstimator( | 276 NetworkQualityEstimator::NetworkQualityEstimator( |
224 std::unique_ptr<ExternalEstimateProvider> external_estimates_provider, | 277 std::unique_ptr<ExternalEstimateProvider> external_estimates_provider, |
225 const std::map<std::string, std::string>& variation_params) | 278 const std::map<std::string, std::string>& variation_params) |
226 : NetworkQualityEstimator(std::move(external_estimates_provider), | 279 : NetworkQualityEstimator(std::move(external_estimates_provider), |
227 variation_params, | 280 variation_params, |
228 false, | 281 false, |
(...skipping 29 matching lines...) Expand all Loading... |
258 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, | 311 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, |
259 std::string())), | 312 std::string())), |
260 downstream_throughput_kbps_observations_(weight_multiplier_per_second_), | 313 downstream_throughput_kbps_observations_(weight_multiplier_per_second_), |
261 rtt_observations_(weight_multiplier_per_second_), | 314 rtt_observations_(weight_multiplier_per_second_), |
262 effective_connection_type_at_last_main_frame_( | 315 effective_connection_type_at_last_main_frame_( |
263 EFFECTIVE_CONNECTION_TYPE_UNKNOWN), | 316 EFFECTIVE_CONNECTION_TYPE_UNKNOWN), |
264 external_estimate_provider_(std::move(external_estimates_provider)), | 317 external_estimate_provider_(std::move(external_estimates_provider)), |
265 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), | 318 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), |
266 min_signal_strength_since_connection_change_(INT32_MAX), | 319 min_signal_strength_since_connection_change_(INT32_MAX), |
267 max_signal_strength_since_connection_change_(INT32_MIN), | 320 max_signal_strength_since_connection_change_(INT32_MIN), |
| 321 correlation_uma_logging_probability_( |
| 322 GetDoubleValueForVariationParamWithDefaultValue( |
| 323 variation_params, |
| 324 "correlation_logging_probability", |
| 325 0.0)), |
268 weak_ptr_factory_(this) { | 326 weak_ptr_factory_(this) { |
269 static_assert(kDefaultHalfLifeSeconds > 0, | 327 static_assert(kDefaultHalfLifeSeconds > 0, |
270 "Default half life duration must be > 0"); | 328 "Default half life duration must be > 0"); |
271 static_assert(kMaximumNetworkQualityCacheSize > 0, | 329 static_assert(kMaximumNetworkQualityCacheSize > 0, |
272 "Size of the network quality cache must be > 0"); | 330 "Size of the network quality cache must be > 0"); |
273 // This limit should not be increased unless the logic for removing the | 331 // This limit should not be increased unless the logic for removing the |
274 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. | 332 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. |
275 static_assert(kMaximumNetworkQualityCacheSize <= 10, | 333 static_assert(kMaximumNetworkQualityCacheSize <= 10, |
276 "Size of the network quality cache must <= 10"); | 334 "Size of the network quality cache must <= 10"); |
277 // None of the algorithms can have an empty name. | 335 // None of the algorithms can have an empty name. |
278 DCHECK(algorithm_name_to_enum_.end() == | 336 DCHECK(algorithm_name_to_enum_.end() == |
279 algorithm_name_to_enum_.find(std::string())); | 337 algorithm_name_to_enum_.find(std::string())); |
280 | 338 |
281 DCHECK_EQ(algorithm_name_to_enum_.size(), | 339 DCHECK_EQ(algorithm_name_to_enum_.size(), |
282 static_cast<size_t>(EffectiveConnectionTypeAlgorithm:: | 340 static_cast<size_t>(EffectiveConnectionTypeAlgorithm:: |
283 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST)); | 341 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST)); |
284 DCHECK_NE(EffectiveConnectionTypeAlgorithm:: | 342 DCHECK_NE(EffectiveConnectionTypeAlgorithm:: |
285 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST, | 343 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST, |
286 effective_connection_type_algorithm_); | 344 effective_connection_type_algorithm_); |
| 345 DCHECK_LE(0.0, correlation_uma_logging_probability_); |
| 346 DCHECK_GE(1.0, correlation_uma_logging_probability_); |
287 | 347 |
288 ObtainOperatingParams(variation_params); | 348 ObtainOperatingParams(variation_params); |
289 ObtainEffectiveConnectionTypeModelParams(variation_params); | 349 ObtainEffectiveConnectionTypeModelParams(variation_params); |
290 NetworkChangeNotifier::AddConnectionTypeObserver(this); | 350 NetworkChangeNotifier::AddConnectionTypeObserver(this); |
291 if (external_estimate_provider_) { | 351 if (external_estimate_provider_) { |
292 RecordExternalEstimateProviderMetrics( | 352 RecordExternalEstimateProviderMetrics( |
293 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE); | 353 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE); |
294 external_estimate_provider_->SetUpdatedEstimateDelegate(this); | 354 external_estimate_provider_->SetUpdatedEstimateDelegate(this); |
295 } else { | 355 } else { |
296 RecordExternalEstimateProviderMetrics( | 356 RecordExternalEstimateProviderMetrics( |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
536 | 596 |
537 LoadTimingInfo load_timing_info; | 597 LoadTimingInfo load_timing_info; |
538 request.GetLoadTimingInfo(&load_timing_info); | 598 request.GetLoadTimingInfo(&load_timing_info); |
539 | 599 |
540 // If the load timing info is unavailable, it probably means that the request | 600 // If the load timing info is unavailable, it probably means that the request |
541 // did not go over the network. | 601 // did not go over the network. |
542 if (load_timing_info.send_start.is_null() || | 602 if (load_timing_info.send_start.is_null() || |
543 load_timing_info.receive_headers_end.is_null()) { | 603 load_timing_info.receive_headers_end.is_null()) { |
544 return; | 604 return; |
545 } | 605 } |
| 606 DCHECK(!request.response_info().was_cached); |
546 | 607 |
547 // Duration between when the resource was requested and when the response | 608 // Duration between when the resource was requested and when the response |
548 // headers were received. | 609 // headers were received. |
549 base::TimeDelta observed_http_rtt = | 610 base::TimeDelta observed_http_rtt = |
550 load_timing_info.receive_headers_end - load_timing_info.send_start; | 611 load_timing_info.receive_headers_end - load_timing_info.send_start; |
551 DCHECK_GE(observed_http_rtt, base::TimeDelta()); | 612 DCHECK_GE(observed_http_rtt, base::TimeDelta()); |
552 if (observed_http_rtt < peak_network_quality_.http_rtt()) { | 613 if (observed_http_rtt < peak_network_quality_.http_rtt()) { |
553 peak_network_quality_ = nqe::internal::NetworkQuality( | 614 peak_network_quality_ = nqe::internal::NetworkQuality( |
554 observed_http_rtt, peak_network_quality_.transport_rtt(), | 615 observed_http_rtt, peak_network_quality_.transport_rtt(), |
555 peak_network_quality_.downstream_throughput_kbps()); | 616 peak_network_quality_.downstream_throughput_kbps()); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 void NetworkQualityEstimator::NotifyRequestCompleted( | 738 void NetworkQualityEstimator::NotifyRequestCompleted( |
678 const URLRequest& request) { | 739 const URLRequest& request) { |
679 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), | 740 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("net"), |
680 "NetworkQualityEstimator::NotifyRequestCompleted"); | 741 "NetworkQualityEstimator::NotifyRequestCompleted"); |
681 DCHECK(thread_checker_.CalledOnValidThread()); | 742 DCHECK(thread_checker_.CalledOnValidThread()); |
682 | 743 |
683 if (!RequestSchemeIsHTTPOrHTTPS(request)) | 744 if (!RequestSchemeIsHTTPOrHTTPS(request)) |
684 return; | 745 return; |
685 | 746 |
686 throughput_analyzer_->NotifyRequestCompleted(request); | 747 throughput_analyzer_->NotifyRequestCompleted(request); |
| 748 RecordCorrelationMetric(request); |
| 749 } |
| 750 |
| 751 void NetworkQualityEstimator::RecordCorrelationMetric( |
| 752 const URLRequest& request) const { |
| 753 DCHECK(thread_checker_.CalledOnValidThread()); |
| 754 |
| 755 // The histogram is recorded with probability |
| 756 // |correlation_uma_logging_probability_| to reduce overhead involved with |
| 757 // sparse histograms. Also, recording the correlation on each request is |
| 758 // unnecessary. |
| 759 if (RandDouble() >= correlation_uma_logging_probability_) |
| 760 return; |
| 761 |
| 762 if (request.response_info().was_cached || |
| 763 !request.response_info().network_accessed) { |
| 764 return; |
| 765 } |
| 766 |
| 767 LoadTimingInfo load_timing_info; |
| 768 request.GetLoadTimingInfo(&load_timing_info); |
| 769 DCHECK(!load_timing_info.send_start.is_null() && |
| 770 !load_timing_info.receive_headers_end.is_null()); |
| 771 |
| 772 // Record UMA only for successful requests that have completed. |
| 773 if (!request.status().is_success() || request.status().is_io_pending()) |
| 774 return; |
| 775 if (request.GetResponseCode() != HTTP_OK) |
| 776 return; |
| 777 if (load_timing_info.receive_headers_end < last_main_frame_request_) |
| 778 return; |
| 779 |
| 780 const base::TimeTicks now = tick_clock_->NowTicks(); |
| 781 // Record UMA only for requests that started recently. |
| 782 if (now - last_main_frame_request_ > base::TimeDelta::FromSeconds(15)) |
| 783 return; |
| 784 |
| 785 DCHECK_GE(now, load_timing_info.send_start); |
| 786 |
| 787 int32_t rtt = 0; |
| 788 |
| 789 if (UseTransportRTT()) { |
| 790 rtt = estimated_quality_at_last_main_frame_.transport_rtt() != |
| 791 nqe::internal::InvalidRTT() |
| 792 ? FitInKBitsPerMetricBits( |
| 793 estimated_quality_at_last_main_frame_.transport_rtt() |
| 794 .InMilliseconds()) |
| 795 : 0; |
| 796 } else { |
| 797 rtt = estimated_quality_at_last_main_frame_.http_rtt() != |
| 798 nqe::internal::InvalidRTT() |
| 799 ? FitInKBitsPerMetricBits( |
| 800 estimated_quality_at_last_main_frame_.http_rtt() |
| 801 .InMilliseconds()) |
| 802 : 0; |
| 803 } |
| 804 |
| 805 const int32_t downstream_throughput = |
| 806 estimated_quality_at_last_main_frame_.downstream_throughput_kbps() != |
| 807 nqe::internal::kInvalidThroughput |
| 808 ? FitInKBitsPerMetricBits(estimated_quality_at_last_main_frame_ |
| 809 .downstream_throughput_kbps()) |
| 810 : 0; |
| 811 |
| 812 const int32_t resource_load_time = FitInKBitsPerMetricBits( |
| 813 (now - load_timing_info.send_start).InMilliseconds()); |
| 814 |
| 815 int64_t resource_size = (request.GetTotalReceivedBytes() * 8) / 1024; |
| 816 if (resource_size >= (1 << kBitsPerMetric)) { |
| 817 // Too large resource size (at least 128 Kb). |
| 818 return; |
| 819 } |
| 820 |
| 821 DCHECK_EQ( |
| 822 0, (rtt | downstream_throughput | resource_load_time | resource_size) >> |
| 823 kBitsPerMetric); |
| 824 |
| 825 // First 32 - (4* kBitsPerMetric) of the sample are unset. Next |
| 826 // kBitsPerMetric of the sample contain |rtt|. Next |
| 827 // kBitsPerMetric contain |downstream_throughput|. Next kBitsPerMetric |
| 828 // contain |resource_load_time|. And, the last kBitsPerMetric |
| 829 // contain |resource_size|. |
| 830 int32_t sample = rtt; |
| 831 sample = (sample << kBitsPerMetric) | downstream_throughput; |
| 832 sample = (sample << kBitsPerMetric) | resource_load_time; |
| 833 sample = (sample << kBitsPerMetric) | resource_size; |
| 834 |
| 835 UMA_HISTOGRAM_SPARSE_SLOWLY("NQE.Correlation.ResourceLoadTime.0Kb_128Kb", |
| 836 sample); |
687 } | 837 } |
688 | 838 |
689 void NetworkQualityEstimator::NotifyURLRequestDestroyed( | 839 void NetworkQualityEstimator::NotifyURLRequestDestroyed( |
690 const URLRequest& request) { | 840 const URLRequest& request) { |
691 DCHECK(thread_checker_.CalledOnValidThread()); | 841 DCHECK(thread_checker_.CalledOnValidThread()); |
692 | 842 |
693 NotifyRequestCompleted(request); | 843 if (!RequestSchemeIsHTTPOrHTTPS(request)) |
| 844 return; |
| 845 |
| 846 throughput_analyzer_->NotifyRequestCompleted(request); |
694 } | 847 } |
695 | 848 |
696 void NetworkQualityEstimator::AddRTTObserver(RTTObserver* rtt_observer) { | 849 void NetworkQualityEstimator::AddRTTObserver(RTTObserver* rtt_observer) { |
697 DCHECK(thread_checker_.CalledOnValidThread()); | 850 DCHECK(thread_checker_.CalledOnValidThread()); |
698 rtt_observer_list_.AddObserver(rtt_observer); | 851 rtt_observer_list_.AddObserver(rtt_observer); |
699 } | 852 } |
700 | 853 |
701 void NetworkQualityEstimator::RemoveRTTObserver(RTTObserver* rtt_observer) { | 854 void NetworkQualityEstimator::RemoveRTTObserver(RTTObserver* rtt_observer) { |
702 DCHECK(thread_checker_.CalledOnValidThread()); | 855 DCHECK(thread_checker_.CalledOnValidThread()); |
703 rtt_observer_list_.RemoveObserver(rtt_observer); | 856 rtt_observer_list_.RemoveObserver(rtt_observer); |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
982 NetworkQualityEstimator::MetricUsage:: | 1135 NetworkQualityEstimator::MetricUsage:: |
983 USE_IF_AVAILABLE /* transport_rtt_metric */, | 1136 USE_IF_AVAILABLE /* transport_rtt_metric */, |
984 NetworkQualityEstimator::MetricUsage:: | 1137 NetworkQualityEstimator::MetricUsage:: |
985 USE_IF_AVAILABLE /* downstream_throughput_kbps_metric */); | 1138 USE_IF_AVAILABLE /* downstream_throughput_kbps_metric */); |
986 } | 1139 } |
987 // Add additional algorithms here. | 1140 // Add additional algorithms here. |
988 NOTREACHED(); | 1141 NOTREACHED(); |
989 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; | 1142 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; |
990 } | 1143 } |
991 | 1144 |
| 1145 bool NetworkQualityEstimator::UseTransportRTT() const { |
| 1146 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1147 |
| 1148 if (effective_connection_type_algorithm_ == |
| 1149 EffectiveConnectionTypeAlgorithm::HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT) { |
| 1150 return false; |
| 1151 } |
| 1152 if (effective_connection_type_algorithm_ == |
| 1153 EffectiveConnectionTypeAlgorithm:: |
| 1154 TRANSPORT_RTT_OR_DOWNSTREAM_THROUGHOUT) { |
| 1155 return true; |
| 1156 } |
| 1157 // Add additional algorithms here. |
| 1158 NOTREACHED(); |
| 1159 return false; |
| 1160 } |
| 1161 |
992 NetworkQualityEstimator::EffectiveConnectionType | 1162 NetworkQualityEstimator::EffectiveConnectionType |
993 NetworkQualityEstimator::GetRecentEffectiveConnectionTypeUsingMetrics( | 1163 NetworkQualityEstimator::GetRecentEffectiveConnectionTypeUsingMetrics( |
994 const base::TimeTicks& start_time, | 1164 const base::TimeTicks& start_time, |
995 NetworkQualityEstimator::MetricUsage http_rtt_metric, | 1165 NetworkQualityEstimator::MetricUsage http_rtt_metric, |
996 NetworkQualityEstimator::MetricUsage transport_rtt_metric, | 1166 NetworkQualityEstimator::MetricUsage transport_rtt_metric, |
997 NetworkQualityEstimator::MetricUsage downstream_throughput_kbps_metric) | 1167 NetworkQualityEstimator::MetricUsage downstream_throughput_kbps_metric) |
998 const { | 1168 const { |
999 DCHECK(thread_checker_.CalledOnValidThread()); | 1169 DCHECK(thread_checker_.CalledOnValidThread()); |
1000 | 1170 |
1001 // If the device is currently offline, then return | 1171 // If the device is currently offline, then return |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1350 NOTREACHED(); | 1520 NOTREACHED(); |
1351 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; | 1521 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; |
1352 } | 1522 } |
1353 | 1523 |
1354 void NetworkQualityEstimator::SetTickClockForTesting( | 1524 void NetworkQualityEstimator::SetTickClockForTesting( |
1355 std::unique_ptr<base::TickClock> tick_clock) { | 1525 std::unique_ptr<base::TickClock> tick_clock) { |
1356 DCHECK(thread_checker_.CalledOnValidThread()); | 1526 DCHECK(thread_checker_.CalledOnValidThread()); |
1357 tick_clock_ = std::move(tick_clock); | 1527 tick_clock_ = std::move(tick_clock); |
1358 } | 1528 } |
1359 | 1529 |
| 1530 double NetworkQualityEstimator::RandDouble() const { |
| 1531 return base::RandDouble(); |
| 1532 } |
| 1533 |
1360 void NetworkQualityEstimator::CacheNetworkQualityEstimate() { | 1534 void NetworkQualityEstimator::CacheNetworkQualityEstimate() { |
1361 DCHECK(thread_checker_.CalledOnValidThread()); | 1535 DCHECK(thread_checker_.CalledOnValidThread()); |
1362 DCHECK_LE(cached_network_qualities_.size(), | 1536 DCHECK_LE(cached_network_qualities_.size(), |
1363 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 1537 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
1364 | 1538 |
1365 // If the network name is unavailable, caching should not be performed. | 1539 // If the network name is unavailable, caching should not be performed. |
1366 if (current_network_id_.id.empty()) | 1540 if (current_network_id_.id.empty()) |
1367 return; | 1541 return; |
1368 | 1542 |
1369 base::TimeDelta http_rtt = nqe::internal::InvalidRTT(); | 1543 base::TimeDelta http_rtt = nqe::internal::InvalidRTT(); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1492 NotifyObserversOfEffectiveConnectionTypeChanged() { | 1666 NotifyObserversOfEffectiveConnectionTypeChanged() { |
1493 DCHECK(thread_checker_.CalledOnValidThread()); | 1667 DCHECK(thread_checker_.CalledOnValidThread()); |
1494 | 1668 |
1495 // TODO(tbansal): Add hysteresis in the notification. | 1669 // TODO(tbansal): Add hysteresis in the notification. |
1496 FOR_EACH_OBSERVER( | 1670 FOR_EACH_OBSERVER( |
1497 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, | 1671 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, |
1498 OnEffectiveConnectionTypeChanged(effective_connection_type_)); | 1672 OnEffectiveConnectionTypeChanged(effective_connection_type_)); |
1499 } | 1673 } |
1500 | 1674 |
1501 } // namespace net | 1675 } // namespace net |
OLD | NEW |