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

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

Issue 2266663002: NQE: Change GetEffectiveConnectionType to return last ECT (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed bengr comments Created 4 years, 3 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>
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 last_connection_change_(tick_clock_->NowTicks()), 379 last_connection_change_(tick_clock_->NowTicks()),
380 current_network_id_(nqe::internal::NetworkID( 380 current_network_id_(nqe::internal::NetworkID(
381 NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, 381 NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN,
382 std::string())), 382 std::string())),
383 downstream_throughput_kbps_observations_(weight_multiplier_per_second_), 383 downstream_throughput_kbps_observations_(weight_multiplier_per_second_),
384 rtt_observations_(weight_multiplier_per_second_), 384 rtt_observations_(weight_multiplier_per_second_),
385 effective_connection_type_at_last_main_frame_( 385 effective_connection_type_at_last_main_frame_(
386 EFFECTIVE_CONNECTION_TYPE_UNKNOWN), 386 EFFECTIVE_CONNECTION_TYPE_UNKNOWN),
387 external_estimate_provider_(std::move(external_estimates_provider)), 387 external_estimate_provider_(std::move(external_estimates_provider)),
388 effective_connection_type_recomputation_interval_( 388 effective_connection_type_recomputation_interval_(
389 base::TimeDelta::FromSeconds(15)), 389 base::TimeDelta::FromSeconds(10)),
390 rtt_observations_size_at_last_ect_computation_(0), 390 rtt_observations_size_at_last_ect_computation_(0),
391 throughput_observations_size_at_last_ect_computation_(0), 391 throughput_observations_size_at_last_ect_computation_(0),
392 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), 392 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN),
393 min_signal_strength_since_connection_change_(INT32_MAX), 393 min_signal_strength_since_connection_change_(INT32_MAX),
394 max_signal_strength_since_connection_change_(INT32_MIN), 394 max_signal_strength_since_connection_change_(INT32_MIN),
395 correlation_uma_logging_probability_( 395 correlation_uma_logging_probability_(
396 GetDoubleValueForVariationParamWithDefaultValue( 396 GetDoubleValueForVariationParamWithDefaultValue(
397 variation_params, 397 variation_params,
398 "correlation_logging_probability", 398 "correlation_logging_probability",
399 0.0)), 399 0.0)),
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 if (!GetTransportRTT(&estimated_transport_rtt)) 654 if (!GetTransportRTT(&estimated_transport_rtt))
655 estimated_transport_rtt = nqe::internal::InvalidRTT(); 655 estimated_transport_rtt = nqe::internal::InvalidRTT();
656 656
657 int32_t downstream_throughput_kbps; 657 int32_t downstream_throughput_kbps;
658 if (!GetDownlinkThroughputKbps(&downstream_throughput_kbps)) 658 if (!GetDownlinkThroughputKbps(&downstream_throughput_kbps))
659 downstream_throughput_kbps = nqe::internal::kInvalidThroughput; 659 downstream_throughput_kbps = nqe::internal::kInvalidThroughput;
660 660
661 estimated_quality_at_last_main_frame_ = nqe::internal::NetworkQuality( 661 estimated_quality_at_last_main_frame_ = nqe::internal::NetworkQuality(
662 estimated_http_rtt, estimated_transport_rtt, 662 estimated_http_rtt, estimated_transport_rtt,
663 downstream_throughput_kbps); 663 downstream_throughput_kbps);
664
665 ComputeEffectiveConnectionType();
664 effective_connection_type_at_last_main_frame_ = 666 effective_connection_type_at_last_main_frame_ =
665 GetEffectiveConnectionType(); 667 GetEffectiveConnectionType();
666 668
667 RecordMetricsOnMainFrameRequest(); 669 RecordMetricsOnMainFrameRequest();
668 MaybeQueryExternalEstimateProvider(); 670 MaybeQueryExternalEstimateProvider();
669 671
670 // Post the tasks which will run in the future and record the estimation 672 // Post the tasks which will run in the future and record the estimation
671 // accuracy based on the observations received between now and the time of 673 // accuracy based on the observations received between now and the time of
672 // task execution. Posting the task at different intervals makes it 674 // task execution. Posting the task at different intervals makes it
673 // possible to measure the accuracy by comparing the estimate with the 675 // possible to measure the accuracy by comparing the estimate with the
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 RecordNetworkIDAvailability(); 1031 RecordNetworkIDAvailability();
1030 1032
1031 MaybeQueryExternalEstimateProvider(); 1033 MaybeQueryExternalEstimateProvider();
1032 1034
1033 // Read any cached estimates for the new network. If cached estimates are 1035 // Read any cached estimates for the new network. If cached estimates are
1034 // unavailable, add the default estimates. 1036 // unavailable, add the default estimates.
1035 if (!ReadCachedNetworkQualityEstimate()) 1037 if (!ReadCachedNetworkQualityEstimate())
1036 AddDefaultEstimates(); 1038 AddDefaultEstimates();
1037 estimated_quality_at_last_main_frame_ = nqe::internal::NetworkQuality(); 1039 estimated_quality_at_last_main_frame_ = nqe::internal::NetworkQuality();
1038 throughput_analyzer_->OnConnectionTypeChanged(); 1040 throughput_analyzer_->OnConnectionTypeChanged();
1039 MaybeRecomputeEffectiveConnectionType(); 1041 MaybeComputeEffectiveConnectionType();
1040 UpdateSignalStrength(); 1042 UpdateSignalStrength();
1041 } 1043 }
1042 1044
1043 void NetworkQualityEstimator::MaybeQueryExternalEstimateProvider() const { 1045 void NetworkQualityEstimator::MaybeQueryExternalEstimateProvider() const {
1044 // Query the external estimate provider on certain connection types. Once the 1046 // Query the external estimate provider on certain connection types. Once the
1045 // updated estimates are available, OnUpdatedEstimateAvailable will be called 1047 // updated estimates are available, OnUpdatedEstimateAvailable will be called
1046 // by |external_estimate_provider_| with updated estimates. 1048 // by |external_estimate_provider_| with updated estimates.
1047 if (external_estimate_provider_ && 1049 if (external_estimate_provider_ &&
1048 current_network_id_.type != NetworkChangeNotifier::CONNECTION_NONE && 1050 current_network_id_.type != NetworkChangeNotifier::CONNECTION_NONE &&
1049 current_network_id_.type != NetworkChangeNotifier::CONNECTION_UNKNOWN && 1051 current_network_id_.type != NetworkChangeNotifier::CONNECTION_UNKNOWN &&
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 base::Histogram::FactoryGet( 1186 base::Histogram::FactoryGet(
1185 std::string("NQE.MainFrame.EffectiveConnectionType.") + 1187 std::string("NQE.MainFrame.EffectiveConnectionType.") +
1186 GetNameForConnectionType(current_network_id_.type), 1188 GetNameForConnectionType(current_network_id_.type),
1187 0, EFFECTIVE_CONNECTION_TYPE_LAST, 1189 0, EFFECTIVE_CONNECTION_TYPE_LAST,
1188 EFFECTIVE_CONNECTION_TYPE_LAST /* Number of buckets */, 1190 EFFECTIVE_CONNECTION_TYPE_LAST /* Number of buckets */,
1189 base::HistogramBase::kUmaTargetedHistogramFlag); 1191 base::HistogramBase::kUmaTargetedHistogramFlag);
1190 1192
1191 effective_connection_type_histogram->Add(effective_connection_type); 1193 effective_connection_type_histogram->Add(effective_connection_type);
1192 } 1194 }
1193 1195
1196 void NetworkQualityEstimator::ComputeEffectiveConnectionType() {
1197 DCHECK(thread_checker_.CalledOnValidThread());
1198
1199 const base::TimeTicks now = tick_clock_->NowTicks();
1200
1201 const EffectiveConnectionType past_type = effective_connection_type_;
1202 last_effective_connection_type_computation_ = now;
1203
1204 effective_connection_type_ =
1205 GetRecentEffectiveConnectionType(base::TimeTicks());
1206
1207 if (past_type != effective_connection_type_)
1208 NotifyObserversOfEffectiveConnectionTypeChanged();
1209
1210 rtt_observations_size_at_last_ect_computation_ = rtt_observations_.Size();
1211 throughput_observations_size_at_last_ect_computation_ =
1212 downstream_throughput_kbps_observations_.Size();
1213 }
1214
1194 EffectiveConnectionType NetworkQualityEstimator::GetEffectiveConnectionType() 1215 EffectiveConnectionType NetworkQualityEstimator::GetEffectiveConnectionType()
1195 const { 1216 const {
1196 DCHECK(thread_checker_.CalledOnValidThread()); 1217 DCHECK(thread_checker_.CalledOnValidThread());
1197 return GetRecentEffectiveConnectionType(base::TimeTicks()); 1218 return effective_connection_type_;
1198 } 1219 }
1199 1220
1200 EffectiveConnectionType 1221 EffectiveConnectionType
1201 NetworkQualityEstimator::GetRecentEffectiveConnectionType( 1222 NetworkQualityEstimator::GetRecentEffectiveConnectionType(
1202 const base::TimeTicks& start_time) const { 1223 const base::TimeTicks& start_time) const {
1203 DCHECK(thread_checker_.CalledOnValidThread()); 1224 DCHECK(thread_checker_.CalledOnValidThread());
1204 1225
1205 if (effective_connection_type_algorithm_ == 1226 if (effective_connection_type_algorithm_ ==
1206 EffectiveConnectionTypeAlgorithm::HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT) { 1227 EffectiveConnectionTypeAlgorithm::HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT) {
1207 return GetRecentEffectiveConnectionTypeUsingMetrics( 1228 return GetRecentEffectiveConnectionTypeUsingMetrics(
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
1598 rtt_observations_.AddObservation(observation); 1619 rtt_observations_.AddObservation(observation);
1599 } 1620 }
1600 1621
1601 void NetworkQualityEstimator::NotifyObserversOfRTT( 1622 void NetworkQualityEstimator::NotifyObserversOfRTT(
1602 const RttObservation& observation) { 1623 const RttObservation& observation) {
1603 DCHECK(thread_checker_.CalledOnValidThread()); 1624 DCHECK(thread_checker_.CalledOnValidThread());
1604 DCHECK_NE(nqe::internal::InvalidRTT(), observation.value); 1625 DCHECK_NE(nqe::internal::InvalidRTT(), observation.value);
1605 1626
1606 // Maybe recompute the effective connection type since a new RTT observation 1627 // Maybe recompute the effective connection type since a new RTT observation
1607 // is available. 1628 // is available.
1608 MaybeRecomputeEffectiveConnectionType(); 1629 MaybeComputeEffectiveConnectionType();
1609 FOR_EACH_OBSERVER( 1630 FOR_EACH_OBSERVER(
1610 RTTObserver, rtt_observer_list_, 1631 RTTObserver, rtt_observer_list_,
1611 OnRTTObservation(observation.value.InMilliseconds(), 1632 OnRTTObservation(observation.value.InMilliseconds(),
1612 observation.timestamp, observation.source)); 1633 observation.timestamp, observation.source));
1613 } 1634 }
1614 1635
1615 void NetworkQualityEstimator::NotifyObserversOfThroughput( 1636 void NetworkQualityEstimator::NotifyObserversOfThroughput(
1616 const ThroughputObservation& observation) { 1637 const ThroughputObservation& observation) {
1617 DCHECK(thread_checker_.CalledOnValidThread()); 1638 DCHECK(thread_checker_.CalledOnValidThread());
1618 DCHECK_NE(nqe::internal::kInvalidThroughput, observation.value); 1639 DCHECK_NE(nqe::internal::kInvalidThroughput, observation.value);
1619 1640
1620 // Maybe recompute the effective connection type since a new throughput 1641 // Maybe recompute the effective connection type since a new throughput
1621 // observation is available. 1642 // observation is available.
1622 MaybeRecomputeEffectiveConnectionType(); 1643 MaybeComputeEffectiveConnectionType();
1623 FOR_EACH_OBSERVER( 1644 FOR_EACH_OBSERVER(
1624 ThroughputObserver, throughput_observer_list_, 1645 ThroughputObserver, throughput_observer_list_,
1625 OnThroughputObservation(observation.value, observation.timestamp, 1646 OnThroughputObservation(observation.value, observation.timestamp,
1626 observation.source)); 1647 observation.source));
1627 } 1648 }
1628 1649
1629 void NetworkQualityEstimator::OnNewThroughputObservationAvailable( 1650 void NetworkQualityEstimator::OnNewThroughputObservationAvailable(
1630 int32_t downstream_kbps) { 1651 int32_t downstream_kbps) {
1631 DCHECK(thread_checker_.CalledOnValidThread()); 1652 DCHECK(thread_checker_.CalledOnValidThread());
1632 1653
1633 if (downstream_kbps == 0) 1654 if (downstream_kbps == 0)
1634 return; 1655 return;
1635 1656
1636 DCHECK_NE(nqe::internal::kInvalidThroughput, downstream_kbps); 1657 DCHECK_NE(nqe::internal::kInvalidThroughput, downstream_kbps);
1637 1658
1638 if (downstream_kbps > peak_network_quality_.downstream_throughput_kbps()) { 1659 if (downstream_kbps > peak_network_quality_.downstream_throughput_kbps()) {
1639 peak_network_quality_ = nqe::internal::NetworkQuality( 1660 peak_network_quality_ = nqe::internal::NetworkQuality(
1640 peak_network_quality_.http_rtt(), peak_network_quality_.transport_rtt(), 1661 peak_network_quality_.http_rtt(), peak_network_quality_.transport_rtt(),
1641 downstream_kbps); 1662 downstream_kbps);
1642 } 1663 }
1643 ThroughputObservation throughput_observation( 1664 ThroughputObservation throughput_observation(
1644 downstream_kbps, tick_clock_->NowTicks(), 1665 downstream_kbps, tick_clock_->NowTicks(),
1645 NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST); 1666 NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST);
1646 downstream_throughput_kbps_observations_.AddObservation( 1667 downstream_throughput_kbps_observations_.AddObservation(
1647 throughput_observation); 1668 throughput_observation);
1648 NotifyObserversOfThroughput(throughput_observation); 1669 NotifyObserversOfThroughput(throughput_observation);
1649 } 1670 }
1650 1671
1651 void NetworkQualityEstimator::MaybeRecomputeEffectiveConnectionType() { 1672 void NetworkQualityEstimator::MaybeComputeEffectiveConnectionType() {
1652 DCHECK(thread_checker_.CalledOnValidThread()); 1673 DCHECK(thread_checker_.CalledOnValidThread());
1653 1674
1654 const base::TimeTicks now = tick_clock_->NowTicks(); 1675 const base::TimeTicks now = tick_clock_->NowTicks();
1655 // Recompute effective connection type only if 1676 // Recompute effective connection type only if
1656 // |effective_connection_type_recomputation_interval_| has passed since it was 1677 // |effective_connection_type_recomputation_interval_| has passed since it was
1657 // last computed or a connection change event was observed since the last 1678 // last computed or a connection change event was observed since the last
1658 // computation. Strict inequalities are used to ensure that effective 1679 // computation. Strict inequalities are used to ensure that effective
1659 // connection type is recomputed on connection change events even if the clock 1680 // connection type is recomputed on connection change events even if the clock
1660 // has not updated. 1681 // has not updated.
1661 if (now - last_effective_connection_type_computation_ < 1682 if (now - last_effective_connection_type_computation_ <
1662 effective_connection_type_recomputation_interval_ && 1683 effective_connection_type_recomputation_interval_ &&
1663 last_connection_change_ < last_effective_connection_type_computation_ && 1684 last_connection_change_ < last_effective_connection_type_computation_ &&
1664 // Recompute the effective connection type if the previously computed 1685 // Recompute the effective connection type if the previously computed
1665 // effective connection type was unknown. 1686 // effective connection type was unknown.
1666 effective_connection_type_ != EFFECTIVE_CONNECTION_TYPE_UNKNOWN && 1687 effective_connection_type_ != EFFECTIVE_CONNECTION_TYPE_UNKNOWN &&
1667 // Recompute the effective connection type if the number of samples 1688 // Recompute the effective connection type if the number of samples
1668 // available now are more than twice in count than the number of 1689 // available now are 50% more than the number of samples that were
1669 // samples that were available when the effective connection type was 1690 // available when the effective connection type was last computed.
1670 // last computed. 1691 rtt_observations_size_at_last_ect_computation_ * 1.5 >=
1671 rtt_observations_size_at_last_ect_computation_ * 2 >=
1672 rtt_observations_.Size() && 1692 rtt_observations_.Size() &&
1673 throughput_observations_size_at_last_ect_computation_ * 2 >= 1693 throughput_observations_size_at_last_ect_computation_ * 1.5 >=
1674 downstream_throughput_kbps_observations_.Size()) { 1694 downstream_throughput_kbps_observations_.Size()) {
1675 return; 1695 return;
1676 } 1696 }
1677 1697 ComputeEffectiveConnectionType();
1678 const EffectiveConnectionType past_type = effective_connection_type_;
1679 last_effective_connection_type_computation_ = now;
1680 effective_connection_type_ = GetEffectiveConnectionType();
1681
1682 if (past_type != effective_connection_type_)
1683 NotifyObserversOfEffectiveConnectionTypeChanged();
1684
1685 rtt_observations_size_at_last_ect_computation_ = rtt_observations_.Size();
1686 throughput_observations_size_at_last_ect_computation_ =
1687 downstream_throughput_kbps_observations_.Size();
1688 } 1698 }
1689 1699
1690 void NetworkQualityEstimator:: 1700 void NetworkQualityEstimator::
1691 NotifyObserversOfEffectiveConnectionTypeChanged() { 1701 NotifyObserversOfEffectiveConnectionTypeChanged() {
1692 DCHECK(thread_checker_.CalledOnValidThread()); 1702 DCHECK(thread_checker_.CalledOnValidThread());
1693 DCHECK_NE(EFFECTIVE_CONNECTION_TYPE_LAST, effective_connection_type_); 1703 DCHECK_NE(EFFECTIVE_CONNECTION_TYPE_LAST, effective_connection_type_);
1694 1704
1695 // TODO(tbansal): Add hysteresis in the notification. 1705 // TODO(tbansal): Add hysteresis in the notification.
1696 FOR_EACH_OBSERVER( 1706 FOR_EACH_OBSERVER(
1697 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, 1707 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_,
1698 OnEffectiveConnectionTypeChanged(effective_connection_type_)); 1708 OnEffectiveConnectionTypeChanged(effective_connection_type_));
1699 1709
1700 // Add the estimates of the current network to the cache store. 1710 // Add the estimates of the current network to the cache store.
1701 if (effective_connection_type_ != EFFECTIVE_CONNECTION_TYPE_UNKNOWN) { 1711 if (effective_connection_type_ != EFFECTIVE_CONNECTION_TYPE_UNKNOWN) {
1702 network_quality_store_->Add( 1712 network_quality_store_->Add(
1703 current_network_id_, 1713 current_network_id_,
1704 nqe::internal::CachedNetworkQuality( 1714 nqe::internal::CachedNetworkQuality(
1705 tick_clock_->NowTicks(), estimated_quality_at_last_main_frame_, 1715 tick_clock_->NowTicks(), estimated_quality_at_last_main_frame_,
1706 effective_connection_type_)); 1716 effective_connection_type_));
1707 } 1717 }
1708 } 1718 }
1709 1719
1710 } // namespace net 1720 } // 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