| Index: net/base/network_quality_estimator.cc
|
| diff --git a/net/base/network_quality_estimator.cc b/net/base/network_quality_estimator.cc
|
| index 6415ee6e6d7eb36b47ab4fd568d3537283b27729..805ee3080171ced0c8182696805115b17cf426f0 100644
|
| --- a/net/base/network_quality_estimator.cc
|
| +++ b/net/base/network_quality_estimator.cc
|
| @@ -15,6 +15,10 @@
|
|
|
| namespace net {
|
|
|
| +// Maximum number of observations to hold in the ObservationBuffer.
|
| +const size_t NetworkQualityEstimator::ObservationBuffer::kMaximumObservations =
|
| + 500;
|
| +
|
| NetworkQualityEstimator::NetworkQualityEstimator()
|
| : NetworkQualityEstimator(false) {
|
| }
|
| @@ -24,7 +28,7 @@ NetworkQualityEstimator::NetworkQualityEstimator(
|
| : allow_localhost_requests_(allow_local_host_requests_for_tests),
|
| last_connection_change_(base::TimeTicks::Now()),
|
| current_connection_type_(NetworkChangeNotifier::GetConnectionType()),
|
| - bytes_read_since_last_connection_change_(false),
|
| + have_received_bytes_since_last_connection_change_(false),
|
| peak_kbps_since_last_connection_change_(0) {
|
| static_assert(kMinRequestDurationMicroseconds > 0,
|
| "Minimum request duration must be > 0");
|
| @@ -36,10 +40,13 @@ NetworkQualityEstimator::~NetworkQualityEstimator() {
|
| NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
|
| }
|
|
|
| -void NetworkQualityEstimator::NotifyDataReceived(const URLRequest& request,
|
| - int64_t prefilter_bytes_read) {
|
| +void NetworkQualityEstimator::NotifyDataReceived(
|
| + const URLRequest& request,
|
| + int64_t cumulative_prefilter_bytes_read,
|
| + int64_t prefiltered_bytes_read) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| - DCHECK_GT(prefilter_bytes_read, 0);
|
| + DCHECK_GT(cumulative_prefilter_bytes_read, 0);
|
| + DCHECK_GT(prefiltered_bytes_read, 0);
|
|
|
| if (!request.url().is_valid() ||
|
| (!allow_localhost_requests_ && IsLocalhost(request.url().host())) ||
|
| @@ -54,61 +61,68 @@ void NetworkQualityEstimator::NotifyDataReceived(const URLRequest& request,
|
| base::TimeTicks now = base::TimeTicks::Now();
|
| base::TimeDelta request_duration = now - request.creation_time();
|
| DCHECK_GE(request_duration, base::TimeDelta());
|
| - if (!bytes_read_since_last_connection_change_)
|
| - fastest_RTT_since_last_connection_change_ = request_duration;
|
| + if (!have_received_bytes_since_last_connection_change_)
|
| + fastest_rtt_since_last_connection_change_ = request_duration;
|
| +
|
| + have_received_bytes_since_last_connection_change_ = true;
|
| + if (request_duration < fastest_rtt_since_last_connection_change_)
|
| + fastest_rtt_since_last_connection_change_ = request_duration;
|
|
|
| - bytes_read_since_last_connection_change_ = true;
|
| - if (request_duration < fastest_RTT_since_last_connection_change_)
|
| - fastest_RTT_since_last_connection_change_ = request_duration;
|
| + // Only add RTT observation if this is the first read for this response.
|
| + if (cumulative_prefilter_bytes_read == prefiltered_bytes_read)
|
| + rtt_msec_observations_.AddObservation(request_duration.InMilliseconds());
|
|
|
| // Ignore tiny transfers which will not produce accurate rates.
|
| // Ignore short duration transfers.
|
| - if (prefilter_bytes_read >= kMinTransferSizeInBytes &&
|
| + if (cumulative_prefilter_bytes_read >= kMinTransferSizeInBytes &&
|
| request_duration >=
|
| base::TimeDelta::FromMicroseconds(kMinRequestDurationMicroseconds)) {
|
| - uint64_t kbps = static_cast<uint64_t>(prefilter_bytes_read * 8 * 1000 /
|
| - request_duration.InMicroseconds());
|
| + int32_t kbps =
|
| + static_cast<int32_t>(cumulative_prefilter_bytes_read * 8 * 1000 /
|
| + request_duration.InMicroseconds());
|
| if (kbps > peak_kbps_since_last_connection_change_)
|
| peak_kbps_since_last_connection_change_ = kbps;
|
| +
|
| + kbps_observations_.AddObservation(kbps);
|
| }
|
| }
|
|
|
| void NetworkQualityEstimator::OnConnectionTypeChanged(
|
| NetworkChangeNotifier::ConnectionType type) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| - if (bytes_read_since_last_connection_change_) {
|
| + if (have_received_bytes_since_last_connection_change_) {
|
| switch (current_connection_type_) {
|
| case NetworkChangeNotifier::CONNECTION_UNKNOWN:
|
| UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Unknown",
|
| - fastest_RTT_since_last_connection_change_);
|
| + fastest_rtt_since_last_connection_change_);
|
| break;
|
| case NetworkChangeNotifier::CONNECTION_ETHERNET:
|
| UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Ethernet",
|
| - fastest_RTT_since_last_connection_change_);
|
| + fastest_rtt_since_last_connection_change_);
|
| break;
|
| case NetworkChangeNotifier::CONNECTION_WIFI:
|
| UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Wifi",
|
| - fastest_RTT_since_last_connection_change_);
|
| + fastest_rtt_since_last_connection_change_);
|
| break;
|
| case NetworkChangeNotifier::CONNECTION_2G:
|
| UMA_HISTOGRAM_TIMES("NQE.FastestRTT.2G",
|
| - fastest_RTT_since_last_connection_change_);
|
| + fastest_rtt_since_last_connection_change_);
|
| break;
|
| case NetworkChangeNotifier::CONNECTION_3G:
|
| UMA_HISTOGRAM_TIMES("NQE.FastestRTT.3G",
|
| - fastest_RTT_since_last_connection_change_);
|
| + fastest_rtt_since_last_connection_change_);
|
| break;
|
| case NetworkChangeNotifier::CONNECTION_4G:
|
| UMA_HISTOGRAM_TIMES("NQE.FastestRTT.4G",
|
| - fastest_RTT_since_last_connection_change_);
|
| + fastest_rtt_since_last_connection_change_);
|
| break;
|
| case NetworkChangeNotifier::CONNECTION_NONE:
|
| UMA_HISTOGRAM_TIMES("NQE.FastestRTT.None",
|
| - fastest_RTT_since_last_connection_change_);
|
| + fastest_rtt_since_last_connection_change_);
|
| break;
|
| case NetworkChangeNotifier::CONNECTION_BLUETOOTH:
|
| UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Bluetooth",
|
| - fastest_RTT_since_last_connection_change_);
|
| + fastest_rtt_since_last_connection_change_);
|
| break;
|
| default:
|
| NOTREACHED();
|
| @@ -157,24 +171,53 @@ void NetworkQualityEstimator::OnConnectionTypeChanged(
|
| }
|
|
|
| last_connection_change_ = base::TimeTicks::Now();
|
| - bytes_read_since_last_connection_change_ = false;
|
| + have_received_bytes_since_last_connection_change_ = false;
|
| peak_kbps_since_last_connection_change_ = 0;
|
| current_connection_type_ = type;
|
| }
|
|
|
| -NetworkQuality NetworkQualityEstimator::GetEstimate() const {
|
| +NetworkQuality NetworkQualityEstimator::GetPeakEstimate() const {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
| - if (!bytes_read_since_last_connection_change_) {
|
| - return NetworkQuality(fastest_RTT_since_last_connection_change_, 0,
|
| - peak_kbps_since_last_connection_change_, 0);
|
| - }
|
| - if (!peak_kbps_since_last_connection_change_) {
|
| - return NetworkQuality(fastest_RTT_since_last_connection_change_, 0.1,
|
| - peak_kbps_since_last_connection_change_, 0);
|
| - }
|
| - return NetworkQuality(fastest_RTT_since_last_connection_change_, 0.1,
|
| - peak_kbps_since_last_connection_change_, 0.1);
|
| + if (!have_received_bytes_since_last_connection_change_)
|
| + return NetworkQuality(base::TimeDelta(), 0);
|
| + if (!peak_kbps_since_last_connection_change_)
|
| + return NetworkQuality(fastest_rtt_since_last_connection_change_, 0);
|
| + return NetworkQuality(fastest_rtt_since_last_connection_change_,
|
| + peak_kbps_since_last_connection_change_);
|
| +}
|
| +
|
| +NetworkQualityEstimator::Observation::Observation(int32_t value,
|
| + base::TimeTicks timestamp)
|
| + : value(value), timestamp(timestamp) {
|
| + DCHECK_GE(value, 0);
|
| +}
|
| +
|
| +NetworkQualityEstimator::Observation::~Observation() {
|
| +}
|
| +
|
| +NetworkQualityEstimator::ObservationBuffer::ObservationBuffer() {
|
| + static_assert(kMaximumObservations > 0U,
|
| + "Minimum size of observation buffer must be > 0");
|
| +}
|
| +
|
| +NetworkQualityEstimator::ObservationBuffer::~ObservationBuffer() {
|
| +}
|
| +
|
| +void NetworkQualityEstimator::ObservationBuffer::AddObservation(int32_t value) {
|
| + DCHECK_LE(observations_.size(), kMaximumObservations);
|
| + if (value < 0)
|
| + return;
|
| + // Pop the oldest element if the buffer is already full.
|
| + if (observations_.size() == kMaximumObservations)
|
| + observations_.pop_front();
|
| +
|
| + observations_.push_back(Observation(value, base::TimeTicks::Now()));
|
| + DCHECK_LE(observations_.size(), kMaximumObservations);
|
| +}
|
| +
|
| +size_t NetworkQualityEstimator::ObservationBuffer::size() const {
|
| + return observations_.size();
|
| }
|
|
|
| } // namespace net
|
|
|