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> |
| 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; | |
|
Ilya Sherman
2016/07/21 23:39:51
Did you want to set this to 8? (And update the cod
tbansal1
2016/07/22 00:15:44
I want to keep the 4 bits unused. I might add Effe
| |
| 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 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 962 NetworkQualityEstimator::MetricUsage:: | 1115 NetworkQualityEstimator::MetricUsage:: |
| 963 USE_IF_AVAILABLE /* transport_rtt_metric */, | 1116 USE_IF_AVAILABLE /* transport_rtt_metric */, |
| 964 NetworkQualityEstimator::MetricUsage:: | 1117 NetworkQualityEstimator::MetricUsage:: |
| 965 USE_IF_AVAILABLE /* downstream_throughput_kbps_metric */); | 1118 USE_IF_AVAILABLE /* downstream_throughput_kbps_metric */); |
| 966 } | 1119 } |
| 967 // Add additional algorithms here. | 1120 // Add additional algorithms here. |
| 968 NOTREACHED(); | 1121 NOTREACHED(); |
| 969 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; | 1122 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; |
| 970 } | 1123 } |
| 971 | 1124 |
| 1125 bool NetworkQualityEstimator::UseTransportRTT() const { | |
| 1126 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 1127 | |
| 1128 if (effective_connection_type_algorithm_ == | |
| 1129 EffectiveConnectionTypeAlgorithm::HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT) { | |
| 1130 return false; | |
| 1131 } | |
| 1132 if (effective_connection_type_algorithm_ == | |
| 1133 EffectiveConnectionTypeAlgorithm:: | |
| 1134 TRANSPORT_RTT_OR_DOWNSTREAM_THROUGHOUT) { | |
| 1135 return true; | |
| 1136 } | |
| 1137 // Add additional algorithms here. | |
| 1138 NOTREACHED(); | |
| 1139 return false; | |
| 1140 } | |
| 1141 | |
| 972 NetworkQualityEstimator::EffectiveConnectionType | 1142 NetworkQualityEstimator::EffectiveConnectionType |
| 973 NetworkQualityEstimator::GetRecentEffectiveConnectionTypeUsingMetrics( | 1143 NetworkQualityEstimator::GetRecentEffectiveConnectionTypeUsingMetrics( |
| 974 const base::TimeTicks& start_time, | 1144 const base::TimeTicks& start_time, |
| 975 NetworkQualityEstimator::MetricUsage http_rtt_metric, | 1145 NetworkQualityEstimator::MetricUsage http_rtt_metric, |
| 976 NetworkQualityEstimator::MetricUsage transport_rtt_metric, | 1146 NetworkQualityEstimator::MetricUsage transport_rtt_metric, |
| 977 NetworkQualityEstimator::MetricUsage downstream_throughput_kbps_metric) | 1147 NetworkQualityEstimator::MetricUsage downstream_throughput_kbps_metric) |
| 978 const { | 1148 const { |
| 979 DCHECK(thread_checker_.CalledOnValidThread()); | 1149 DCHECK(thread_checker_.CalledOnValidThread()); |
| 980 | 1150 |
| 981 // If the device is currently offline, then return | 1151 // If the device is currently offline, then return |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1330 NOTREACHED(); | 1500 NOTREACHED(); |
| 1331 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; | 1501 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; |
| 1332 } | 1502 } |
| 1333 | 1503 |
| 1334 void NetworkQualityEstimator::SetTickClockForTesting( | 1504 void NetworkQualityEstimator::SetTickClockForTesting( |
| 1335 std::unique_ptr<base::TickClock> tick_clock) { | 1505 std::unique_ptr<base::TickClock> tick_clock) { |
| 1336 DCHECK(thread_checker_.CalledOnValidThread()); | 1506 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1337 tick_clock_ = std::move(tick_clock); | 1507 tick_clock_ = std::move(tick_clock); |
| 1338 } | 1508 } |
| 1339 | 1509 |
| 1510 double NetworkQualityEstimator::RandDouble() const { | |
| 1511 return base::RandDouble(); | |
| 1512 } | |
| 1513 | |
| 1340 void NetworkQualityEstimator::CacheNetworkQualityEstimate() { | 1514 void NetworkQualityEstimator::CacheNetworkQualityEstimate() { |
| 1341 DCHECK(thread_checker_.CalledOnValidThread()); | 1515 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1342 DCHECK_LE(cached_network_qualities_.size(), | 1516 DCHECK_LE(cached_network_qualities_.size(), |
| 1343 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 1517 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
| 1344 | 1518 |
| 1345 // If the network name is unavailable, caching should not be performed. | 1519 // If the network name is unavailable, caching should not be performed. |
| 1346 if (current_network_id_.id.empty()) | 1520 if (current_network_id_.id.empty()) |
| 1347 return; | 1521 return; |
| 1348 | 1522 |
| 1349 base::TimeDelta http_rtt = nqe::internal::InvalidRTT(); | 1523 base::TimeDelta http_rtt = nqe::internal::InvalidRTT(); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1472 NotifyObserversOfEffectiveConnectionTypeChanged() { | 1646 NotifyObserversOfEffectiveConnectionTypeChanged() { |
| 1473 DCHECK(thread_checker_.CalledOnValidThread()); | 1647 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1474 | 1648 |
| 1475 // TODO(tbansal): Add hysteresis in the notification. | 1649 // TODO(tbansal): Add hysteresis in the notification. |
| 1476 FOR_EACH_OBSERVER( | 1650 FOR_EACH_OBSERVER( |
| 1477 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, | 1651 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, |
| 1478 OnEffectiveConnectionTypeChanged(effective_connection_type_)); | 1652 OnEffectiveConnectionTypeChanged(effective_connection_type_)); |
| 1479 } | 1653 } |
| 1480 | 1654 |
| 1481 } // namespace net | 1655 } // namespace net |
| OLD | NEW |