Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(355)

Side by Side Diff: net/nqe/network_quality_estimator.cc

Issue 2007713002: Expose NQE::OnEffectiveConnectionTypeChanged API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed bengr comments Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698