Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 246 variations_value >= kMinimumThroughputVariationParameterKbps) { | 246 variations_value >= kMinimumThroughputVariationParameterKbps) { |
| 247 default_observations_[i] = | 247 default_observations_[i] = |
| 248 NetworkQuality(default_observations_[i].rtt(), variations_value); | 248 NetworkQuality(default_observations_[i].rtt(), variations_value); |
| 249 } | 249 } |
| 250 } | 250 } |
| 251 } | 251 } |
| 252 | 252 |
| 253 void NetworkQualityEstimator::AddDefaultEstimates() { | 253 void NetworkQualityEstimator::AddDefaultEstimates() { |
| 254 DCHECK(thread_checker_.CalledOnValidThread()); | 254 DCHECK(thread_checker_.CalledOnValidThread()); |
| 255 if (default_observations_[current_network_id_.type].rtt() != InvalidRTT()) { | 255 if (default_observations_[current_network_id_.type].rtt() != InvalidRTT()) { |
| 256 rtt_msec_observations_.AddObservation(Observation( | 256 Observation rtt_observation( |
| 257 default_observations_[current_network_id_.type].rtt().InMilliseconds(), | 257 default_observations_[current_network_id_.type].rtt().InMilliseconds(), |
| 258 base::TimeTicks::Now())); | 258 base::TimeTicks::Now(), DEFAULT_FROM_PLATFORM); |
| 259 rtt_msec_observations_.AddObservation(rtt_observation); | |
| 260 NotifyObserversOfRTT(rtt_observation); | |
| 259 } | 261 } |
| 260 if (default_observations_[current_network_id_.type] | 262 if (default_observations_[current_network_id_.type] |
| 261 .downstream_throughput_kbps() != kInvalidThroughput) { | 263 .downstream_throughput_kbps() != kInvalidThroughput) { |
| 264 Observation throughput_observation( | |
| 265 default_observations_[current_network_id_.type] | |
| 266 .downstream_throughput_kbps(), | |
| 267 base::TimeTicks::Now(), DEFAULT_FROM_PLATFORM); | |
| 262 downstream_throughput_kbps_observations_.AddObservation( | 268 downstream_throughput_kbps_observations_.AddObservation( |
| 263 Observation(default_observations_[current_network_id_.type] | 269 throughput_observation); |
| 264 .downstream_throughput_kbps(), | 270 NotifyObserversOfThroughput(throughput_observation); |
| 265 base::TimeTicks::Now())); | |
| 266 } | 271 } |
| 267 } | 272 } |
| 268 | 273 |
| 269 NetworkQualityEstimator::~NetworkQualityEstimator() { | 274 NetworkQualityEstimator::~NetworkQualityEstimator() { |
| 270 DCHECK(thread_checker_.CalledOnValidThread()); | 275 DCHECK(thread_checker_.CalledOnValidThread()); |
| 271 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); | 276 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); |
| 272 } | 277 } |
| 273 | 278 |
| 274 void NetworkQualityEstimator::NotifyHeadersReceived(const URLRequest& request) { | 279 void NetworkQualityEstimator::NotifyHeadersReceived(const URLRequest& request) { |
| 275 DCHECK(thread_checker_.CalledOnValidThread()); | 280 DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 303 | 308 |
| 304 // Duration between when the resource was requested and when response | 309 // Duration between when the resource was requested and when response |
| 305 // headers were received. | 310 // headers were received. |
| 306 base::TimeDelta observed_rtt = headers_received_time - request_start_time; | 311 base::TimeDelta observed_rtt = headers_received_time - request_start_time; |
| 307 DCHECK_GE(observed_rtt, base::TimeDelta()); | 312 DCHECK_GE(observed_rtt, base::TimeDelta()); |
| 308 if (observed_rtt < peak_network_quality_.rtt()) { | 313 if (observed_rtt < peak_network_quality_.rtt()) { |
| 309 peak_network_quality_ = NetworkQuality( | 314 peak_network_quality_ = NetworkQuality( |
| 310 observed_rtt, peak_network_quality_.downstream_throughput_kbps()); | 315 observed_rtt, peak_network_quality_.downstream_throughput_kbps()); |
| 311 } | 316 } |
| 312 | 317 |
| 313 rtt_msec_observations_.AddObservation( | 318 Observation rtt_observation(observed_rtt.InMilliseconds(), now, |
| 314 Observation(observed_rtt.InMilliseconds(), now)); | 319 URL_REQUEST); |
| 320 rtt_msec_observations_.AddObservation(rtt_observation); | |
| 321 NotifyObserversOfRTT(rtt_observation); | |
| 315 | 322 |
| 316 // Compare the RTT observation with the estimated value and record it. | 323 // Compare the RTT observation with the estimated value and record it. |
| 317 if (estimated_median_network_quality_.rtt() != InvalidRTT()) { | 324 if (estimated_median_network_quality_.rtt() != InvalidRTT()) { |
| 318 RecordRTTUMA(estimated_median_network_quality_.rtt().InMilliseconds(), | 325 RecordRTTUMA(estimated_median_network_quality_.rtt().InMilliseconds(), |
| 319 observed_rtt.InMilliseconds()); | 326 observed_rtt.InMilliseconds()); |
| 320 } | 327 } |
| 321 } | 328 } |
| 322 | 329 |
| 323 void NetworkQualityEstimator::NotifyRequestCompleted( | 330 void NetworkQualityEstimator::NotifyRequestCompleted( |
| 324 const URLRequest& request) { | 331 const URLRequest& request) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 371 // connection. | 378 // connection. |
| 372 if (downstream_kbps - downstream_kbps_as_integer > 0) | 379 if (downstream_kbps - downstream_kbps_as_integer > 0) |
| 373 downstream_kbps_as_integer++; | 380 downstream_kbps_as_integer++; |
| 374 | 381 |
| 375 DCHECK_GT(downstream_kbps_as_integer, 0.0); | 382 DCHECK_GT(downstream_kbps_as_integer, 0.0); |
| 376 if (downstream_kbps_as_integer > | 383 if (downstream_kbps_as_integer > |
| 377 peak_network_quality_.downstream_throughput_kbps()) | 384 peak_network_quality_.downstream_throughput_kbps()) |
| 378 peak_network_quality_ = | 385 peak_network_quality_ = |
| 379 NetworkQuality(peak_network_quality_.rtt(), downstream_kbps_as_integer); | 386 NetworkQuality(peak_network_quality_.rtt(), downstream_kbps_as_integer); |
| 380 | 387 |
| 388 Observation throughput_observation(downstream_kbps_as_integer, now, | |
| 389 URL_REQUEST); | |
| 381 downstream_throughput_kbps_observations_.AddObservation( | 390 downstream_throughput_kbps_observations_.AddObservation( |
| 382 Observation(downstream_kbps_as_integer, now)); | 391 throughput_observation); |
| 392 NotifyObserversOfThroughput(throughput_observation); | |
| 393 } | |
| 394 | |
| 395 void NetworkQualityEstimator::AddRTTObserver(RTTObserver* rtt_observer) { | |
| 396 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 397 rtt_observer_list_.AddObserver(rtt_observer); | |
| 398 } | |
| 399 | |
| 400 void NetworkQualityEstimator::RemoveRTTObserver(RTTObserver* rtt_observer) { | |
| 401 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 402 rtt_observer_list_.RemoveObserver(rtt_observer); | |
| 403 } | |
| 404 | |
| 405 void NetworkQualityEstimator::AddThroughputObserver( | |
| 406 ThroughputObserver* throughput_observer) { | |
| 407 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 408 throughput_observer_list_.AddObserver(throughput_observer); | |
| 409 } | |
| 410 | |
| 411 void NetworkQualityEstimator::RemoveThroughputObserver( | |
| 412 ThroughputObserver* throughput_observer) { | |
| 413 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 414 throughput_observer_list_.RemoveObserver(throughput_observer); | |
| 383 } | 415 } |
| 384 | 416 |
| 385 void NetworkQualityEstimator::RecordRTTUMA(int32_t estimated_value_msec, | 417 void NetworkQualityEstimator::RecordRTTUMA(int32_t estimated_value_msec, |
| 386 int32_t actual_value_msec) const { | 418 int32_t actual_value_msec) const { |
| 387 DCHECK(thread_checker_.CalledOnValidThread()); | 419 DCHECK(thread_checker_.CalledOnValidThread()); |
| 388 | 420 |
| 389 // Record the difference between the actual and the estimated value. | 421 // Record the difference between the actual and the estimated value. |
| 390 if (estimated_value_msec >= actual_value_msec) { | 422 if (estimated_value_msec >= actual_value_msec) { |
| 391 base::HistogramBase* difference_rtt = | 423 base::HistogramBase* difference_rtt = |
| 392 GetHistogram("DifferenceRTTEstimatedAndActual.", | 424 GetHistogram("DifferenceRTTEstimatedAndActual.", |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 598 bool NetworkQualityEstimator::GetRecentMedianDownlinkThroughputKbps( | 630 bool NetworkQualityEstimator::GetRecentMedianDownlinkThroughputKbps( |
| 599 const base::TimeTicks& begin_timestamp, | 631 const base::TimeTicks& begin_timestamp, |
| 600 int32_t* kbps) const { | 632 int32_t* kbps) const { |
| 601 DCHECK(thread_checker_.CalledOnValidThread()); | 633 DCHECK(thread_checker_.CalledOnValidThread()); |
| 602 DCHECK(kbps); | 634 DCHECK(kbps); |
| 603 *kbps = GetDownlinkThroughputKbpsEstimateInternal(begin_timestamp, 50); | 635 *kbps = GetDownlinkThroughputKbpsEstimateInternal(begin_timestamp, 50); |
| 604 return (*kbps != kInvalidThroughput); | 636 return (*kbps != kInvalidThroughput); |
| 605 } | 637 } |
| 606 | 638 |
| 607 NetworkQualityEstimator::Observation::Observation(int32_t value, | 639 NetworkQualityEstimator::Observation::Observation(int32_t value, |
| 608 base::TimeTicks timestamp) | 640 base::TimeTicks timestamp, |
| 609 : value(value), timestamp(timestamp) { | 641 ObservationSource source) |
| 642 : value(value), timestamp(timestamp), source(source) { | |
| 610 DCHECK_GE(value, 0); | 643 DCHECK_GE(value, 0); |
| 611 DCHECK(!timestamp.is_null()); | 644 DCHECK(!timestamp.is_null()); |
| 612 } | 645 } |
| 613 | 646 |
| 614 NetworkQualityEstimator::Observation::~Observation() { | 647 NetworkQualityEstimator::Observation::~Observation() { |
| 615 } | 648 } |
| 616 | 649 |
| 617 NetworkQualityEstimator::ObservationBuffer::ObservationBuffer( | 650 NetworkQualityEstimator::ObservationBuffer::ObservationBuffer( |
| 618 double weight_multiplier_per_second) | 651 double weight_multiplier_per_second) |
| 619 : weight_multiplier_per_second_(weight_multiplier_per_second) { | 652 : weight_multiplier_per_second_(weight_multiplier_per_second) { |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 814 cached_network_qualities_.find(current_network_id_); | 847 cached_network_qualities_.find(current_network_id_); |
| 815 | 848 |
| 816 if (it == cached_network_qualities_.end()) | 849 if (it == cached_network_qualities_.end()) |
| 817 return false; | 850 return false; |
| 818 | 851 |
| 819 NetworkQuality network_quality(it->second.network_quality()); | 852 NetworkQuality network_quality(it->second.network_quality()); |
| 820 | 853 |
| 821 DCHECK_NE(InvalidRTT(), network_quality.rtt()); | 854 DCHECK_NE(InvalidRTT(), network_quality.rtt()); |
| 822 DCHECK_NE(kInvalidThroughput, network_quality.downstream_throughput_kbps()); | 855 DCHECK_NE(kInvalidThroughput, network_quality.downstream_throughput_kbps()); |
| 823 | 856 |
| 824 downstream_throughput_kbps_observations_.AddObservation(Observation( | 857 Observation througphput_observation( |
| 825 network_quality.downstream_throughput_kbps(), base::TimeTicks::Now())); | 858 network_quality.downstream_throughput_kbps(), base::TimeTicks::Now(), |
| 826 rtt_msec_observations_.AddObservation(Observation( | 859 CACHED_ESTIMATE); |
| 827 network_quality.rtt().InMilliseconds(), base::TimeTicks::Now())); | 860 downstream_throughput_kbps_observations_.AddObservation( |
| 861 througphput_observation); | |
| 862 NotifyObserversOfThroughput(througphput_observation); | |
|
pauljensen
2015/10/06 19:10:29
This is a little odd. We didn't really observe a
| |
| 863 | |
| 864 Observation rtt_observation(network_quality.rtt().InMilliseconds(), | |
| 865 base::TimeTicks::Now(), CACHED_ESTIMATE); | |
| 866 rtt_msec_observations_.AddObservation(rtt_observation); | |
| 867 NotifyObserversOfRTT(rtt_observation); | |
| 868 | |
| 828 return true; | 869 return true; |
| 829 } | 870 } |
| 830 | 871 |
| 831 void NetworkQualityEstimator::OnUpdatedEstimateAvailable() { | 872 void NetworkQualityEstimator::OnUpdatedEstimateAvailable() { |
| 832 DCHECK(thread_checker_.CalledOnValidThread()); | 873 DCHECK(thread_checker_.CalledOnValidThread()); |
| 833 DCHECK(external_estimate_provider_); | 874 DCHECK(external_estimate_provider_); |
| 834 | 875 |
| 835 RecordExternalEstimateProviderMetrics( | 876 RecordExternalEstimateProviderMetrics( |
| 836 EXTERNAL_ESTIMATE_PROVIDER_STATUS_CALLBACK); | 877 EXTERNAL_ESTIMATE_PROVIDER_STATUS_CALLBACK); |
| 837 QueryExternalEstimateProvider(); | 878 QueryExternalEstimateProvider(); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 858 // updates estimates are available, OnUpdatedEstimateAvailable() will be | 899 // updates estimates are available, OnUpdatedEstimateAvailable() will be |
| 859 // called. | 900 // called. |
| 860 external_estimate_provider_->Update(); | 901 external_estimate_provider_->Update(); |
| 861 return; | 902 return; |
| 862 } | 903 } |
| 863 | 904 |
| 864 RecordExternalEstimateProviderMetrics( | 905 RecordExternalEstimateProviderMetrics( |
| 865 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERY_SUCCESSFUL); | 906 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERY_SUCCESSFUL); |
| 866 base::TimeDelta rtt; | 907 base::TimeDelta rtt; |
| 867 if (external_estimate_provider_->GetRTT(&rtt)) { | 908 if (external_estimate_provider_->GetRTT(&rtt)) { |
| 868 rtt_msec_observations_.AddObservation( | 909 rtt_msec_observations_.AddObservation(Observation( |
| 869 Observation(rtt.InMilliseconds(), base::TimeTicks::Now())); | 910 rtt.InMilliseconds(), base::TimeTicks::Now(), EXTERNAL_ESTIMATE)); |
| 870 } | 911 } |
| 871 | 912 |
| 872 int32_t downstream_throughput_kbps; | 913 int32_t downstream_throughput_kbps; |
| 873 if (external_estimate_provider_->GetDownstreamThroughputKbps( | 914 if (external_estimate_provider_->GetDownstreamThroughputKbps( |
| 874 &downstream_throughput_kbps)) { | 915 &downstream_throughput_kbps)) { |
| 875 downstream_throughput_kbps_observations_.AddObservation( | 916 downstream_throughput_kbps_observations_.AddObservation(Observation( |
| 876 Observation(downstream_throughput_kbps, base::TimeTicks::Now())); | 917 downstream_throughput_kbps, base::TimeTicks::Now(), EXTERNAL_ESTIMATE)); |
| 877 } | 918 } |
| 878 } | 919 } |
| 879 | 920 |
| 880 void NetworkQualityEstimator::CacheNetworkQualityEstimate() { | 921 void NetworkQualityEstimator::CacheNetworkQualityEstimate() { |
| 881 DCHECK(thread_checker_.CalledOnValidThread()); | 922 DCHECK(thread_checker_.CalledOnValidThread()); |
| 882 DCHECK_LE(cached_network_qualities_.size(), | 923 DCHECK_LE(cached_network_qualities_.size(), |
| 883 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 924 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
| 884 | 925 |
| 885 // If the network name is unavailable, caching should not be performed. | 926 // If the network name is unavailable, caching should not be performed. |
| 886 if (current_network_id_.id.empty()) | 927 if (current_network_id_.id.empty()) |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 923 new SocketPerformanceWatcherTCP()); | 964 new SocketPerformanceWatcherTCP()); |
| 924 } | 965 } |
| 925 | 966 |
| 926 scoped_ptr<SocketPerformanceWatcher> | 967 scoped_ptr<SocketPerformanceWatcher> |
| 927 NetworkQualityEstimator::CreateUDPSocketPerformanceWatcher() const { | 968 NetworkQualityEstimator::CreateUDPSocketPerformanceWatcher() const { |
| 928 DCHECK(thread_checker_.CalledOnValidThread()); | 969 DCHECK(thread_checker_.CalledOnValidThread()); |
| 929 return scoped_ptr<SocketPerformanceWatcher>( | 970 return scoped_ptr<SocketPerformanceWatcher>( |
| 930 new SocketPerformanceWatcherUDP()); | 971 new SocketPerformanceWatcherUDP()); |
| 931 } | 972 } |
| 932 | 973 |
| 974 void NetworkQualityEstimator::NotifyObserversOfRTT( | |
| 975 const Observation& observation) { | |
| 976 FOR_EACH_OBSERVER(RTTObserver, rtt_observer_list_, | |
| 977 OnRTTObservation(observation.value, observation.timestamp, | |
| 978 observation.source)); | |
| 979 } | |
| 980 | |
| 981 void NetworkQualityEstimator::NotifyObserversOfThroughput( | |
| 982 const Observation& observation) { | |
| 983 FOR_EACH_OBSERVER( | |
| 984 ThroughputObserver, throughput_observer_list_, | |
| 985 OnThroughputObservation(observation.value, observation.timestamp, | |
| 986 observation.source)); | |
| 987 } | |
| 988 | |
| 933 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( | 989 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( |
| 934 const NetworkQuality& network_quality) | 990 const NetworkQuality& network_quality) |
| 935 : last_update_time_(base::TimeTicks::Now()), | 991 : last_update_time_(base::TimeTicks::Now()), |
| 936 network_quality_(network_quality) { | 992 network_quality_(network_quality) { |
| 937 } | 993 } |
| 938 | 994 |
| 939 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( | 995 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( |
| 940 const CachedNetworkQuality& other) | 996 const CachedNetworkQuality& other) |
| 941 : last_update_time_(other.last_update_time_), | 997 : last_update_time_(other.last_update_time_), |
| 942 network_quality_(other.network_quality_) { | 998 network_quality_(other.network_quality_) { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 970 | 1026 |
| 971 NetworkQualityEstimator::NetworkQuality& | 1027 NetworkQualityEstimator::NetworkQuality& |
| 972 NetworkQualityEstimator::NetworkQuality:: | 1028 NetworkQualityEstimator::NetworkQuality:: |
| 973 operator=(const NetworkQuality& other) { | 1029 operator=(const NetworkQuality& other) { |
| 974 rtt_ = other.rtt_; | 1030 rtt_ = other.rtt_; |
| 975 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; | 1031 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; |
| 976 return *this; | 1032 return *this; |
| 977 } | 1033 } |
| 978 | 1034 |
| 979 } // namespace net | 1035 } // namespace net |
| OLD | NEW |