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/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 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 386 } | 391 } |
| 387 } | 392 } |
| 388 } | 393 } |
| 389 | 394 |
| 390 void NetworkQualityEstimator::AddDefaultEstimates() { | 395 void NetworkQualityEstimator::AddDefaultEstimates() { |
| 391 DCHECK(thread_checker_.CalledOnValidThread()); | 396 DCHECK(thread_checker_.CalledOnValidThread()); |
| 392 if (default_observations_[current_network_id_.type].rtt() != | 397 if (default_observations_[current_network_id_.type].rtt() != |
| 393 nqe::internal::InvalidRTT()) { | 398 nqe::internal::InvalidRTT()) { |
| 394 RttObservation rtt_observation( | 399 RttObservation rtt_observation( |
| 395 default_observations_[current_network_id_.type].rtt(), | 400 default_observations_[current_network_id_.type].rtt(), |
| 396 base::TimeTicks::Now(), | 401 tick_clock_->NowTicks(), |
| 397 NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_FROM_PLATFORM); | 402 NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_FROM_PLATFORM); |
| 398 rtt_observations_.AddObservation(rtt_observation); | 403 rtt_observations_.AddObservation(rtt_observation); |
| 399 NotifyObserversOfRTT(rtt_observation); | 404 NotifyObserversOfRTT(rtt_observation); |
| 400 } | 405 } |
| 401 if (default_observations_[current_network_id_.type] | 406 if (default_observations_[current_network_id_.type] |
| 402 .downstream_throughput_kbps() != nqe::internal::kInvalidThroughput) { | 407 .downstream_throughput_kbps() != nqe::internal::kInvalidThroughput) { |
| 403 ThroughputObservation throughput_observation( | 408 ThroughputObservation throughput_observation( |
| 404 default_observations_[current_network_id_.type] | 409 default_observations_[current_network_id_.type] |
| 405 .downstream_throughput_kbps(), | 410 .downstream_throughput_kbps(), |
| 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 downstream_throughput_kbps_observations_.AddObservation( | 413 downstream_throughput_kbps_observations_.AddObservation( |
| 409 throughput_observation); | 414 throughput_observation); |
| 410 NotifyObserversOfThroughput(throughput_observation); | 415 NotifyObserversOfThroughput(throughput_observation); |
| 411 } | 416 } |
| 412 } | 417 } |
| 413 | 418 |
| 414 NetworkQualityEstimator::~NetworkQualityEstimator() { | 419 NetworkQualityEstimator::~NetworkQualityEstimator() { |
| 415 DCHECK(thread_checker_.CalledOnValidThread()); | 420 DCHECK(thread_checker_.CalledOnValidThread()); |
| 416 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); | 421 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 443 rtt = nqe::internal::InvalidRTT(); | 448 rtt = nqe::internal::InvalidRTT(); |
| 444 | 449 |
| 445 int32_t downstream_throughput_kbps; | 450 int32_t downstream_throughput_kbps; |
| 446 if (!GetDownlinkThroughputKbpsEstimate(&downstream_throughput_kbps)) | 451 if (!GetDownlinkThroughputKbpsEstimate(&downstream_throughput_kbps)) |
| 447 downstream_throughput_kbps = nqe::internal::kInvalidThroughput; | 452 downstream_throughput_kbps = nqe::internal::kInvalidThroughput; |
| 448 | 453 |
| 449 estimated_median_network_quality_ = | 454 estimated_median_network_quality_ = |
| 450 nqe::internal::NetworkQuality(rtt, downstream_throughput_kbps); | 455 nqe::internal::NetworkQuality(rtt, downstream_throughput_kbps); |
| 451 } | 456 } |
| 452 | 457 |
| 453 base::TimeTicks now = base::TimeTicks::Now(); | 458 const base::TimeTicks now = tick_clock_->NowTicks(); |
| 454 LoadTimingInfo load_timing_info; | 459 LoadTimingInfo load_timing_info; |
| 455 request.GetLoadTimingInfo(&load_timing_info); | 460 request.GetLoadTimingInfo(&load_timing_info); |
| 456 | 461 |
| 457 // If the load timing info is unavailable, it probably means that the request | 462 // If the load timing info is unavailable, it probably means that the request |
| 458 // did not go over the network. | 463 // did not go over the network. |
| 459 if (load_timing_info.send_start.is_null() || | 464 if (load_timing_info.send_start.is_null() || |
| 460 load_timing_info.receive_headers_end.is_null()) { | 465 load_timing_info.receive_headers_end.is_null()) { |
| 461 return; | 466 return; |
| 462 } | 467 } |
| 463 | 468 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 594 void NetworkQualityEstimator::OnConnectionTypeChanged( | 599 void NetworkQualityEstimator::OnConnectionTypeChanged( |
| 595 NetworkChangeNotifier::ConnectionType type) { | 600 NetworkChangeNotifier::ConnectionType type) { |
| 596 DCHECK(thread_checker_.CalledOnValidThread()); | 601 DCHECK(thread_checker_.CalledOnValidThread()); |
| 597 | 602 |
| 598 RecordMetricsOnConnectionTypeChanged(); | 603 RecordMetricsOnConnectionTypeChanged(); |
| 599 | 604 |
| 600 // Write the estimates of the previous network to the cache. | 605 // Write the estimates of the previous network to the cache. |
| 601 CacheNetworkQualityEstimate(); | 606 CacheNetworkQualityEstimate(); |
| 602 | 607 |
| 603 // Clear the local state. | 608 // Clear the local state. |
| 604 last_connection_change_ = base::TimeTicks::Now(); | 609 last_connection_change_ = tick_clock_->NowTicks(); |
| 605 peak_network_quality_ = nqe::internal::NetworkQuality(); | 610 peak_network_quality_ = nqe::internal::NetworkQuality(); |
| 606 downstream_throughput_kbps_observations_.Clear(); | 611 downstream_throughput_kbps_observations_.Clear(); |
| 607 rtt_observations_.Clear(); | 612 rtt_observations_.Clear(); |
| 608 current_network_id_ = GetCurrentNetworkID(); | 613 current_network_id_ = GetCurrentNetworkID(); |
| 609 | 614 |
| 610 QueryExternalEstimateProvider(); | 615 QueryExternalEstimateProvider(); |
| 611 | 616 |
| 612 // Read any cached estimates for the new network. If cached estimates are | 617 // Read any cached estimates for the new network. If cached estimates are |
| 613 // unavailable, add the default estimates. | 618 // unavailable, add the default estimates. |
| 614 if (!ReadCachedNetworkQualityEstimate()) | 619 if (!ReadCachedNetworkQualityEstimate()) |
| 615 AddDefaultEstimates(); | 620 AddDefaultEstimates(); |
| 616 estimated_median_network_quality_ = nqe::internal::NetworkQuality(); | 621 estimated_median_network_quality_ = nqe::internal::NetworkQuality(); |
| 617 throughput_analyzer_->OnConnectionTypeChanged(); | 622 throughput_analyzer_->OnConnectionTypeChanged(); |
| 623 MaybeRecomputeEffectiveConnectionType(); | |
| 618 } | 624 } |
| 619 | 625 |
| 620 void NetworkQualityEstimator::RecordMetricsOnConnectionTypeChanged() const { | 626 void NetworkQualityEstimator::RecordMetricsOnConnectionTypeChanged() const { |
| 621 DCHECK(thread_checker_.CalledOnValidThread()); | 627 DCHECK(thread_checker_.CalledOnValidThread()); |
| 622 if (peak_network_quality_.rtt() != nqe::internal::InvalidRTT()) { | 628 if (peak_network_quality_.rtt() != nqe::internal::InvalidRTT()) { |
| 623 base::HistogramBase* rtt_histogram = | 629 base::HistogramBase* rtt_histogram = |
| 624 GetHistogram("FastestRTT.", current_network_id_.type, 10 * 1000); | 630 GetHistogram("FastestRTT.", current_network_id_.type, 10 * 1000); |
| 625 rtt_histogram->Add(peak_network_quality_.rtt().InMilliseconds()); | 631 rtt_histogram->Add(peak_network_quality_.rtt().InMilliseconds()); |
| 626 } | 632 } |
| 627 | 633 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 733 if (estimated_rtt_is_higher_than_threshold || | 739 if (estimated_rtt_is_higher_than_threshold || |
| 734 estimated_throughput_is_lower_than_threshold) { | 740 estimated_throughput_is_lower_than_threshold) { |
| 735 return type; | 741 return type; |
| 736 } | 742 } |
| 737 } | 743 } |
| 738 // Return the fastest connection type. | 744 // Return the fastest connection type. |
| 739 return static_cast<EffectiveConnectionType>(EFFECTIVE_CONNECTION_TYPE_LAST - | 745 return static_cast<EffectiveConnectionType>(EFFECTIVE_CONNECTION_TYPE_LAST - |
| 740 1); | 746 1); |
| 741 } | 747 } |
| 742 | 748 |
| 749 void NetworkQualityEstimator::AddEffectiveConnectionTypeObserver( | |
| 750 EffectiveConnectionTypeObserver* observer) { | |
| 751 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 752 effective_connection_type_observer_list_.AddObserver(observer); | |
| 753 } | |
| 754 | |
| 755 void NetworkQualityEstimator::RemoveEffectiveConnectionTypeObserver( | |
| 756 EffectiveConnectionTypeObserver* observer) { | |
| 757 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 758 effective_connection_type_observer_list_.RemoveObserver(observer); | |
| 759 } | |
| 760 | |
| 743 bool NetworkQualityEstimator::GetURLRequestRTTEstimate( | 761 bool NetworkQualityEstimator::GetURLRequestRTTEstimate( |
| 744 base::TimeDelta* rtt) const { | 762 base::TimeDelta* rtt) const { |
| 745 DCHECK(thread_checker_.CalledOnValidThread()); | 763 DCHECK(thread_checker_.CalledOnValidThread()); |
| 746 std::vector<NetworkQualityObservationSource> disallowed_observation_sources; | 764 std::vector<NetworkQualityObservationSource> disallowed_observation_sources; |
| 747 disallowed_observation_sources.push_back( | 765 disallowed_observation_sources.push_back( |
| 748 NETWORK_QUALITY_OBSERVATION_SOURCE_TCP); | 766 NETWORK_QUALITY_OBSERVATION_SOURCE_TCP); |
| 749 disallowed_observation_sources.push_back( | 767 disallowed_observation_sources.push_back( |
| 750 NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC); | 768 NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC); |
| 751 *rtt = GetRTTEstimateInternal(disallowed_observation_sources, | 769 *rtt = GetRTTEstimateInternal(disallowed_observation_sources, |
| 752 base::TimeTicks(), 50); | 770 base::TimeTicks(), 50); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 912 if (it == cached_network_qualities_.end()) | 930 if (it == cached_network_qualities_.end()) |
| 913 return false; | 931 return false; |
| 914 | 932 |
| 915 nqe::internal::NetworkQuality network_quality(it->second.network_quality()); | 933 nqe::internal::NetworkQuality network_quality(it->second.network_quality()); |
| 916 | 934 |
| 917 DCHECK_NE(nqe::internal::InvalidRTT(), network_quality.rtt()); | 935 DCHECK_NE(nqe::internal::InvalidRTT(), network_quality.rtt()); |
| 918 DCHECK_NE(nqe::internal::kInvalidThroughput, | 936 DCHECK_NE(nqe::internal::kInvalidThroughput, |
| 919 network_quality.downstream_throughput_kbps()); | 937 network_quality.downstream_throughput_kbps()); |
| 920 | 938 |
| 921 ThroughputObservation througphput_observation( | 939 ThroughputObservation througphput_observation( |
| 922 network_quality.downstream_throughput_kbps(), base::TimeTicks::Now(), | 940 network_quality.downstream_throughput_kbps(), tick_clock_->NowTicks(), |
| 923 NETWORK_QUALITY_OBSERVATION_SOURCE_CACHED_ESTIMATE); | 941 NETWORK_QUALITY_OBSERVATION_SOURCE_CACHED_ESTIMATE); |
| 924 downstream_throughput_kbps_observations_.AddObservation( | 942 downstream_throughput_kbps_observations_.AddObservation( |
| 925 througphput_observation); | 943 througphput_observation); |
| 926 NotifyObserversOfThroughput(througphput_observation); | 944 NotifyObserversOfThroughput(througphput_observation); |
| 927 | 945 |
| 928 RttObservation rtt_observation( | 946 RttObservation rtt_observation( |
| 929 network_quality.rtt(), base::TimeTicks::Now(), | 947 network_quality.rtt(), tick_clock_->NowTicks(), |
| 930 NETWORK_QUALITY_OBSERVATION_SOURCE_CACHED_ESTIMATE); | 948 NETWORK_QUALITY_OBSERVATION_SOURCE_CACHED_ESTIMATE); |
| 931 rtt_observations_.AddObservation(rtt_observation); | 949 rtt_observations_.AddObservation(rtt_observation); |
| 932 NotifyObserversOfRTT(rtt_observation); | 950 NotifyObserversOfRTT(rtt_observation); |
| 933 | 951 |
| 934 return true; | 952 return true; |
| 935 } | 953 } |
| 936 | 954 |
| 937 void NetworkQualityEstimator::OnUpdatedEstimateAvailable() { | 955 void NetworkQualityEstimator::OnUpdatedEstimateAvailable() { |
| 938 DCHECK(thread_checker_.CalledOnValidThread()); | 956 DCHECK(thread_checker_.CalledOnValidThread()); |
| 939 DCHECK(external_estimate_provider_); | 957 DCHECK(external_estimate_provider_); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 960 return "4G"; | 978 return "4G"; |
| 961 case EFFECTIVE_CONNECTION_TYPE_BROADBAND: | 979 case EFFECTIVE_CONNECTION_TYPE_BROADBAND: |
| 962 return "Broadband"; | 980 return "Broadband"; |
| 963 default: | 981 default: |
| 964 NOTREACHED(); | 982 NOTREACHED(); |
| 965 break; | 983 break; |
| 966 } | 984 } |
| 967 return ""; | 985 return ""; |
| 968 } | 986 } |
| 969 | 987 |
| 988 void NetworkQualityEstimator::SetTickClockForTesting( | |
| 989 std::unique_ptr<base::TickClock> tick_clock) { | |
| 990 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 991 tick_clock_ = std::move(tick_clock); | |
| 992 } | |
| 993 | |
| 970 void NetworkQualityEstimator::QueryExternalEstimateProvider() { | 994 void NetworkQualityEstimator::QueryExternalEstimateProvider() { |
| 971 DCHECK(thread_checker_.CalledOnValidThread()); | 995 DCHECK(thread_checker_.CalledOnValidThread()); |
| 972 | 996 |
| 973 if (!external_estimate_provider_) | 997 if (!external_estimate_provider_) |
| 974 return; | 998 return; |
| 975 RecordExternalEstimateProviderMetrics( | 999 RecordExternalEstimateProviderMetrics( |
| 976 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERIED); | 1000 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERIED); |
| 977 | 1001 |
| 978 base::TimeDelta time_since_last_update; | 1002 base::TimeDelta time_since_last_update; |
| 979 | 1003 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 992 } | 1016 } |
| 993 | 1017 |
| 994 RecordExternalEstimateProviderMetrics( | 1018 RecordExternalEstimateProviderMetrics( |
| 995 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERY_SUCCESSFUL); | 1019 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERY_SUCCESSFUL); |
| 996 base::TimeDelta rtt; | 1020 base::TimeDelta rtt; |
| 997 if (external_estimate_provider_->GetRTT(&rtt)) { | 1021 if (external_estimate_provider_->GetRTT(&rtt)) { |
| 998 RecordExternalEstimateProviderMetrics( | 1022 RecordExternalEstimateProviderMetrics( |
| 999 EXTERNAL_ESTIMATE_PROVIDER_STATUS_RTT_AVAILABLE); | 1023 EXTERNAL_ESTIMATE_PROVIDER_STATUS_RTT_AVAILABLE); |
| 1000 UMA_HISTOGRAM_TIMES("NQE.ExternalEstimateProvider.RTT", rtt); | 1024 UMA_HISTOGRAM_TIMES("NQE.ExternalEstimateProvider.RTT", rtt); |
| 1001 rtt_observations_.AddObservation( | 1025 rtt_observations_.AddObservation( |
| 1002 RttObservation(rtt, base::TimeTicks::Now(), | 1026 RttObservation(rtt, tick_clock_->NowTicks(), |
| 1003 NETWORK_QUALITY_OBSERVATION_SOURCE_EXTERNAL_ESTIMATE)); | 1027 NETWORK_QUALITY_OBSERVATION_SOURCE_EXTERNAL_ESTIMATE)); |
| 1004 } | 1028 } |
| 1005 | 1029 |
| 1006 int32_t downstream_throughput_kbps; | 1030 int32_t downstream_throughput_kbps; |
| 1007 if (external_estimate_provider_->GetDownstreamThroughputKbps( | 1031 if (external_estimate_provider_->GetDownstreamThroughputKbps( |
| 1008 &downstream_throughput_kbps)) { | 1032 &downstream_throughput_kbps)) { |
| 1009 RecordExternalEstimateProviderMetrics( | 1033 RecordExternalEstimateProviderMetrics( |
| 1010 EXTERNAL_ESTIMATE_PROVIDER_STATUS_DOWNLINK_BANDWIDTH_AVAILABLE); | 1034 EXTERNAL_ESTIMATE_PROVIDER_STATUS_DOWNLINK_BANDWIDTH_AVAILABLE); |
| 1011 UMA_HISTOGRAM_COUNTS("NQE.ExternalEstimateProvider.DownlinkBandwidth", | 1035 UMA_HISTOGRAM_COUNTS("NQE.ExternalEstimateProvider.DownlinkBandwidth", |
| 1012 downstream_throughput_kbps); | 1036 downstream_throughput_kbps); |
| 1013 downstream_throughput_kbps_observations_.AddObservation( | 1037 downstream_throughput_kbps_observations_.AddObservation( |
| 1014 ThroughputObservation( | 1038 ThroughputObservation( |
| 1015 downstream_throughput_kbps, base::TimeTicks::Now(), | 1039 downstream_throughput_kbps, tick_clock_->NowTicks(), |
| 1016 NETWORK_QUALITY_OBSERVATION_SOURCE_EXTERNAL_ESTIMATE)); | 1040 NETWORK_QUALITY_OBSERVATION_SOURCE_EXTERNAL_ESTIMATE)); |
| 1017 } | 1041 } |
| 1018 } | 1042 } |
| 1019 | 1043 |
| 1020 void NetworkQualityEstimator::CacheNetworkQualityEstimate() { | 1044 void NetworkQualityEstimator::CacheNetworkQualityEstimate() { |
| 1021 DCHECK(thread_checker_.CalledOnValidThread()); | 1045 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1022 DCHECK_LE(cached_network_qualities_.size(), | 1046 DCHECK_LE(cached_network_qualities_.size(), |
| 1023 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 1047 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
| 1024 | 1048 |
| 1025 // If the network name is unavailable, caching should not be performed. | 1049 // If the network name is unavailable, caching should not be performed. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1058 nqe::internal::CachedNetworkQuality(network_quality))); | 1082 nqe::internal::CachedNetworkQuality(network_quality))); |
| 1059 DCHECK_LE(cached_network_qualities_.size(), | 1083 DCHECK_LE(cached_network_qualities_.size(), |
| 1060 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 1084 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
| 1061 } | 1085 } |
| 1062 | 1086 |
| 1063 void NetworkQualityEstimator::OnUpdatedRTTAvailable( | 1087 void NetworkQualityEstimator::OnUpdatedRTTAvailable( |
| 1064 SocketPerformanceWatcherFactory::Protocol protocol, | 1088 SocketPerformanceWatcherFactory::Protocol protocol, |
| 1065 const base::TimeDelta& rtt) { | 1089 const base::TimeDelta& rtt) { |
| 1066 DCHECK(thread_checker_.CalledOnValidThread()); | 1090 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1067 | 1091 |
| 1068 RttObservation observation(rtt, base::TimeTicks::Now(), | 1092 RttObservation observation(rtt, tick_clock_->NowTicks(), |
| 1069 ProtocolSourceToObservationSource(protocol)); | 1093 ProtocolSourceToObservationSource(protocol)); |
| 1070 NotifyObserversOfRTT(observation); | 1094 NotifyObserversOfRTT(observation); |
| 1071 rtt_observations_.AddObservation(observation); | 1095 rtt_observations_.AddObservation(observation); |
| 1072 } | 1096 } |
| 1073 | 1097 |
| 1074 void NetworkQualityEstimator::NotifyObserversOfRTT( | 1098 void NetworkQualityEstimator::NotifyObserversOfRTT( |
| 1075 const RttObservation& observation) { | 1099 const RttObservation& observation) { |
| 1100 // May be recompute the effective connection type since a new RTT observation | |
|
bengr
2016/05/27 19:46:01
May be -> Maybe
tbansal1
2016/05/28 01:20:42
Done.
| |
| 1101 // is available. | |
| 1102 MaybeRecomputeEffectiveConnectionType(); | |
| 1076 FOR_EACH_OBSERVER( | 1103 FOR_EACH_OBSERVER( |
| 1077 RTTObserver, rtt_observer_list_, | 1104 RTTObserver, rtt_observer_list_, |
| 1078 OnRTTObservation(observation.value.InMilliseconds(), | 1105 OnRTTObservation(observation.value.InMilliseconds(), |
| 1079 observation.timestamp, observation.source)); | 1106 observation.timestamp, observation.source)); |
| 1080 } | 1107 } |
| 1081 | 1108 |
| 1082 void NetworkQualityEstimator::NotifyObserversOfThroughput( | 1109 void NetworkQualityEstimator::NotifyObserversOfThroughput( |
| 1083 const ThroughputObservation& observation) { | 1110 const ThroughputObservation& observation) { |
| 1111 // May be recompute the effective connection type since a new throughput | |
| 1112 // observation is available. | |
| 1113 MaybeRecomputeEffectiveConnectionType(); | |
| 1084 FOR_EACH_OBSERVER( | 1114 FOR_EACH_OBSERVER( |
| 1085 ThroughputObserver, throughput_observer_list_, | 1115 ThroughputObserver, throughput_observer_list_, |
| 1086 OnThroughputObservation(observation.value, observation.timestamp, | 1116 OnThroughputObservation(observation.value, observation.timestamp, |
| 1087 observation.source)); | 1117 observation.source)); |
| 1088 } | 1118 } |
| 1089 | 1119 |
| 1090 void NetworkQualityEstimator::OnNewThroughputObservationAvailable( | 1120 void NetworkQualityEstimator::OnNewThroughputObservationAvailable( |
| 1091 int32_t downstream_kbps) { | 1121 int32_t downstream_kbps) { |
| 1092 DCHECK(thread_checker_.CalledOnValidThread()); | 1122 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1093 | 1123 |
| 1094 if (downstream_kbps == 0) | 1124 if (downstream_kbps == 0) |
| 1095 return; | 1125 return; |
| 1096 | 1126 |
| 1097 if (downstream_kbps > peak_network_quality_.downstream_throughput_kbps()) { | 1127 if (downstream_kbps > peak_network_quality_.downstream_throughput_kbps()) { |
| 1098 peak_network_quality_ = nqe::internal::NetworkQuality( | 1128 peak_network_quality_ = nqe::internal::NetworkQuality( |
| 1099 peak_network_quality_.rtt(), downstream_kbps); | 1129 peak_network_quality_.rtt(), downstream_kbps); |
| 1100 } | 1130 } |
| 1101 ThroughputObservation throughput_observation( | 1131 ThroughputObservation throughput_observation( |
| 1102 downstream_kbps, base::TimeTicks::Now(), | 1132 downstream_kbps, tick_clock_->NowTicks(), |
| 1103 NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST); | 1133 NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST); |
| 1104 downstream_throughput_kbps_observations_.AddObservation( | 1134 downstream_throughput_kbps_observations_.AddObservation( |
| 1105 throughput_observation); | 1135 throughput_observation); |
| 1106 NotifyObserversOfThroughput(throughput_observation); | 1136 NotifyObserversOfThroughput(throughput_observation); |
| 1107 } | 1137 } |
| 1108 | 1138 |
| 1139 void NetworkQualityEstimator::MaybeRecomputeEffectiveConnectionType() { | |
| 1140 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 1141 | |
| 1142 const base::TimeTicks now = tick_clock_->NowTicks(); | |
| 1143 // Recompute effective connection type only if | |
| 1144 // |effective_connection_type_recomputation_interval_| has passed since it was | |
| 1145 // last computed or a connection change event was observed since the last | |
| 1146 // computation. | |
| 1147 if (now - last_effective_connection_type_computation_ <= | |
| 1148 effective_connection_type_recomputation_interval_ && | |
| 1149 last_connection_change_ < last_effective_connection_type_computation_) { | |
|
bengr
2016/05/27 19:46:01
nit: Why is this < and not <=?
tbansal1
2016/05/28 01:20:42
Changed both to < for consistency. Also, added com
| |
| 1150 return; | |
| 1151 } | |
| 1152 | |
| 1153 const EffectiveConnectionType past_type = effective_connection_type_; | |
| 1154 last_effective_connection_type_computation_ = now; | |
| 1155 effective_connection_type_ = GetEffectiveConnectionType(); | |
|
bengr
2016/05/27 19:46:01
If we never change type, don't we wind up computin
tbansal1
2016/05/28 01:20:42
If there is no connection change, then there would
bengr
2016/05/31 17:39:24
Acknowledged.
| |
| 1156 | |
| 1157 if (past_type != effective_connection_type_) | |
| 1158 NotifyObserversOfEffectiveConnectionTypeChanged(); | |
| 1159 } | |
| 1160 | |
| 1161 void NetworkQualityEstimator:: | |
| 1162 NotifyObserversOfEffectiveConnectionTypeChanged() { | |
| 1163 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 1164 | |
| 1165 // TODO(tbansal): Add hysteresis in the notification. | |
| 1166 FOR_EACH_OBSERVER( | |
| 1167 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, | |
| 1168 OnEffectiveConnectionTypeChanged(effective_connection_type_)); | |
| 1169 } | |
| 1170 | |
| 1109 } // namespace net | 1171 } // namespace net |
| OLD | NEW |