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

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

Issue 1316863006: Populate EEP estimate in NQE (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed asvitkine comments Created 5 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
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/base/network_quality_estimator.h" 5 #include "net/base/network_quality_estimator.h"
6 6
7 #include <float.h> 7 #include <float.h>
8 #include <algorithm> 8 #include <algorithm>
9 #include <cmath> 9 #include <cmath>
10 #include <limits> 10 #include <limits>
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 bool allow_smaller_responses_for_tests) 171 bool allow_smaller_responses_for_tests)
172 : allow_localhost_requests_(allow_local_host_requests_for_tests), 172 : allow_localhost_requests_(allow_local_host_requests_for_tests),
173 allow_small_responses_(allow_smaller_responses_for_tests), 173 allow_small_responses_(allow_smaller_responses_for_tests),
174 last_connection_change_(base::TimeTicks::Now()), 174 last_connection_change_(base::TimeTicks::Now()),
175 current_network_id_( 175 current_network_id_(
176 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, 176 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN,
177 std::string())), 177 std::string())),
178 downstream_throughput_kbps_observations_( 178 downstream_throughput_kbps_observations_(
179 GetWeightMultiplierPerSecond(variation_params)), 179 GetWeightMultiplierPerSecond(variation_params)),
180 rtt_msec_observations_(GetWeightMultiplierPerSecond(variation_params)), 180 rtt_msec_observations_(GetWeightMultiplierPerSecond(variation_params)),
181 external_estimates_provider_(external_estimates_provider.Pass()) { 181 external_estimate_provider_(external_estimates_provider.Pass()),
182 external_estimate_request_time_(base::TimeTicks()) {
mmenke 2015/09/11 14:26:29 Don't need to explicitly call the default construc
tbansal1 2015/09/11 21:24:30 Done.
182 static_assert(kMinRequestDurationMicroseconds > 0, 183 static_assert(kMinRequestDurationMicroseconds > 0,
183 "Minimum request duration must be > 0"); 184 "Minimum request duration must be > 0");
184 static_assert(kDefaultHalfLifeSeconds > 0, 185 static_assert(kDefaultHalfLifeSeconds > 0,
185 "Default half life duration must be > 0"); 186 "Default half life duration must be > 0");
186 static_assert(kMaximumNetworkQualityCacheSize > 0, 187 static_assert(kMaximumNetworkQualityCacheSize > 0,
187 "Size of the network quality cache must be > 0"); 188 "Size of the network quality cache must be > 0");
188 // This limit should not be increased unless the logic for removing the 189 // This limit should not be increased unless the logic for removing the
189 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. 190 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue.
190 static_assert(kMaximumNetworkQualityCacheSize <= 10, 191 static_assert(kMaximumNetworkQualityCacheSize <= 10,
191 "Size of the network quality cache must <= 10"); 192 "Size of the network quality cache must <= 10");
192 193
193 ObtainOperatingParams(variation_params); 194 ObtainOperatingParams(variation_params);
194 NetworkChangeNotifier::AddConnectionTypeObserver(this); 195 NetworkChangeNotifier::AddConnectionTypeObserver(this);
195 if (external_estimates_provider_) 196 if (external_estimate_provider_) {
196 external_estimates_provider_->SetUpdatedEstimateDelegate(this); 197 RecordExternalEstimateProviderMetrics(
198 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE);
199 external_estimate_provider_->SetUpdatedEstimateDelegate(this);
200 QueryExternalEstimateProvider();
201 } else {
202 RecordExternalEstimateProviderMetrics(
203 EXTERNAL_ESTIMATE_PROVIDER_STATUS_NOT_AVAILABLE);
204 }
197 current_network_id_ = GetCurrentNetworkID(); 205 current_network_id_ = GetCurrentNetworkID();
198 AddDefaultEstimates(); 206 AddDefaultEstimates();
199 } 207 }
200 208
201 // static 209 // static
202 const base::TimeDelta NetworkQualityEstimator::InvalidRTT() { 210 const base::TimeDelta NetworkQualityEstimator::InvalidRTT() {
203 return base::TimeDelta::Max(); 211 return base::TimeDelta::Max();
204 } 212 }
205 213
206 void NetworkQualityEstimator::ObtainOperatingParams( 214 void NetworkQualityEstimator::ObtainOperatingParams(
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 } 265 }
258 266
259 NetworkQualityEstimator::~NetworkQualityEstimator() { 267 NetworkQualityEstimator::~NetworkQualityEstimator() {
260 DCHECK(thread_checker_.CalledOnValidThread()); 268 DCHECK(thread_checker_.CalledOnValidThread());
261 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); 269 NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
262 } 270 }
263 271
264 void NetworkQualityEstimator::NotifyHeadersReceived(const URLRequest& request) { 272 void NetworkQualityEstimator::NotifyHeadersReceived(const URLRequest& request) {
265 DCHECK(thread_checker_.CalledOnValidThread()); 273 DCHECK(thread_checker_.CalledOnValidThread());
266 274
275 MaybeQueryExternalEstimateProvider();
267 if (!RequestProvidesUsefulObservations(request)) 276 if (!RequestProvidesUsefulObservations(request))
268 return; 277 return;
269 278
270 // Update |estimated_median_network_quality_| if this is a main frame request. 279 // Update |estimated_median_network_quality_| if this is a main frame request.
271 if (request.load_flags() & LOAD_MAIN_FRAME) { 280 if (request.load_flags() & LOAD_MAIN_FRAME) {
272 estimated_median_network_quality_ = NetworkQuality( 281 estimated_median_network_quality_ = NetworkQuality(
273 GetRTTEstimateInternal(base::TimeTicks(), 50), 282 GetRTTEstimateInternal(base::TimeTicks(), 50),
274 GetDownlinkThroughputKbpsEstimateInternal(base::TimeTicks(), 50)); 283 GetDownlinkThroughputKbpsEstimateInternal(base::TimeTicks(), 50));
275 } 284 }
276 285
(...skipping 30 matching lines...) Expand all
307 if (estimated_median_network_quality_.rtt() != InvalidRTT()) { 316 if (estimated_median_network_quality_.rtt() != InvalidRTT()) {
308 RecordRTTUMA(estimated_median_network_quality_.rtt().InMilliseconds(), 317 RecordRTTUMA(estimated_median_network_quality_.rtt().InMilliseconds(),
309 observed_rtt.InMilliseconds()); 318 observed_rtt.InMilliseconds());
310 } 319 }
311 } 320 }
312 321
313 void NetworkQualityEstimator::NotifyRequestCompleted( 322 void NetworkQualityEstimator::NotifyRequestCompleted(
314 const URLRequest& request) { 323 const URLRequest& request) {
315 DCHECK(thread_checker_.CalledOnValidThread()); 324 DCHECK(thread_checker_.CalledOnValidThread());
316 325
326 MaybeQueryExternalEstimateProvider();
317 if (!RequestProvidesUsefulObservations(request)) 327 if (!RequestProvidesUsefulObservations(request))
318 return; 328 return;
319 329
320 base::TimeTicks now = base::TimeTicks::Now(); 330 base::TimeTicks now = base::TimeTicks::Now();
321 LoadTimingInfo load_timing_info; 331 LoadTimingInfo load_timing_info;
322 request.GetLoadTimingInfo(&load_timing_info); 332 request.GetLoadTimingInfo(&load_timing_info);
323 333
324 // If the load timing info is unavailable, it probably means that the request 334 // If the load timing info is unavailable, it probably means that the request
325 // did not go over the network. 335 // did not go over the network.
326 if (load_timing_info.send_start.is_null() || 336 if (load_timing_info.send_start.is_null() ||
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 return request.url().is_valid() && 422 return request.url().is_valid() &&
413 (allow_localhost_requests_ || !IsLocalhost(request.url().host())) && 423 (allow_localhost_requests_ || !IsLocalhost(request.url().host())) &&
414 request.url().SchemeIsHTTPOrHTTPS() && 424 request.url().SchemeIsHTTPOrHTTPS() &&
415 // Verify that response headers are received, so it can be ensured that 425 // Verify that response headers are received, so it can be ensured that
416 // response is not cached. 426 // response is not cached.
417 !request.response_info().response_time.is_null() && 427 !request.response_info().response_time.is_null() &&
418 !request.was_cached() && 428 !request.was_cached() &&
419 request.creation_time() >= last_connection_change_; 429 request.creation_time() >= last_connection_change_;
420 } 430 }
421 431
432 void NetworkQualityEstimator::RecordExternalEstimateProviderMetrics(
433 NQEExternalEstimateProviderStatus status) const {
434 UMA_HISTOGRAM_ENUMERATION("NQE.ExternalEstimateProviderStatus", status,
435 EXTERNAL_ESTIMATE_PROVIDER_STATUS_BOUNDARY);
436 }
437
422 void NetworkQualityEstimator::OnConnectionTypeChanged( 438 void NetworkQualityEstimator::OnConnectionTypeChanged(
423 NetworkChangeNotifier::ConnectionType type) { 439 NetworkChangeNotifier::ConnectionType type) {
424 DCHECK(thread_checker_.CalledOnValidThread()); 440 DCHECK(thread_checker_.CalledOnValidThread());
425 if (peak_network_quality_.rtt() != InvalidRTT()) { 441 if (peak_network_quality_.rtt() != InvalidRTT()) {
426 switch (current_network_id_.type) { 442 switch (current_network_id_.type) {
427 case NetworkChangeNotifier::CONNECTION_UNKNOWN: 443 case NetworkChangeNotifier::CONNECTION_UNKNOWN:
428 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Unknown", 444 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Unknown",
429 peak_network_quality_.rtt()); 445 peak_network_quality_.rtt());
430 break; 446 break;
431 case NetworkChangeNotifier::CONNECTION_ETHERNET: 447 case NetworkChangeNotifier::CONNECTION_ETHERNET:
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 // Write the estimates of the previous network to the cache. 547 // Write the estimates of the previous network to the cache.
532 CacheNetworkQualityEstimate(); 548 CacheNetworkQualityEstimate();
533 549
534 // Clear the local state. 550 // Clear the local state.
535 last_connection_change_ = base::TimeTicks::Now(); 551 last_connection_change_ = base::TimeTicks::Now();
536 peak_network_quality_ = NetworkQuality(); 552 peak_network_quality_ = NetworkQuality();
537 downstream_throughput_kbps_observations_.Clear(); 553 downstream_throughput_kbps_observations_.Clear();
538 rtt_msec_observations_.Clear(); 554 rtt_msec_observations_.Clear();
539 current_network_id_ = GetCurrentNetworkID(); 555 current_network_id_ = GetCurrentNetworkID();
540 556
557 QueryExternalEstimateProvider();
558
541 // Read any cached estimates for the new network. If cached estimates are 559 // Read any cached estimates for the new network. If cached estimates are
542 // unavailable, add the default estimates. 560 // unavailable, add the default estimates.
543 if (!ReadCachedNetworkQualityEstimate()) 561 if (!ReadCachedNetworkQualityEstimate())
544 AddDefaultEstimates(); 562 AddDefaultEstimates();
545 estimated_median_network_quality_ = NetworkQuality(); 563 estimated_median_network_quality_ = NetworkQuality();
546 } 564 }
547 565
548 bool NetworkQualityEstimator::GetRTTEstimate(base::TimeDelta* rtt) const { 566 bool NetworkQualityEstimator::GetRTTEstimate(base::TimeDelta* rtt) {
549 DCHECK(thread_checker_.CalledOnValidThread()); 567 DCHECK(thread_checker_.CalledOnValidThread());
550 DCHECK(rtt); 568 DCHECK(rtt);
569 MaybeQueryExternalEstimateProvider();
mmenke 2015/09/11 15:07:22 Wait..So the frequency one calls this method can a
mmenke 2015/09/11 15:17:52 Ah, right...It's the queries vs maybe queries. Th
tbansal1 2015/09/11 21:24:30 Please see the reply below.
551 if (rtt_msec_observations_.Size() == 0) { 570 if (rtt_msec_observations_.Size() == 0) {
552 *rtt = InvalidRTT(); 571 *rtt = InvalidRTT();
553 return false; 572 return false;
554 } 573 }
555 *rtt = GetRTTEstimateInternal(base::TimeTicks(), 50); 574 *rtt = GetRTTEstimateInternal(base::TimeTicks(), 50);
556 return (*rtt != InvalidRTT()); 575 return (*rtt != InvalidRTT());
557 } 576 }
558 577
559 bool NetworkQualityEstimator::GetDownlinkThroughputKbpsEstimate( 578 bool NetworkQualityEstimator::GetDownlinkThroughputKbpsEstimate(int32_t* kbps) {
560 int32_t* kbps) const {
561 DCHECK(thread_checker_.CalledOnValidThread()); 579 DCHECK(thread_checker_.CalledOnValidThread());
562 DCHECK(kbps); 580 DCHECK(kbps);
581 MaybeQueryExternalEstimateProvider();
563 if (downstream_throughput_kbps_observations_.Size() == 0) { 582 if (downstream_throughput_kbps_observations_.Size() == 0) {
564 *kbps = kInvalidThroughput; 583 *kbps = kInvalidThroughput;
565 return false; 584 return false;
566 } 585 }
567 *kbps = GetDownlinkThroughputKbpsEstimateInternal(base::TimeTicks(), 50); 586 *kbps = GetDownlinkThroughputKbpsEstimateInternal(base::TimeTicks(), 50);
568 return (*kbps != kInvalidThroughput); 587 return (*kbps != kInvalidThroughput);
569 } 588 }
570 589
571 bool NetworkQualityEstimator::GetRecentMedianRTT( 590 bool NetworkQualityEstimator::GetRecentMedianRTT(
572 const base::TimeTicks& begin_timestamp, 591 const base::TimeTicks& begin_timestamp,
573 base::TimeDelta* rtt) const { 592 base::TimeDelta* rtt) {
574 DCHECK(thread_checker_.CalledOnValidThread()); 593 DCHECK(thread_checker_.CalledOnValidThread());
575 DCHECK(rtt); 594 DCHECK(rtt);
595
596 MaybeQueryExternalEstimateProvider();
576 *rtt = GetRTTEstimateInternal(begin_timestamp, 50); 597 *rtt = GetRTTEstimateInternal(begin_timestamp, 50);
577 return (*rtt != InvalidRTT()); 598 return (*rtt != InvalidRTT());
578 } 599 }
579 600
580 bool NetworkQualityEstimator::GetRecentMedianDownlinkThroughputKbps( 601 bool NetworkQualityEstimator::GetRecentMedianDownlinkThroughputKbps(
581 const base::TimeTicks& begin_timestamp, 602 const base::TimeTicks& begin_timestamp,
582 int32_t* kbps) const { 603 int32_t* kbps) {
583 DCHECK(thread_checker_.CalledOnValidThread()); 604 DCHECK(thread_checker_.CalledOnValidThread());
584 DCHECK(kbps); 605 DCHECK(kbps);
606
607 MaybeQueryExternalEstimateProvider();
585 *kbps = GetDownlinkThroughputKbpsEstimateInternal(begin_timestamp, 50); 608 *kbps = GetDownlinkThroughputKbpsEstimateInternal(begin_timestamp, 50);
586 return (*kbps != kInvalidThroughput); 609 return (*kbps != kInvalidThroughput);
587 } 610 }
588 611
589 NetworkQualityEstimator::Observation::Observation(int32_t value, 612 NetworkQualityEstimator::Observation::Observation(int32_t value,
590 base::TimeTicks timestamp) 613 base::TimeTicks timestamp)
591 : value(value), timestamp(timestamp) { 614 : value(value), timestamp(timestamp) {
592 DCHECK_GE(value, 0); 615 DCHECK_GE(value, 0);
593 DCHECK(!timestamp.is_null()); 616 DCHECK(!timestamp.is_null());
594 } 617 }
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 DCHECK_NE(InvalidRTT(), network_quality.rtt()); 826 DCHECK_NE(InvalidRTT(), network_quality.rtt());
804 DCHECK_NE(kInvalidThroughput, network_quality.downstream_throughput_kbps()); 827 DCHECK_NE(kInvalidThroughput, network_quality.downstream_throughput_kbps());
805 828
806 downstream_throughput_kbps_observations_.AddObservation(Observation( 829 downstream_throughput_kbps_observations_.AddObservation(Observation(
807 network_quality.downstream_throughput_kbps(), base::TimeTicks::Now())); 830 network_quality.downstream_throughput_kbps(), base::TimeTicks::Now()));
808 rtt_msec_observations_.AddObservation(Observation( 831 rtt_msec_observations_.AddObservation(Observation(
809 network_quality.rtt().InMilliseconds(), base::TimeTicks::Now())); 832 network_quality.rtt().InMilliseconds(), base::TimeTicks::Now()));
810 return true; 833 return true;
811 } 834 }
812 835
813 void NetworkQualityEstimator::OnUpdatedEstimateAvailable() { 836 void NetworkQualityEstimator::OnUpdatedEstimateAvailable() {
mmenke 2015/09/11 15:07:22 Why is this needed? Seems like we pull it wheneve
tbansal1 2015/09/11 21:24:31 EEP that we are currently using on Android has asy
814 DCHECK(thread_checker_.CalledOnValidThread()); 837 DCHECK(thread_checker_.CalledOnValidThread());
815 DCHECK(external_estimates_provider_); 838 DCHECK(external_estimate_provider_);
816 // TODO(tbansal): Query provider for the recent value. 839
840 RecordExternalEstimateProviderMetrics(
841 EXTERNAL_ESTIMATE_PROVIDER_STATUS_CALLBACK);
842 QueryExternalEstimateProvider();
843 }
844
845 void NetworkQualityEstimator::MaybeQueryExternalEstimateProvider() {
846 if (base::TimeTicks::Now() - external_estimate_request_time_ >=
847 base::TimeDelta::FromMilliseconds(
848 kExternalEstimateProviderQueryIntervalMsec)) {
849 QueryExternalEstimateProvider();
850 }
851 }
852
853 void NetworkQualityEstimator::QueryExternalEstimateProvider() {
854 DCHECK(thread_checker_.CalledOnValidThread());
855
856 if (!external_estimate_provider_)
857 return;
858 RecordExternalEstimateProviderMetrics(
859 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERIED);
860 external_estimate_request_time_ = base::TimeTicks::Now();
861
862 base::TimeDelta time_since_last_update;
863 if (!external_estimate_provider_->GetTimeSinceLastUpdate(
864 &time_since_last_update) ||
865 time_since_last_update >
866 base::TimeDelta::FromMilliseconds(
867 kExternalEstimateProviderQueryIntervalMsec)) {
mmenke 2015/09/11 14:26:29 Why do both MaybeQueryExternalEstimateProvider and
tbansal1 2015/09/11 21:24:31 One is checking when was the last time native requ
868 // Request the external estimate provider for updated estimates. When the
869 // updates estimates are available, OnUpdatedEstimateAvailable() will get
870 // called.
871 external_estimate_provider_->RequestUpdate();
872 return;
873 }
874
875 RecordExternalEstimateProviderMetrics(
876 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERY_SUCCESSFUL);
877 base::TimeDelta rtt;
878 if (external_estimate_provider_->GetRTT(&rtt)) {
879 rtt_msec_observations_.AddObservation(Observation(
880 rtt.InMilliseconds(), base::TimeTicks::Now() - time_since_last_update));
mmenke 2015/09/11 14:26:29 So we just toss in the EEP's estimates in a bucket
tbansal1 2015/09/11 21:24:31 Long-term goal is to look at other useful events:
881 }
882
883 int32_t downstream_throughput_kbps;
884 if (external_estimate_provider_->GetDownstreamThroughputKbps(
885 &downstream_throughput_kbps)) {
886 downstream_throughput_kbps_observations_.AddObservation(
887 Observation(downstream_throughput_kbps,
888 base::TimeTicks::Now() - time_since_last_update));
889 }
817 } 890 }
818 891
819 void NetworkQualityEstimator::CacheNetworkQualityEstimate() { 892 void NetworkQualityEstimator::CacheNetworkQualityEstimate() {
820 DCHECK(thread_checker_.CalledOnValidThread()); 893 DCHECK(thread_checker_.CalledOnValidThread());
821 DCHECK_LE(cached_network_qualities_.size(), 894 DCHECK_LE(cached_network_qualities_.size(),
822 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); 895 static_cast<size_t>(kMaximumNetworkQualityCacheSize));
823 896
824 // If the network name is unavailable, caching should not be performed. 897 // If the network name is unavailable, caching should not be performed.
825 if (current_network_id_.id.empty()) 898 if (current_network_id_.id.empty())
826 return; 899 return;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 982
910 NetworkQualityEstimator::NetworkQuality& 983 NetworkQualityEstimator::NetworkQuality&
911 NetworkQualityEstimator::NetworkQuality:: 984 NetworkQualityEstimator::NetworkQuality::
912 operator=(const NetworkQuality& other) { 985 operator=(const NetworkQuality& other) {
913 rtt_ = other.rtt_; 986 rtt_ = other.rtt_;
914 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; 987 downstream_throughput_kbps_ = other.downstream_throughput_kbps_;
915 return *this; 988 return *this;
916 } 989 }
917 990
918 } // namespace net 991 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698