| 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/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/metrics/histogram.h" | 15 #include "base/metrics/histogram.h" |
| 16 #include "base/metrics/histogram_base.h" | 16 #include "base/metrics/histogram_base.h" |
| 17 #include "base/single_thread_task_runner.h" | 17 #include "base/single_thread_task_runner.h" |
| 18 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
| 19 #include "base/threading/thread_task_runner_handle.h" | 19 #include "base/threading/thread_task_runner_handle.h" |
| 20 #include "base/time/default_tick_clock.h" |
| 20 #include "base/trace_event/trace_event.h" | 21 #include "base/trace_event/trace_event.h" |
| 21 #include "build/build_config.h" | 22 #include "build/build_config.h" |
| 22 #include "net/base/load_flags.h" | 23 #include "net/base/load_flags.h" |
| 23 #include "net/base/load_timing_info.h" | 24 #include "net/base/load_timing_info.h" |
| 24 #include "net/base/network_interfaces.h" | 25 #include "net/base/network_interfaces.h" |
| 25 #include "net/base/url_util.h" | 26 #include "net/base/url_util.h" |
| 26 #include "net/nqe/throughput_analyzer.h" | 27 #include "net/nqe/throughput_analyzer.h" |
| 27 #include "net/socket/socket_performance_watcher.h" | 28 #include "net/socket/socket_performance_watcher.h" |
| 28 #include "net/url_request/url_request.h" | 29 #include "net/url_request/url_request.h" |
| 29 #include "url/gurl.h" | 30 #include "url/gurl.h" |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 | 246 |
| 246 NetworkQualityEstimator::NetworkQualityEstimator( | 247 NetworkQualityEstimator::NetworkQualityEstimator( |
| 247 std::unique_ptr<ExternalEstimateProvider> external_estimates_provider, | 248 std::unique_ptr<ExternalEstimateProvider> external_estimates_provider, |
| 248 const std::map<std::string, std::string>& variation_params, | 249 const std::map<std::string, std::string>& variation_params, |
| 249 bool use_local_host_requests_for_tests, | 250 bool use_local_host_requests_for_tests, |
| 250 bool use_smaller_responses_for_tests) | 251 bool use_smaller_responses_for_tests) |
| 251 : use_localhost_requests_(use_local_host_requests_for_tests), | 252 : use_localhost_requests_(use_local_host_requests_for_tests), |
| 252 use_small_responses_(use_smaller_responses_for_tests), | 253 use_small_responses_(use_smaller_responses_for_tests), |
| 253 weight_multiplier_per_second_( | 254 weight_multiplier_per_second_( |
| 254 GetWeightMultiplierPerSecond(variation_params)), | 255 GetWeightMultiplierPerSecond(variation_params)), |
| 255 last_connection_change_(base::TimeTicks::Now()), | 256 tick_clock_(new base::DefaultTickClock()), |
| 257 effective_connection_type_recomputation_interval_( |
| 258 base::TimeDelta::FromSeconds(15)), |
| 259 last_connection_change_(tick_clock_->NowTicks()), |
| 256 current_network_id_( | 260 current_network_id_( |
| 257 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, | 261 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, |
| 258 std::string())), | 262 std::string())), |
| 259 downstream_throughput_kbps_observations_(weight_multiplier_per_second_), | 263 downstream_throughput_kbps_observations_(weight_multiplier_per_second_), |
| 260 rtt_observations_(weight_multiplier_per_second_), | 264 rtt_observations_(weight_multiplier_per_second_), |
| 261 external_estimate_provider_(std::move(external_estimates_provider)), | 265 external_estimate_provider_(std::move(external_estimates_provider)), |
| 266 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), |
| 262 weak_ptr_factory_(this) { | 267 weak_ptr_factory_(this) { |
| 263 static_assert(kDefaultHalfLifeSeconds > 0, | 268 static_assert(kDefaultHalfLifeSeconds > 0, |
| 264 "Default half life duration must be > 0"); | 269 "Default half life duration must be > 0"); |
| 265 static_assert(kMaximumNetworkQualityCacheSize > 0, | 270 static_assert(kMaximumNetworkQualityCacheSize > 0, |
| 266 "Size of the network quality cache must be > 0"); | 271 "Size of the network quality cache must be > 0"); |
| 267 // This limit should not be increased unless the logic for removing the | 272 // This limit should not be increased unless the logic for removing the |
| 268 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. | 273 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. |
| 269 static_assert(kMaximumNetworkQualityCacheSize <= 10, | 274 static_assert(kMaximumNetworkQualityCacheSize <= 10, |
| 270 "Size of the network quality cache must <= 10"); | 275 "Size of the network quality cache must <= 10"); |
| 271 | 276 |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 396 } | 401 } |
| 397 } | 402 } |
| 398 | 403 |
| 399 void NetworkQualityEstimator::AddDefaultEstimates() { | 404 void NetworkQualityEstimator::AddDefaultEstimates() { |
| 400 DCHECK(thread_checker_.CalledOnValidThread()); | 405 DCHECK(thread_checker_.CalledOnValidThread()); |
| 401 | 406 |
| 402 if (default_observations_[current_network_id_.type].http_rtt() != | 407 if (default_observations_[current_network_id_.type].http_rtt() != |
| 403 nqe::internal::InvalidRTT()) { | 408 nqe::internal::InvalidRTT()) { |
| 404 RttObservation rtt_observation( | 409 RttObservation rtt_observation( |
| 405 default_observations_[current_network_id_.type].http_rtt(), | 410 default_observations_[current_network_id_.type].http_rtt(), |
| 406 base::TimeTicks::Now(), | 411 tick_clock_->NowTicks(), |
| 407 NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_FROM_PLATFORM); | 412 NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_FROM_PLATFORM); |
| 408 rtt_observations_.AddObservation(rtt_observation); | 413 rtt_observations_.AddObservation(rtt_observation); |
| 409 NotifyObserversOfRTT(rtt_observation); | 414 NotifyObserversOfRTT(rtt_observation); |
| 410 } | 415 } |
| 411 | 416 |
| 412 if (default_observations_[current_network_id_.type] | 417 if (default_observations_[current_network_id_.type] |
| 413 .downstream_throughput_kbps() != nqe::internal::kInvalidThroughput) { | 418 .downstream_throughput_kbps() != nqe::internal::kInvalidThroughput) { |
| 414 ThroughputObservation throughput_observation( | 419 ThroughputObservation throughput_observation( |
| 415 default_observations_[current_network_id_.type] | 420 default_observations_[current_network_id_.type] |
| 416 .downstream_throughput_kbps(), | 421 .downstream_throughput_kbps(), |
| 417 base::TimeTicks::Now(), | 422 tick_clock_->NowTicks(), |
| 418 NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_FROM_PLATFORM); | 423 NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_FROM_PLATFORM); |
| 419 downstream_throughput_kbps_observations_.AddObservation( | 424 downstream_throughput_kbps_observations_.AddObservation( |
| 420 throughput_observation); | 425 throughput_observation); |
| 421 NotifyObserversOfThroughput(throughput_observation); | 426 NotifyObserversOfThroughput(throughput_observation); |
| 422 } | 427 } |
| 423 } | 428 } |
| 424 | 429 |
| 425 NetworkQualityEstimator::~NetworkQualityEstimator() { | 430 NetworkQualityEstimator::~NetworkQualityEstimator() { |
| 426 DCHECK(thread_checker_.CalledOnValidThread()); | 431 DCHECK(thread_checker_.CalledOnValidThread()); |
| 427 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); | 432 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 455 | 460 |
| 456 int32_t downstream_throughput_kbps; | 461 int32_t downstream_throughput_kbps; |
| 457 if (!GetDownlinkThroughputKbpsEstimate(&downstream_throughput_kbps)) | 462 if (!GetDownlinkThroughputKbpsEstimate(&downstream_throughput_kbps)) |
| 458 downstream_throughput_kbps = nqe::internal::kInvalidThroughput; | 463 downstream_throughput_kbps = nqe::internal::kInvalidThroughput; |
| 459 | 464 |
| 460 estimated_median_network_quality_ = nqe::internal::NetworkQuality( | 465 estimated_median_network_quality_ = nqe::internal::NetworkQuality( |
| 461 estimated_http_rtt, nqe::internal::InvalidRTT(), | 466 estimated_http_rtt, nqe::internal::InvalidRTT(), |
| 462 downstream_throughput_kbps); | 467 downstream_throughput_kbps); |
| 463 } | 468 } |
| 464 | 469 |
| 465 base::TimeTicks now = base::TimeTicks::Now(); | 470 const base::TimeTicks now = tick_clock_->NowTicks(); |
| 466 LoadTimingInfo load_timing_info; | 471 LoadTimingInfo load_timing_info; |
| 467 request.GetLoadTimingInfo(&load_timing_info); | 472 request.GetLoadTimingInfo(&load_timing_info); |
| 468 | 473 |
| 469 // If the load timing info is unavailable, it probably means that the request | 474 // If the load timing info is unavailable, it probably means that the request |
| 470 // did not go over the network. | 475 // did not go over the network. |
| 471 if (load_timing_info.send_start.is_null() || | 476 if (load_timing_info.send_start.is_null() || |
| 472 load_timing_info.receive_headers_end.is_null()) { | 477 load_timing_info.receive_headers_end.is_null()) { |
| 473 return; | 478 return; |
| 474 } | 479 } |
| 475 | 480 |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 603 void NetworkQualityEstimator::OnConnectionTypeChanged( | 608 void NetworkQualityEstimator::OnConnectionTypeChanged( |
| 604 NetworkChangeNotifier::ConnectionType type) { | 609 NetworkChangeNotifier::ConnectionType type) { |
| 605 DCHECK(thread_checker_.CalledOnValidThread()); | 610 DCHECK(thread_checker_.CalledOnValidThread()); |
| 606 | 611 |
| 607 RecordMetricsOnConnectionTypeChanged(); | 612 RecordMetricsOnConnectionTypeChanged(); |
| 608 | 613 |
| 609 // Write the estimates of the previous network to the cache. | 614 // Write the estimates of the previous network to the cache. |
| 610 CacheNetworkQualityEstimate(); | 615 CacheNetworkQualityEstimate(); |
| 611 | 616 |
| 612 // Clear the local state. | 617 // Clear the local state. |
| 613 last_connection_change_ = base::TimeTicks::Now(); | 618 last_connection_change_ = tick_clock_->NowTicks(); |
| 614 peak_network_quality_ = nqe::internal::NetworkQuality(); | 619 peak_network_quality_ = nqe::internal::NetworkQuality(); |
| 615 downstream_throughput_kbps_observations_.Clear(); | 620 downstream_throughput_kbps_observations_.Clear(); |
| 616 rtt_observations_.Clear(); | 621 rtt_observations_.Clear(); |
| 617 current_network_id_ = GetCurrentNetworkID(); | 622 current_network_id_ = GetCurrentNetworkID(); |
| 618 | 623 |
| 619 QueryExternalEstimateProvider(); | 624 QueryExternalEstimateProvider(); |
| 620 | 625 |
| 621 // Read any cached estimates for the new network. If cached estimates are | 626 // Read any cached estimates for the new network. If cached estimates are |
| 622 // unavailable, add the default estimates. | 627 // unavailable, add the default estimates. |
| 623 if (!ReadCachedNetworkQualityEstimate()) | 628 if (!ReadCachedNetworkQualityEstimate()) |
| 624 AddDefaultEstimates(); | 629 AddDefaultEstimates(); |
| 625 estimated_median_network_quality_ = nqe::internal::NetworkQuality(); | 630 estimated_median_network_quality_ = nqe::internal::NetworkQuality(); |
| 626 throughput_analyzer_->OnConnectionTypeChanged(); | 631 throughput_analyzer_->OnConnectionTypeChanged(); |
| 632 MaybeRecomputeEffectiveConnectionType(); |
| 627 } | 633 } |
| 628 | 634 |
| 629 void NetworkQualityEstimator::RecordMetricsOnConnectionTypeChanged() const { | 635 void NetworkQualityEstimator::RecordMetricsOnConnectionTypeChanged() const { |
| 630 DCHECK(thread_checker_.CalledOnValidThread()); | 636 DCHECK(thread_checker_.CalledOnValidThread()); |
| 631 if (peak_network_quality_.http_rtt() != nqe::internal::InvalidRTT()) { | 637 if (peak_network_quality_.http_rtt() != nqe::internal::InvalidRTT()) { |
| 632 base::HistogramBase* rtt_histogram = | 638 base::HistogramBase* rtt_histogram = |
| 633 GetHistogram("FastestRTT.", current_network_id_.type, 10 * 1000); | 639 GetHistogram("FastestRTT.", current_network_id_.type, 10 * 1000); |
| 634 rtt_histogram->Add(peak_network_quality_.http_rtt().InMilliseconds()); | 640 rtt_histogram->Add(peak_network_quality_.http_rtt().InMilliseconds()); |
| 635 } | 641 } |
| 636 | 642 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 if (estimated_http_rtt_is_higher_than_threshold || | 748 if (estimated_http_rtt_is_higher_than_threshold || |
| 743 estimated_throughput_is_lower_than_threshold) { | 749 estimated_throughput_is_lower_than_threshold) { |
| 744 return type; | 750 return type; |
| 745 } | 751 } |
| 746 } | 752 } |
| 747 // Return the fastest connection type. | 753 // Return the fastest connection type. |
| 748 return static_cast<EffectiveConnectionType>(EFFECTIVE_CONNECTION_TYPE_LAST - | 754 return static_cast<EffectiveConnectionType>(EFFECTIVE_CONNECTION_TYPE_LAST - |
| 749 1); | 755 1); |
| 750 } | 756 } |
| 751 | 757 |
| 758 void NetworkQualityEstimator::AddEffectiveConnectionTypeObserver( |
| 759 EffectiveConnectionTypeObserver* observer) { |
| 760 DCHECK(thread_checker_.CalledOnValidThread()); |
| 761 effective_connection_type_observer_list_.AddObserver(observer); |
| 762 } |
| 763 |
| 764 void NetworkQualityEstimator::RemoveEffectiveConnectionTypeObserver( |
| 765 EffectiveConnectionTypeObserver* observer) { |
| 766 DCHECK(thread_checker_.CalledOnValidThread()); |
| 767 effective_connection_type_observer_list_.RemoveObserver(observer); |
| 768 } |
| 769 |
| 752 bool NetworkQualityEstimator::GetHttpRTTEstimate(base::TimeDelta* rtt) const { | 770 bool NetworkQualityEstimator::GetHttpRTTEstimate(base::TimeDelta* rtt) const { |
| 753 DCHECK(thread_checker_.CalledOnValidThread()); | 771 DCHECK(thread_checker_.CalledOnValidThread()); |
| 754 std::vector<NetworkQualityObservationSource> disallowed_observation_sources; | 772 std::vector<NetworkQualityObservationSource> disallowed_observation_sources; |
| 755 disallowed_observation_sources.push_back( | 773 disallowed_observation_sources.push_back( |
| 756 NETWORK_QUALITY_OBSERVATION_SOURCE_TCP); | 774 NETWORK_QUALITY_OBSERVATION_SOURCE_TCP); |
| 757 disallowed_observation_sources.push_back( | 775 disallowed_observation_sources.push_back( |
| 758 NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC); | 776 NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC); |
| 759 *rtt = GetRTTEstimateInternal(disallowed_observation_sources, | 777 *rtt = GetRTTEstimateInternal(disallowed_observation_sources, |
| 760 base::TimeTicks(), 50); | 778 base::TimeTicks(), 50); |
| 761 return (*rtt != nqe::internal::InvalidRTT()); | 779 return (*rtt != nqe::internal::InvalidRTT()); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 915 return false; | 933 return false; |
| 916 | 934 |
| 917 CachedNetworkQualities::const_iterator it = | 935 CachedNetworkQualities::const_iterator it = |
| 918 cached_network_qualities_.find(current_network_id_); | 936 cached_network_qualities_.find(current_network_id_); |
| 919 | 937 |
| 920 if (it == cached_network_qualities_.end()) | 938 if (it == cached_network_qualities_.end()) |
| 921 return false; | 939 return false; |
| 922 | 940 |
| 923 nqe::internal::NetworkQuality network_quality(it->second.network_quality()); | 941 nqe::internal::NetworkQuality network_quality(it->second.network_quality()); |
| 924 | 942 |
| 925 const base::TimeTicks now = base::TimeTicks::Now(); | 943 const base::TimeTicks now = tick_clock_->NowTicks(); |
| 926 bool read_cached_estimate = false; | 944 bool read_cached_estimate = false; |
| 927 | 945 |
| 928 if (network_quality.downstream_throughput_kbps() != | 946 if (network_quality.downstream_throughput_kbps() != |
| 929 nqe::internal::kInvalidThroughput) { | 947 nqe::internal::kInvalidThroughput) { |
| 930 read_cached_estimate = true; | 948 read_cached_estimate = true; |
| 931 ThroughputObservation througphput_observation( | 949 ThroughputObservation througphput_observation( |
| 932 network_quality.downstream_throughput_kbps(), now, | 950 network_quality.downstream_throughput_kbps(), now, |
| 933 NETWORK_QUALITY_OBSERVATION_SOURCE_CACHED_ESTIMATE); | 951 NETWORK_QUALITY_OBSERVATION_SOURCE_CACHED_ESTIMATE); |
| 934 downstream_throughput_kbps_observations_.AddObservation( | 952 downstream_throughput_kbps_observations_.AddObservation( |
| 935 througphput_observation); | 953 througphput_observation); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 974 return "4G"; | 992 return "4G"; |
| 975 case EFFECTIVE_CONNECTION_TYPE_BROADBAND: | 993 case EFFECTIVE_CONNECTION_TYPE_BROADBAND: |
| 976 return "Broadband"; | 994 return "Broadband"; |
| 977 default: | 995 default: |
| 978 NOTREACHED(); | 996 NOTREACHED(); |
| 979 break; | 997 break; |
| 980 } | 998 } |
| 981 return ""; | 999 return ""; |
| 982 } | 1000 } |
| 983 | 1001 |
| 1002 void NetworkQualityEstimator::SetTickClockForTesting( |
| 1003 std::unique_ptr<base::TickClock> tick_clock) { |
| 1004 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1005 tick_clock_ = std::move(tick_clock); |
| 1006 } |
| 1007 |
| 984 void NetworkQualityEstimator::QueryExternalEstimateProvider() { | 1008 void NetworkQualityEstimator::QueryExternalEstimateProvider() { |
| 985 DCHECK(thread_checker_.CalledOnValidThread()); | 1009 DCHECK(thread_checker_.CalledOnValidThread()); |
| 986 | 1010 |
| 987 if (!external_estimate_provider_) | 1011 if (!external_estimate_provider_) |
| 988 return; | 1012 return; |
| 989 RecordExternalEstimateProviderMetrics( | 1013 RecordExternalEstimateProviderMetrics( |
| 990 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERIED); | 1014 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERIED); |
| 991 | 1015 |
| 992 base::TimeDelta time_since_last_update; | 1016 base::TimeDelta time_since_last_update; |
| 993 | 1017 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1006 } | 1030 } |
| 1007 | 1031 |
| 1008 RecordExternalEstimateProviderMetrics( | 1032 RecordExternalEstimateProviderMetrics( |
| 1009 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERY_SUCCESSFUL); | 1033 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERY_SUCCESSFUL); |
| 1010 base::TimeDelta rtt; | 1034 base::TimeDelta rtt; |
| 1011 if (external_estimate_provider_->GetRTT(&rtt)) { | 1035 if (external_estimate_provider_->GetRTT(&rtt)) { |
| 1012 RecordExternalEstimateProviderMetrics( | 1036 RecordExternalEstimateProviderMetrics( |
| 1013 EXTERNAL_ESTIMATE_PROVIDER_STATUS_RTT_AVAILABLE); | 1037 EXTERNAL_ESTIMATE_PROVIDER_STATUS_RTT_AVAILABLE); |
| 1014 UMA_HISTOGRAM_TIMES("NQE.ExternalEstimateProvider.RTT", rtt); | 1038 UMA_HISTOGRAM_TIMES("NQE.ExternalEstimateProvider.RTT", rtt); |
| 1015 rtt_observations_.AddObservation( | 1039 rtt_observations_.AddObservation( |
| 1016 RttObservation(rtt, base::TimeTicks::Now(), | 1040 RttObservation(rtt, tick_clock_->NowTicks(), |
| 1017 NETWORK_QUALITY_OBSERVATION_SOURCE_EXTERNAL_ESTIMATE)); | 1041 NETWORK_QUALITY_OBSERVATION_SOURCE_EXTERNAL_ESTIMATE)); |
| 1018 } | 1042 } |
| 1019 | 1043 |
| 1020 int32_t downstream_throughput_kbps; | 1044 int32_t downstream_throughput_kbps; |
| 1021 if (external_estimate_provider_->GetDownstreamThroughputKbps( | 1045 if (external_estimate_provider_->GetDownstreamThroughputKbps( |
| 1022 &downstream_throughput_kbps)) { | 1046 &downstream_throughput_kbps)) { |
| 1023 RecordExternalEstimateProviderMetrics( | 1047 RecordExternalEstimateProviderMetrics( |
| 1024 EXTERNAL_ESTIMATE_PROVIDER_STATUS_DOWNLINK_BANDWIDTH_AVAILABLE); | 1048 EXTERNAL_ESTIMATE_PROVIDER_STATUS_DOWNLINK_BANDWIDTH_AVAILABLE); |
| 1025 UMA_HISTOGRAM_COUNTS("NQE.ExternalEstimateProvider.DownlinkBandwidth", | 1049 UMA_HISTOGRAM_COUNTS("NQE.ExternalEstimateProvider.DownlinkBandwidth", |
| 1026 downstream_throughput_kbps); | 1050 downstream_throughput_kbps); |
| 1027 downstream_throughput_kbps_observations_.AddObservation( | 1051 downstream_throughput_kbps_observations_.AddObservation( |
| 1028 ThroughputObservation( | 1052 ThroughputObservation( |
| 1029 downstream_throughput_kbps, base::TimeTicks::Now(), | 1053 downstream_throughput_kbps, tick_clock_->NowTicks(), |
| 1030 NETWORK_QUALITY_OBSERVATION_SOURCE_EXTERNAL_ESTIMATE)); | 1054 NETWORK_QUALITY_OBSERVATION_SOURCE_EXTERNAL_ESTIMATE)); |
| 1031 } | 1055 } |
| 1032 } | 1056 } |
| 1033 | 1057 |
| 1034 void NetworkQualityEstimator::CacheNetworkQualityEstimate() { | 1058 void NetworkQualityEstimator::CacheNetworkQualityEstimate() { |
| 1035 DCHECK(thread_checker_.CalledOnValidThread()); | 1059 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1036 DCHECK_LE(cached_network_qualities_.size(), | 1060 DCHECK_LE(cached_network_qualities_.size(), |
| 1037 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 1061 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
| 1038 | 1062 |
| 1039 // If the network name is unavailable, caching should not be performed. | 1063 // If the network name is unavailable, caching should not be performed. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1075 DCHECK_LE(cached_network_qualities_.size(), | 1099 DCHECK_LE(cached_network_qualities_.size(), |
| 1076 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 1100 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
| 1077 } | 1101 } |
| 1078 | 1102 |
| 1079 void NetworkQualityEstimator::OnUpdatedRTTAvailable( | 1103 void NetworkQualityEstimator::OnUpdatedRTTAvailable( |
| 1080 SocketPerformanceWatcherFactory::Protocol protocol, | 1104 SocketPerformanceWatcherFactory::Protocol protocol, |
| 1081 const base::TimeDelta& rtt) { | 1105 const base::TimeDelta& rtt) { |
| 1082 DCHECK(thread_checker_.CalledOnValidThread()); | 1106 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1083 DCHECK_NE(nqe::internal::InvalidRTT(), rtt); | 1107 DCHECK_NE(nqe::internal::InvalidRTT(), rtt); |
| 1084 | 1108 |
| 1085 RttObservation observation(rtt, base::TimeTicks::Now(), | 1109 RttObservation observation(rtt, tick_clock_->NowTicks(), |
| 1086 ProtocolSourceToObservationSource(protocol)); | 1110 ProtocolSourceToObservationSource(protocol)); |
| 1087 NotifyObserversOfRTT(observation); | 1111 NotifyObserversOfRTT(observation); |
| 1088 rtt_observations_.AddObservation(observation); | 1112 rtt_observations_.AddObservation(observation); |
| 1089 } | 1113 } |
| 1090 | 1114 |
| 1091 void NetworkQualityEstimator::NotifyObserversOfRTT( | 1115 void NetworkQualityEstimator::NotifyObserversOfRTT( |
| 1092 const RttObservation& observation) { | 1116 const RttObservation& observation) { |
| 1093 DCHECK(thread_checker_.CalledOnValidThread()); | 1117 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1094 DCHECK_NE(nqe::internal::InvalidRTT(), observation.value); | 1118 DCHECK_NE(nqe::internal::InvalidRTT(), observation.value); |
| 1095 | 1119 |
| 1120 // Maybe recompute the effective connection type since a new RTT observation |
| 1121 // is available. |
| 1122 MaybeRecomputeEffectiveConnectionType(); |
| 1096 FOR_EACH_OBSERVER( | 1123 FOR_EACH_OBSERVER( |
| 1097 RTTObserver, rtt_observer_list_, | 1124 RTTObserver, rtt_observer_list_, |
| 1098 OnRTTObservation(observation.value.InMilliseconds(), | 1125 OnRTTObservation(observation.value.InMilliseconds(), |
| 1099 observation.timestamp, observation.source)); | 1126 observation.timestamp, observation.source)); |
| 1100 } | 1127 } |
| 1101 | 1128 |
| 1102 void NetworkQualityEstimator::NotifyObserversOfThroughput( | 1129 void NetworkQualityEstimator::NotifyObserversOfThroughput( |
| 1103 const ThroughputObservation& observation) { | 1130 const ThroughputObservation& observation) { |
| 1104 DCHECK(thread_checker_.CalledOnValidThread()); | 1131 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1105 DCHECK_NE(nqe::internal::kInvalidThroughput, observation.value); | 1132 DCHECK_NE(nqe::internal::kInvalidThroughput, observation.value); |
| 1106 | 1133 |
| 1134 // Maybe recompute the effective connection type since a new throughput |
| 1135 // observation is available. |
| 1136 MaybeRecomputeEffectiveConnectionType(); |
| 1107 FOR_EACH_OBSERVER( | 1137 FOR_EACH_OBSERVER( |
| 1108 ThroughputObserver, throughput_observer_list_, | 1138 ThroughputObserver, throughput_observer_list_, |
| 1109 OnThroughputObservation(observation.value, observation.timestamp, | 1139 OnThroughputObservation(observation.value, observation.timestamp, |
| 1110 observation.source)); | 1140 observation.source)); |
| 1111 } | 1141 } |
| 1112 | 1142 |
| 1113 void NetworkQualityEstimator::OnNewThroughputObservationAvailable( | 1143 void NetworkQualityEstimator::OnNewThroughputObservationAvailable( |
| 1114 int32_t downstream_kbps) { | 1144 int32_t downstream_kbps) { |
| 1115 DCHECK(thread_checker_.CalledOnValidThread()); | 1145 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1116 | 1146 |
| 1117 if (downstream_kbps == 0) | 1147 if (downstream_kbps == 0) |
| 1118 return; | 1148 return; |
| 1119 | 1149 |
| 1120 DCHECK_NE(nqe::internal::kInvalidThroughput, downstream_kbps); | 1150 DCHECK_NE(nqe::internal::kInvalidThroughput, downstream_kbps); |
| 1121 | 1151 |
| 1122 if (downstream_kbps > peak_network_quality_.downstream_throughput_kbps()) { | 1152 if (downstream_kbps > peak_network_quality_.downstream_throughput_kbps()) { |
| 1123 peak_network_quality_ = nqe::internal::NetworkQuality( | 1153 peak_network_quality_ = nqe::internal::NetworkQuality( |
| 1124 peak_network_quality_.http_rtt(), peak_network_quality_.transport_rtt(), | 1154 peak_network_quality_.http_rtt(), peak_network_quality_.transport_rtt(), |
| 1125 downstream_kbps); | 1155 downstream_kbps); |
| 1126 } | 1156 } |
| 1127 ThroughputObservation throughput_observation( | 1157 ThroughputObservation throughput_observation( |
| 1128 downstream_kbps, base::TimeTicks::Now(), | 1158 downstream_kbps, tick_clock_->NowTicks(), |
| 1129 NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST); | 1159 NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST); |
| 1130 downstream_throughput_kbps_observations_.AddObservation( | 1160 downstream_throughput_kbps_observations_.AddObservation( |
| 1131 throughput_observation); | 1161 throughput_observation); |
| 1132 NotifyObserversOfThroughput(throughput_observation); | 1162 NotifyObserversOfThroughput(throughput_observation); |
| 1133 } | 1163 } |
| 1134 | 1164 |
| 1165 void NetworkQualityEstimator::MaybeRecomputeEffectiveConnectionType() { |
| 1166 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1167 |
| 1168 const base::TimeTicks now = tick_clock_->NowTicks(); |
| 1169 // Recompute effective connection type only if |
| 1170 // |effective_connection_type_recomputation_interval_| has passed since it was |
| 1171 // last computed or a connection change event was observed since the last |
| 1172 // computation. Strict inequalities are used to ensure that effective |
| 1173 // connection type is recomputed on connection change events even if the clock |
| 1174 // has not updated. |
| 1175 if (now - last_effective_connection_type_computation_ < |
| 1176 effective_connection_type_recomputation_interval_ && |
| 1177 last_connection_change_ < last_effective_connection_type_computation_) { |
| 1178 return; |
| 1179 } |
| 1180 |
| 1181 const EffectiveConnectionType past_type = effective_connection_type_; |
| 1182 last_effective_connection_type_computation_ = now; |
| 1183 effective_connection_type_ = GetEffectiveConnectionType(); |
| 1184 |
| 1185 if (past_type != effective_connection_type_) |
| 1186 NotifyObserversOfEffectiveConnectionTypeChanged(); |
| 1187 } |
| 1188 |
| 1189 void NetworkQualityEstimator:: |
| 1190 NotifyObserversOfEffectiveConnectionTypeChanged() { |
| 1191 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1192 |
| 1193 // TODO(tbansal): Add hysteresis in the notification. |
| 1194 FOR_EACH_OBSERVER( |
| 1195 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, |
| 1196 OnEffectiveConnectionTypeChanged(effective_connection_type_)); |
| 1197 } |
| 1198 |
| 1135 } // namespace net | 1199 } // namespace net |
| OLD | NEW |