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

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: Rebased 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
« no previous file with comments | « net/nqe/network_quality_estimator.h ('k') | net/nqe/network_quality_estimator_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 } 400 }
396 } 401 }
397 402
398 void NetworkQualityEstimator::AddDefaultEstimates() { 403 void NetworkQualityEstimator::AddDefaultEstimates() {
399 DCHECK(thread_checker_.CalledOnValidThread()); 404 DCHECK(thread_checker_.CalledOnValidThread());
400 405
401 if (default_observations_[current_network_id_.type].http_rtt() != 406 if (default_observations_[current_network_id_.type].http_rtt() !=
402 nqe::internal::InvalidRTT()) { 407 nqe::internal::InvalidRTT()) {
403 RttObservation rtt_observation( 408 RttObservation rtt_observation(
404 default_observations_[current_network_id_.type].http_rtt(), 409 default_observations_[current_network_id_.type].http_rtt(),
405 base::TimeTicks::Now(), 410 tick_clock_->NowTicks(),
406 NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_FROM_PLATFORM); 411 NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_FROM_PLATFORM);
407 rtt_observations_.AddObservation(rtt_observation); 412 rtt_observations_.AddObservation(rtt_observation);
408 NotifyObserversOfRTT(rtt_observation); 413 NotifyObserversOfRTT(rtt_observation);
409 } 414 }
410 415
411 if (default_observations_[current_network_id_.type] 416 if (default_observations_[current_network_id_.type]
412 .downstream_throughput_kbps() != nqe::internal::kInvalidThroughput) { 417 .downstream_throughput_kbps() != nqe::internal::kInvalidThroughput) {
413 ThroughputObservation throughput_observation( 418 ThroughputObservation throughput_observation(
414 default_observations_[current_network_id_.type] 419 default_observations_[current_network_id_.type]
415 .downstream_throughput_kbps(), 420 .downstream_throughput_kbps(),
416 base::TimeTicks::Now(), 421 tick_clock_->NowTicks(),
417 NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_FROM_PLATFORM); 422 NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_FROM_PLATFORM);
418 downstream_throughput_kbps_observations_.AddObservation( 423 downstream_throughput_kbps_observations_.AddObservation(
419 throughput_observation); 424 throughput_observation);
420 NotifyObserversOfThroughput(throughput_observation); 425 NotifyObserversOfThroughput(throughput_observation);
421 } 426 }
422 } 427 }
423 428
424 NetworkQualityEstimator::~NetworkQualityEstimator() { 429 NetworkQualityEstimator::~NetworkQualityEstimator() {
425 DCHECK(thread_checker_.CalledOnValidThread()); 430 DCHECK(thread_checker_.CalledOnValidThread());
426 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); 431 NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
(...skipping 29 matching lines...) Expand all
456 if (!GetDownlinkThroughputKbpsEstimate(&downstream_throughput_kbps)) 461 if (!GetDownlinkThroughputKbpsEstimate(&downstream_throughput_kbps))
457 downstream_throughput_kbps = nqe::internal::kInvalidThroughput; 462 downstream_throughput_kbps = nqe::internal::kInvalidThroughput;
458 463
459 estimated_median_network_quality_ = nqe::internal::NetworkQuality( 464 estimated_median_network_quality_ = nqe::internal::NetworkQuality(
460 estimated_http_rtt, nqe::internal::InvalidRTT(), 465 estimated_http_rtt, nqe::internal::InvalidRTT(),
461 downstream_throughput_kbps); 466 downstream_throughput_kbps);
462 467
463 RecordMetricsOnMainFrameRequest(); 468 RecordMetricsOnMainFrameRequest();
464 } 469 }
465 470
466 base::TimeTicks now = base::TimeTicks::Now(); 471 const base::TimeTicks now = tick_clock_->NowTicks();
467 LoadTimingInfo load_timing_info; 472 LoadTimingInfo load_timing_info;
468 request.GetLoadTimingInfo(&load_timing_info); 473 request.GetLoadTimingInfo(&load_timing_info);
469 474
470 // If the load timing info is unavailable, it probably means that the request 475 // If the load timing info is unavailable, it probably means that the request
471 // did not go over the network. 476 // did not go over the network.
472 if (load_timing_info.send_start.is_null() || 477 if (load_timing_info.send_start.is_null() ||
473 load_timing_info.receive_headers_end.is_null()) { 478 load_timing_info.receive_headers_end.is_null()) {
474 return; 479 return;
475 } 480 }
476 481
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 void NetworkQualityEstimator::OnConnectionTypeChanged( 609 void NetworkQualityEstimator::OnConnectionTypeChanged(
605 NetworkChangeNotifier::ConnectionType type) { 610 NetworkChangeNotifier::ConnectionType type) {
606 DCHECK(thread_checker_.CalledOnValidThread()); 611 DCHECK(thread_checker_.CalledOnValidThread());
607 612
608 RecordMetricsOnConnectionTypeChanged(); 613 RecordMetricsOnConnectionTypeChanged();
609 614
610 // Write the estimates of the previous network to the cache. 615 // Write the estimates of the previous network to the cache.
611 CacheNetworkQualityEstimate(); 616 CacheNetworkQualityEstimate();
612 617
613 // Clear the local state. 618 // Clear the local state.
614 last_connection_change_ = base::TimeTicks::Now(); 619 last_connection_change_ = tick_clock_->NowTicks();
615 peak_network_quality_ = nqe::internal::NetworkQuality(); 620 peak_network_quality_ = nqe::internal::NetworkQuality();
616 downstream_throughput_kbps_observations_.Clear(); 621 downstream_throughput_kbps_observations_.Clear();
617 rtt_observations_.Clear(); 622 rtt_observations_.Clear();
618 current_network_id_ = GetCurrentNetworkID(); 623 current_network_id_ = GetCurrentNetworkID();
619 624
620 // Query the external estimate provider on certain connection types. Once the 625 // Query the external estimate provider on certain connection types. Once the
621 // updated estimates are available, OnUpdatedEstimateAvailable will be called 626 // updated estimates are available, OnUpdatedEstimateAvailable will be called
622 // by |external_estimate_provider_| with updated estimates. 627 // by |external_estimate_provider_| with updated estimates.
623 if (external_estimate_provider_ && 628 if (external_estimate_provider_ &&
624 current_network_id_.type != NetworkChangeNotifier::CONNECTION_NONE && 629 current_network_id_.type != NetworkChangeNotifier::CONNECTION_NONE &&
625 current_network_id_.type != NetworkChangeNotifier::CONNECTION_UNKNOWN && 630 current_network_id_.type != NetworkChangeNotifier::CONNECTION_UNKNOWN &&
626 current_network_id_.type != NetworkChangeNotifier::CONNECTION_ETHERNET && 631 current_network_id_.type != NetworkChangeNotifier::CONNECTION_ETHERNET &&
627 current_network_id_.type != NetworkChangeNotifier::CONNECTION_BLUETOOTH) { 632 current_network_id_.type != NetworkChangeNotifier::CONNECTION_BLUETOOTH) {
628 RecordExternalEstimateProviderMetrics( 633 RecordExternalEstimateProviderMetrics(
629 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERIED); 634 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERIED);
630 external_estimate_provider_->Update(); 635 external_estimate_provider_->Update();
631 } 636 }
632 637
633 // Read any cached estimates for the new network. If cached estimates are 638 // Read any cached estimates for the new network. If cached estimates are
634 // unavailable, add the default estimates. 639 // unavailable, add the default estimates.
635 if (!ReadCachedNetworkQualityEstimate()) 640 if (!ReadCachedNetworkQualityEstimate())
636 AddDefaultEstimates(); 641 AddDefaultEstimates();
637 estimated_median_network_quality_ = nqe::internal::NetworkQuality(); 642 estimated_median_network_quality_ = nqe::internal::NetworkQuality();
638 throughput_analyzer_->OnConnectionTypeChanged(); 643 throughput_analyzer_->OnConnectionTypeChanged();
644 MaybeRecomputeEffectiveConnectionType();
639 } 645 }
640 646
641 void NetworkQualityEstimator::RecordMetricsOnConnectionTypeChanged() const { 647 void NetworkQualityEstimator::RecordMetricsOnConnectionTypeChanged() const {
642 DCHECK(thread_checker_.CalledOnValidThread()); 648 DCHECK(thread_checker_.CalledOnValidThread());
643 if (peak_network_quality_.http_rtt() != nqe::internal::InvalidRTT()) { 649 if (peak_network_quality_.http_rtt() != nqe::internal::InvalidRTT()) {
644 base::HistogramBase* rtt_histogram = 650 base::HistogramBase* rtt_histogram =
645 GetHistogram("FastestRTT.", current_network_id_.type, 10 * 1000); 651 GetHistogram("FastestRTT.", current_network_id_.type, 10 * 1000);
646 rtt_histogram->Add(peak_network_quality_.http_rtt().InMilliseconds()); 652 rtt_histogram->Add(peak_network_quality_.http_rtt().InMilliseconds());
647 } 653 }
648 654
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 if (estimated_http_rtt_is_higher_than_threshold || 797 if (estimated_http_rtt_is_higher_than_threshold ||
792 estimated_throughput_is_lower_than_threshold) { 798 estimated_throughput_is_lower_than_threshold) {
793 return type; 799 return type;
794 } 800 }
795 } 801 }
796 // Return the fastest connection type. 802 // Return the fastest connection type.
797 return static_cast<EffectiveConnectionType>(EFFECTIVE_CONNECTION_TYPE_LAST - 803 return static_cast<EffectiveConnectionType>(EFFECTIVE_CONNECTION_TYPE_LAST -
798 1); 804 1);
799 } 805 }
800 806
807 void NetworkQualityEstimator::AddEffectiveConnectionTypeObserver(
808 EffectiveConnectionTypeObserver* observer) {
809 DCHECK(thread_checker_.CalledOnValidThread());
810 effective_connection_type_observer_list_.AddObserver(observer);
811 }
812
813 void NetworkQualityEstimator::RemoveEffectiveConnectionTypeObserver(
814 EffectiveConnectionTypeObserver* observer) {
815 DCHECK(thread_checker_.CalledOnValidThread());
816 effective_connection_type_observer_list_.RemoveObserver(observer);
817 }
818
801 bool NetworkQualityEstimator::GetHttpRTTEstimate(base::TimeDelta* rtt) const { 819 bool NetworkQualityEstimator::GetHttpRTTEstimate(base::TimeDelta* rtt) const {
802 DCHECK(thread_checker_.CalledOnValidThread()); 820 DCHECK(thread_checker_.CalledOnValidThread());
803 return GetRecentHttpRTTMedian(base::TimeTicks(), rtt); 821 return GetRecentHttpRTTMedian(base::TimeTicks(), rtt);
804 } 822 }
805 823
806 bool NetworkQualityEstimator::GetTransportRTTEstimate( 824 bool NetworkQualityEstimator::GetTransportRTTEstimate(
807 base::TimeDelta* rtt) const { 825 base::TimeDelta* rtt) const {
808 DCHECK(thread_checker_.CalledOnValidThread()); 826 DCHECK(thread_checker_.CalledOnValidThread());
809 return GetRecentTransportRTTMedian(base::TimeTicks(), rtt); 827 return GetRecentTransportRTTMedian(base::TimeTicks(), rtt);
810 } 828 }
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 return false; 961 return false;
944 962
945 CachedNetworkQualities::const_iterator it = 963 CachedNetworkQualities::const_iterator it =
946 cached_network_qualities_.find(current_network_id_); 964 cached_network_qualities_.find(current_network_id_);
947 965
948 if (it == cached_network_qualities_.end()) 966 if (it == cached_network_qualities_.end())
949 return false; 967 return false;
950 968
951 nqe::internal::NetworkQuality network_quality(it->second.network_quality()); 969 nqe::internal::NetworkQuality network_quality(it->second.network_quality());
952 970
953 const base::TimeTicks now = base::TimeTicks::Now(); 971 const base::TimeTicks now = tick_clock_->NowTicks();
954 bool read_cached_estimate = false; 972 bool read_cached_estimate = false;
955 973
956 if (network_quality.downstream_throughput_kbps() != 974 if (network_quality.downstream_throughput_kbps() !=
957 nqe::internal::kInvalidThroughput) { 975 nqe::internal::kInvalidThroughput) {
958 read_cached_estimate = true; 976 read_cached_estimate = true;
959 ThroughputObservation througphput_observation( 977 ThroughputObservation througphput_observation(
960 network_quality.downstream_throughput_kbps(), now, 978 network_quality.downstream_throughput_kbps(), now,
961 NETWORK_QUALITY_OBSERVATION_SOURCE_CACHED_ESTIMATE); 979 NETWORK_QUALITY_OBSERVATION_SOURCE_CACHED_ESTIMATE);
962 downstream_throughput_kbps_observations_.AddObservation( 980 downstream_throughput_kbps_observations_.AddObservation(
963 througphput_observation); 981 througphput_observation);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 return "4G"; 1042 return "4G";
1025 case EFFECTIVE_CONNECTION_TYPE_BROADBAND: 1043 case EFFECTIVE_CONNECTION_TYPE_BROADBAND:
1026 return "Broadband"; 1044 return "Broadband";
1027 default: 1045 default:
1028 NOTREACHED(); 1046 NOTREACHED();
1029 break; 1047 break;
1030 } 1048 }
1031 return ""; 1049 return "";
1032 } 1050 }
1033 1051
1052 void NetworkQualityEstimator::SetTickClockForTesting(
1053 std::unique_ptr<base::TickClock> tick_clock) {
1054 DCHECK(thread_checker_.CalledOnValidThread());
1055 tick_clock_ = std::move(tick_clock);
1056 }
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.
1040 if (current_network_id_.id.empty()) 1064 if (current_network_id_.id.empty())
1041 return; 1065 return;
1042 1066
1043 base::TimeDelta http_rtt = nqe::internal::InvalidRTT(); 1067 base::TimeDelta http_rtt = nqe::internal::InvalidRTT();
(...skipping 31 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
« no previous file with comments | « net/nqe/network_quality_estimator.h ('k') | net/nqe/network_quality_estimator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698