Chromium Code Reviews| Index: net/nqe/network_quality_estimator.cc |
| diff --git a/net/nqe/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc |
| index a9596d04815ee479e0534f05a0510866e4a809f9..fe5bcb31f23691067e0072ded1c4ca2846e219a2 100644 |
| --- a/net/nqe/network_quality_estimator.cc |
| +++ b/net/nqe/network_quality_estimator.cc |
| @@ -17,6 +17,7 @@ |
| #include "base/single_thread_task_runner.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/threading/thread_task_runner_handle.h" |
| +#include "base/time/default_tick_clock.h" |
| #include "base/trace_event/trace_event.h" |
| #include "build/build_config.h" |
| #include "net/base/load_flags.h" |
| @@ -252,13 +253,17 @@ NetworkQualityEstimator::NetworkQualityEstimator( |
| use_small_responses_(use_smaller_responses_for_tests), |
| weight_multiplier_per_second_( |
| GetWeightMultiplierPerSecond(variation_params)), |
| - last_connection_change_(base::TimeTicks::Now()), |
| + tick_clock_(new base::DefaultTickClock()), |
| + effective_connection_type_recomputation_interval_( |
| + base::TimeDelta::FromSeconds(15)), |
| + last_connection_change_(tick_clock_->NowTicks()), |
| current_network_id_( |
| NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, |
| std::string())), |
| downstream_throughput_kbps_observations_(weight_multiplier_per_second_), |
| rtt_observations_(weight_multiplier_per_second_), |
| external_estimate_provider_(std::move(external_estimates_provider)), |
| + effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), |
| weak_ptr_factory_(this) { |
| static_assert(kDefaultHalfLifeSeconds > 0, |
| "Default half life duration must be > 0"); |
| @@ -393,7 +398,7 @@ void NetworkQualityEstimator::AddDefaultEstimates() { |
| nqe::internal::InvalidRTT()) { |
| RttObservation rtt_observation( |
| default_observations_[current_network_id_.type].rtt(), |
| - base::TimeTicks::Now(), |
| + tick_clock_->NowTicks(), |
| NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_FROM_PLATFORM); |
| rtt_observations_.AddObservation(rtt_observation); |
| NotifyObserversOfRTT(rtt_observation); |
| @@ -403,7 +408,7 @@ void NetworkQualityEstimator::AddDefaultEstimates() { |
| ThroughputObservation throughput_observation( |
| default_observations_[current_network_id_.type] |
| .downstream_throughput_kbps(), |
| - base::TimeTicks::Now(), |
| + tick_clock_->NowTicks(), |
| NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_FROM_PLATFORM); |
| downstream_throughput_kbps_observations_.AddObservation( |
| throughput_observation); |
| @@ -450,7 +455,7 @@ void NetworkQualityEstimator::NotifyHeadersReceived(const URLRequest& request) { |
| nqe::internal::NetworkQuality(rtt, downstream_throughput_kbps); |
| } |
| - base::TimeTicks now = base::TimeTicks::Now(); |
| + const base::TimeTicks now = tick_clock_->NowTicks(); |
| LoadTimingInfo load_timing_info; |
| request.GetLoadTimingInfo(&load_timing_info); |
| @@ -601,7 +606,7 @@ void NetworkQualityEstimator::OnConnectionTypeChanged( |
| CacheNetworkQualityEstimate(); |
| // Clear the local state. |
| - last_connection_change_ = base::TimeTicks::Now(); |
| + last_connection_change_ = tick_clock_->NowTicks(); |
| peak_network_quality_ = nqe::internal::NetworkQuality(); |
| downstream_throughput_kbps_observations_.Clear(); |
| rtt_observations_.Clear(); |
| @@ -615,6 +620,7 @@ void NetworkQualityEstimator::OnConnectionTypeChanged( |
| AddDefaultEstimates(); |
| estimated_median_network_quality_ = nqe::internal::NetworkQuality(); |
| throughput_analyzer_->OnConnectionTypeChanged(); |
| + MaybeRecomputeEffectiveConnectionType(); |
| } |
| void NetworkQualityEstimator::RecordMetricsOnConnectionTypeChanged() const { |
| @@ -740,6 +746,18 @@ NetworkQualityEstimator::GetEffectiveConnectionType() const { |
| 1); |
| } |
| +void NetworkQualityEstimator::AddEffectiveConnectionTypeObserver( |
| + EffectiveConnectionTypeObserver* observer) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + effective_connection_type_observer_list_.AddObserver(observer); |
| +} |
| + |
| +void NetworkQualityEstimator::RemoveEffectiveConnectionTypeObserver( |
| + EffectiveConnectionTypeObserver* observer) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + effective_connection_type_observer_list_.RemoveObserver(observer); |
| +} |
| + |
| bool NetworkQualityEstimator::GetURLRequestRTTEstimate( |
| base::TimeDelta* rtt) const { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| @@ -919,14 +937,14 @@ bool NetworkQualityEstimator::ReadCachedNetworkQualityEstimate() { |
| network_quality.downstream_throughput_kbps()); |
| ThroughputObservation througphput_observation( |
| - network_quality.downstream_throughput_kbps(), base::TimeTicks::Now(), |
| + network_quality.downstream_throughput_kbps(), tick_clock_->NowTicks(), |
| NETWORK_QUALITY_OBSERVATION_SOURCE_CACHED_ESTIMATE); |
| downstream_throughput_kbps_observations_.AddObservation( |
| througphput_observation); |
| NotifyObserversOfThroughput(througphput_observation); |
| RttObservation rtt_observation( |
| - network_quality.rtt(), base::TimeTicks::Now(), |
| + network_quality.rtt(), tick_clock_->NowTicks(), |
| NETWORK_QUALITY_OBSERVATION_SOURCE_CACHED_ESTIMATE); |
| rtt_observations_.AddObservation(rtt_observation); |
| NotifyObserversOfRTT(rtt_observation); |
| @@ -967,6 +985,12 @@ const char* NetworkQualityEstimator::GetNameForEffectiveConnectionType( |
| return ""; |
| } |
| +void NetworkQualityEstimator::SetTickClockForTesting( |
| + std::unique_ptr<base::TickClock> tick_clock) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + tick_clock_ = std::move(tick_clock); |
| +} |
| + |
| void NetworkQualityEstimator::QueryExternalEstimateProvider() { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| @@ -999,7 +1023,7 @@ void NetworkQualityEstimator::QueryExternalEstimateProvider() { |
| EXTERNAL_ESTIMATE_PROVIDER_STATUS_RTT_AVAILABLE); |
| UMA_HISTOGRAM_TIMES("NQE.ExternalEstimateProvider.RTT", rtt); |
| rtt_observations_.AddObservation( |
| - RttObservation(rtt, base::TimeTicks::Now(), |
| + RttObservation(rtt, tick_clock_->NowTicks(), |
| NETWORK_QUALITY_OBSERVATION_SOURCE_EXTERNAL_ESTIMATE)); |
| } |
| @@ -1012,7 +1036,7 @@ void NetworkQualityEstimator::QueryExternalEstimateProvider() { |
| downstream_throughput_kbps); |
| downstream_throughput_kbps_observations_.AddObservation( |
| ThroughputObservation( |
| - downstream_throughput_kbps, base::TimeTicks::Now(), |
| + downstream_throughput_kbps, tick_clock_->NowTicks(), |
| NETWORK_QUALITY_OBSERVATION_SOURCE_EXTERNAL_ESTIMATE)); |
| } |
| } |
| @@ -1065,7 +1089,7 @@ void NetworkQualityEstimator::OnUpdatedRTTAvailable( |
| const base::TimeDelta& rtt) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - RttObservation observation(rtt, base::TimeTicks::Now(), |
| + RttObservation observation(rtt, tick_clock_->NowTicks(), |
| ProtocolSourceToObservationSource(protocol)); |
| NotifyObserversOfRTT(observation); |
| rtt_observations_.AddObservation(observation); |
| @@ -1073,6 +1097,9 @@ void NetworkQualityEstimator::OnUpdatedRTTAvailable( |
| void NetworkQualityEstimator::NotifyObserversOfRTT( |
| const RttObservation& observation) { |
| + // 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.
|
| + // is available. |
| + MaybeRecomputeEffectiveConnectionType(); |
| FOR_EACH_OBSERVER( |
| RTTObserver, rtt_observer_list_, |
| OnRTTObservation(observation.value.InMilliseconds(), |
| @@ -1081,6 +1108,9 @@ void NetworkQualityEstimator::NotifyObserversOfRTT( |
| void NetworkQualityEstimator::NotifyObserversOfThroughput( |
| const ThroughputObservation& observation) { |
| + // May be recompute the effective connection type since a new throughput |
| + // observation is available. |
| + MaybeRecomputeEffectiveConnectionType(); |
| FOR_EACH_OBSERVER( |
| ThroughputObserver, throughput_observer_list_, |
| OnThroughputObservation(observation.value, observation.timestamp, |
| @@ -1099,11 +1129,43 @@ void NetworkQualityEstimator::OnNewThroughputObservationAvailable( |
| peak_network_quality_.rtt(), downstream_kbps); |
| } |
| ThroughputObservation throughput_observation( |
| - downstream_kbps, base::TimeTicks::Now(), |
| + downstream_kbps, tick_clock_->NowTicks(), |
| NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST); |
| downstream_throughput_kbps_observations_.AddObservation( |
| throughput_observation); |
| NotifyObserversOfThroughput(throughput_observation); |
| } |
| +void NetworkQualityEstimator::MaybeRecomputeEffectiveConnectionType() { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + |
| + const base::TimeTicks now = tick_clock_->NowTicks(); |
| + // Recompute effective connection type only if |
| + // |effective_connection_type_recomputation_interval_| has passed since it was |
| + // last computed or a connection change event was observed since the last |
| + // computation. |
| + if (now - last_effective_connection_type_computation_ <= |
| + effective_connection_type_recomputation_interval_ && |
| + 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
|
| + return; |
| + } |
| + |
| + const EffectiveConnectionType past_type = effective_connection_type_; |
| + last_effective_connection_type_computation_ = now; |
| + 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.
|
| + |
| + if (past_type != effective_connection_type_) |
| + NotifyObserversOfEffectiveConnectionTypeChanged(); |
| +} |
| + |
| +void NetworkQualityEstimator:: |
| + NotifyObserversOfEffectiveConnectionTypeChanged() { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + |
| + // TODO(tbansal): Add hysteresis in the notification. |
| + FOR_EACH_OBSERVER( |
| + EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, |
| + OnEffectiveConnectionTypeChanged(effective_connection_type_)); |
| +} |
| + |
| } // namespace net |