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 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 184 default_observations_[i] = | 184 default_observations_[i] = |
| 185 NetworkQuality(default_observations_[i].rtt(), variations_value); | 185 NetworkQuality(default_observations_[i].rtt(), variations_value); |
| 186 } | 186 } |
| 187 } | 187 } |
| 188 } | 188 } |
| 189 | 189 |
| 190 void NetworkQualityEstimator::AddDefaultEstimates() { | 190 void NetworkQualityEstimator::AddDefaultEstimates() { |
| 191 DCHECK(thread_checker_.CalledOnValidThread()); | 191 DCHECK(thread_checker_.CalledOnValidThread()); |
| 192 if (default_observations_[current_network_id_.type].rtt() != | 192 if (default_observations_[current_network_id_.type].rtt() != |
| 193 NetworkQuality::InvalidRTT()) { | 193 NetworkQuality::InvalidRTT()) { |
| 194 rtt_msec_observations_.AddObservation(Observation( | 194 Observation rtt_observation( |
| 195 default_observations_[current_network_id_.type].rtt().InMilliseconds(), | 195 default_observations_[current_network_id_.type].rtt().InMilliseconds(), |
| 196 base::TimeTicks::Now())); | 196 base::TimeTicks::Now(), OBSERVATION_SOURCE_DEFAULT_FROM_PLATFORM); |
| 197 rtt_msec_observations_.AddObservation(rtt_observation); | |
| 198 NotifyObserversOfRTT(rtt_observation); | |
| 197 } | 199 } |
| 198 if (default_observations_[current_network_id_.type] | 200 if (default_observations_[current_network_id_.type] |
| 199 .downstream_throughput_kbps() != NetworkQuality::kInvalidThroughput) { | 201 .downstream_throughput_kbps() != NetworkQuality::kInvalidThroughput) { |
| 200 kbps_observations_.AddObservation( | 202 Observation bandwidth_observation( |
| 201 Observation(default_observations_[current_network_id_.type] | 203 default_observations_[current_network_id_.type] |
| 202 .downstream_throughput_kbps(), | 204 .downstream_throughput_kbps(), |
| 203 base::TimeTicks::Now())); | 205 base::TimeTicks::Now(), OBSERVATION_SOURCE_DEFAULT_FROM_PLATFORM); |
| 206 kbps_observations_.AddObservation(bandwidth_observation); | |
| 207 NotifyObserversOfBandwidth(bandwidth_observation); | |
| 204 } | 208 } |
| 205 } | 209 } |
| 206 | 210 |
| 207 NetworkQualityEstimator::~NetworkQualityEstimator() { | 211 NetworkQualityEstimator::~NetworkQualityEstimator() { |
| 208 DCHECK(thread_checker_.CalledOnValidThread()); | 212 DCHECK(thread_checker_.CalledOnValidThread()); |
| 209 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); | 213 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); |
| 210 } | 214 } |
| 211 | 215 |
| 212 void NetworkQualityEstimator::NotifyDataReceived( | 216 void NetworkQualityEstimator::NotifyDataReceived( |
| 213 const URLRequest& request, | 217 const URLRequest& request, |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 253 if (cumulative_prefilter_bytes_read == prefiltered_bytes_read) { | 257 if (cumulative_prefilter_bytes_read == prefiltered_bytes_read) { |
| 254 // Duration between when the resource was requested and when response | 258 // Duration between when the resource was requested and when response |
| 255 // headers were received. | 259 // headers were received. |
| 256 base::TimeDelta observed_rtt = headers_received_time - request_start_time; | 260 base::TimeDelta observed_rtt = headers_received_time - request_start_time; |
| 257 DCHECK_GE(observed_rtt, base::TimeDelta()); | 261 DCHECK_GE(observed_rtt, base::TimeDelta()); |
| 258 if (observed_rtt < peak_network_quality_.rtt()) { | 262 if (observed_rtt < peak_network_quality_.rtt()) { |
| 259 peak_network_quality_ = NetworkQuality( | 263 peak_network_quality_ = NetworkQuality( |
| 260 observed_rtt, peak_network_quality_.downstream_throughput_kbps()); | 264 observed_rtt, peak_network_quality_.downstream_throughput_kbps()); |
| 261 } | 265 } |
| 262 | 266 |
| 263 rtt_msec_observations_.AddObservation( | 267 Observation rtt_observation(observed_rtt.InMilliseconds(), now, |
| 264 Observation(observed_rtt.InMilliseconds(), now)); | 268 OBSERVATION_SOURCE_URL_REQUEST); |
| 269 rtt_msec_observations_.AddObservation(rtt_observation); | |
| 270 NotifyObserversOfRTT(rtt_observation); | |
| 265 | 271 |
| 266 // Compare the RTT observation with the estimated value and record it. | 272 // Compare the RTT observation with the estimated value and record it. |
| 267 if (estimated_median_network_quality_.rtt() != | 273 if (estimated_median_network_quality_.rtt() != |
| 268 NetworkQuality::InvalidRTT()) { | 274 NetworkQuality::InvalidRTT()) { |
| 269 RecordRTTUMA(estimated_median_network_quality_.rtt().InMilliseconds(), | 275 RecordRTTUMA(estimated_median_network_quality_.rtt().InMilliseconds(), |
| 270 observed_rtt.InMilliseconds()); | 276 observed_rtt.InMilliseconds()); |
| 271 } | 277 } |
| 272 } | 278 } |
| 273 | 279 |
| 274 // Time since the resource was requested. | 280 // Time since the resource was requested. |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 297 // when there is no connection. | 303 // when there is no connection. |
| 298 if (kbps_f > 0.0 && kbps == 0) | 304 if (kbps_f > 0.0 && kbps == 0) |
| 299 kbps = 1; | 305 kbps = 1; |
| 300 | 306 |
| 301 if (kbps > 0) { | 307 if (kbps > 0) { |
| 302 if (kbps > peak_network_quality_.downstream_throughput_kbps()) { | 308 if (kbps > peak_network_quality_.downstream_throughput_kbps()) { |
| 303 peak_network_quality_ = | 309 peak_network_quality_ = |
| 304 NetworkQuality(peak_network_quality_.rtt(), kbps); | 310 NetworkQuality(peak_network_quality_.rtt(), kbps); |
| 305 } | 311 } |
| 306 | 312 |
| 307 kbps_observations_.AddObservation(Observation(kbps, now)); | 313 Observation bandwidth_observation(kbps, now, |
| 314 OBSERVATION_SOURCE_URL_REQUEST); | |
| 315 kbps_observations_.AddObservation(bandwidth_observation); | |
| 316 NotifyObserversOfBandwidth(bandwidth_observation); | |
| 308 } | 317 } |
| 309 } | 318 } |
| 310 } | 319 } |
| 311 | 320 |
| 321 void NetworkQualityEstimator::AddRTTObserver(RTTObserver* rtt_observer) { | |
| 322 rtt_observer_list_.AddObserver(rtt_observer); | |
| 323 } | |
| 324 | |
| 325 void NetworkQualityEstimator::RemoveRTTObserver(RTTObserver* rtt_observer) { | |
| 326 rtt_observer_list_.RemoveObserver(rtt_observer); | |
| 327 } | |
| 328 | |
| 329 void NetworkQualityEstimator::AddBandwidthObserver( | |
| 330 BandwidthObserver* bandwidth_observer) { | |
| 331 bandwidth_observer_list_.AddObserver(bandwidth_observer); | |
| 332 } | |
| 333 | |
| 334 void NetworkQualityEstimator::RemoveBandwidthObserver( | |
| 335 BandwidthObserver* bandwidth_observer) { | |
| 336 bandwidth_observer_list_.RemoveObserver(bandwidth_observer); | |
| 337 } | |
| 338 | |
| 339 void NetworkQualityEstimator::Configure(bool allow_local_host_requests, | |
| 340 bool allow_smaller_responses) { | |
| 341 allow_localhost_requests_ = allow_local_host_requests, | |
| 342 allow_small_responses_ = allow_smaller_responses; | |
| 343 } | |
| 344 | |
| 312 void NetworkQualityEstimator::RecordRTTUMA(int32_t estimated_value_msec, | 345 void NetworkQualityEstimator::RecordRTTUMA(int32_t estimated_value_msec, |
| 313 int32_t actual_value_msec) const { | 346 int32_t actual_value_msec) const { |
| 314 DCHECK(thread_checker_.CalledOnValidThread()); | 347 DCHECK(thread_checker_.CalledOnValidThread()); |
| 315 | 348 |
| 316 // Record the difference between the actual and the estimated value. | 349 // Record the difference between the actual and the estimated value. |
| 317 if (estimated_value_msec >= actual_value_msec) { | 350 if (estimated_value_msec >= actual_value_msec) { |
| 318 base::HistogramBase* difference_rtt = | 351 base::HistogramBase* difference_rtt = |
| 319 GetHistogram("DifferenceRTTEstimatedAndActual.", | 352 GetHistogram("DifferenceRTTEstimatedAndActual.", |
| 320 current_network_id_.type, 10 * 1000); // 10 seconds | 353 current_network_id_.type, 10 * 1000); // 10 seconds |
| 321 difference_rtt->Add(estimated_value_msec - actual_value_msec); | 354 difference_rtt->Add(estimated_value_msec - actual_value_msec); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 479 bool NetworkQualityEstimator::GetEstimate(NetworkQuality* median) const { | 512 bool NetworkQualityEstimator::GetEstimate(NetworkQuality* median) const { |
| 480 if (kbps_observations_.Size() == 0 || rtt_msec_observations_.Size() == 0) { | 513 if (kbps_observations_.Size() == 0 || rtt_msec_observations_.Size() == 0) { |
| 481 *median = NetworkQuality(); | 514 *median = NetworkQuality(); |
| 482 return false; | 515 return false; |
| 483 } | 516 } |
| 484 *median = GetEstimate(50); | 517 *median = GetEstimate(50); |
| 485 return true; | 518 return true; |
| 486 } | 519 } |
| 487 | 520 |
| 488 NetworkQualityEstimator::Observation::Observation(int32_t value, | 521 NetworkQualityEstimator::Observation::Observation(int32_t value, |
| 489 base::TimeTicks timestamp) | 522 base::TimeTicks timestamp, |
| 490 : value(value), timestamp(timestamp) { | 523 ObservationSource source) |
| 524 : value(value), timestamp(timestamp), source(source) { | |
| 491 DCHECK_GE(value, 0); | 525 DCHECK_GE(value, 0); |
| 492 DCHECK(!timestamp.is_null()); | 526 DCHECK(!timestamp.is_null()); |
| 493 } | 527 } |
| 494 | 528 |
| 495 NetworkQualityEstimator::Observation::~Observation() { | 529 NetworkQualityEstimator::Observation::~Observation() { |
| 496 } | 530 } |
| 497 | 531 |
| 498 NetworkQualityEstimator::ObservationBuffer::ObservationBuffer( | 532 NetworkQualityEstimator::ObservationBuffer::ObservationBuffer( |
| 499 double weight_multiplier_per_second) | 533 double weight_multiplier_per_second) |
| 500 : weight_multiplier_per_second_(weight_multiplier_per_second) { | 534 : weight_multiplier_per_second_(weight_multiplier_per_second) { |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 660 | 694 |
| 661 if (it == cached_network_qualities_.end()) | 695 if (it == cached_network_qualities_.end()) |
| 662 return false; | 696 return false; |
| 663 | 697 |
| 664 NetworkQuality network_quality(it->second.network_quality()); | 698 NetworkQuality network_quality(it->second.network_quality()); |
| 665 | 699 |
| 666 DCHECK_NE(NetworkQuality::InvalidRTT(), network_quality.rtt()); | 700 DCHECK_NE(NetworkQuality::InvalidRTT(), network_quality.rtt()); |
| 667 DCHECK_NE(NetworkQuality::kInvalidThroughput, | 701 DCHECK_NE(NetworkQuality::kInvalidThroughput, |
| 668 network_quality.downstream_throughput_kbps()); | 702 network_quality.downstream_throughput_kbps()); |
| 669 | 703 |
| 670 kbps_observations_.AddObservation(Observation( | 704 Observation bandwidth_observation( |
| 671 network_quality.downstream_throughput_kbps(), base::TimeTicks::Now())); | 705 network_quality.downstream_throughput_kbps(), base::TimeTicks::Now(), |
| 672 rtt_msec_observations_.AddObservation(Observation( | 706 OBSERVATION_SOURCE_CACHED_ESTIMATE); |
| 673 network_quality.rtt().InMilliseconds(), base::TimeTicks::Now())); | 707 Observation rtt_observation(network_quality.rtt().InMilliseconds(), |
| 708 base::TimeTicks::Now(), | |
| 709 OBSERVATION_SOURCE_CACHED_ESTIMATE); | |
| 710 kbps_observations_.AddObservation(bandwidth_observation); | |
|
mef
2015/08/11 17:16:27
I think it will be a little cleaner if bandwidth_o
bengr
2015/08/25 23:43:34
Done.
| |
| 711 rtt_msec_observations_.AddObservation(rtt_observation); | |
| 712 NotifyObserversOfBandwidth(bandwidth_observation); | |
| 713 NotifyObserversOfRTT(rtt_observation); | |
| 714 | |
| 674 return true; | 715 return true; |
| 675 } | 716 } |
| 676 | 717 |
| 677 void NetworkQualityEstimator::CacheNetworkQualityEstimate() { | 718 void NetworkQualityEstimator::CacheNetworkQualityEstimate() { |
| 678 DCHECK(thread_checker_.CalledOnValidThread()); | 719 DCHECK(thread_checker_.CalledOnValidThread()); |
| 679 DCHECK_LE(cached_network_qualities_.size(), | 720 DCHECK_LE(cached_network_qualities_.size(), |
| 680 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 721 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
| 681 | 722 |
| 682 // If the network name is unavailable, caching should not be performed. | 723 // If the network name is unavailable, caching should not be performed. |
| 683 if (current_network_id_.id.empty()) | 724 if (current_network_id_.id.empty()) |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 706 } | 747 } |
| 707 DCHECK_LT(cached_network_qualities_.size(), | 748 DCHECK_LT(cached_network_qualities_.size(), |
| 708 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 749 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
| 709 | 750 |
| 710 cached_network_qualities_.insert(std::make_pair( | 751 cached_network_qualities_.insert(std::make_pair( |
| 711 current_network_id_, CachedNetworkQuality(network_quality))); | 752 current_network_id_, CachedNetworkQuality(network_quality))); |
| 712 DCHECK_LE(cached_network_qualities_.size(), | 753 DCHECK_LE(cached_network_qualities_.size(), |
| 713 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); | 754 static_cast<size_t>(kMaximumNetworkQualityCacheSize)); |
| 714 } | 755 } |
| 715 | 756 |
| 757 void NetworkQualityEstimator::NotifyObserversOfRTT( | |
| 758 const Observation& observation) { | |
| 759 FOR_EACH_OBSERVER(RTTObserver, rtt_observer_list_, | |
| 760 OnRTTObservation(observation.value, observation.timestamp, | |
| 761 observation.source)); | |
| 762 } | |
| 763 | |
| 764 void NetworkQualityEstimator::NotifyObserversOfBandwidth( | |
| 765 const Observation& observation) { | |
| 766 FOR_EACH_OBSERVER( | |
| 767 BandwidthObserver, bandwidth_observer_list_, | |
| 768 OnBandwidthObservation(observation.value, observation.timestamp, | |
| 769 observation.source)); | |
| 770 } | |
| 771 | |
| 716 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( | 772 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( |
| 717 const NetworkQuality& network_quality) | 773 const NetworkQuality& network_quality) |
| 718 : last_update_time_(base::TimeTicks::Now()), | 774 : last_update_time_(base::TimeTicks::Now()), |
| 719 network_quality_(network_quality) { | 775 network_quality_(network_quality) { |
| 720 } | 776 } |
| 721 | 777 |
| 722 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( | 778 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( |
| 723 const CachedNetworkQuality& other) | 779 const CachedNetworkQuality& other) |
| 724 : last_update_time_(other.last_update_time_), | 780 : last_update_time_(other.last_update_time_), |
| 725 network_quality_(other.network_quality_) { | 781 network_quality_(other.network_quality_) { |
| 726 } | 782 } |
| 727 | 783 |
| 728 NetworkQualityEstimator::CachedNetworkQuality::~CachedNetworkQuality() { | 784 NetworkQualityEstimator::CachedNetworkQuality::~CachedNetworkQuality() { |
| 729 } | 785 } |
| 730 | 786 |
| 731 bool NetworkQualityEstimator::CachedNetworkQuality::OlderThan( | 787 bool NetworkQualityEstimator::CachedNetworkQuality::OlderThan( |
| 732 const CachedNetworkQuality& cached_network_quality) const { | 788 const CachedNetworkQuality& cached_network_quality) const { |
| 733 return last_update_time_ < cached_network_quality.last_update_time_; | 789 return last_update_time_ < cached_network_quality.last_update_time_; |
| 734 } | 790 } |
| 735 | 791 |
| 736 } // namespace net | 792 } // namespace net |
| OLD | NEW |