| 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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 bool allow_smaller_responses_for_tests) | 134 bool allow_smaller_responses_for_tests) |
| 135 : allow_localhost_requests_(allow_local_host_requests_for_tests), | 135 : allow_localhost_requests_(allow_local_host_requests_for_tests), |
| 136 allow_small_responses_(allow_smaller_responses_for_tests), | 136 allow_small_responses_(allow_smaller_responses_for_tests), |
| 137 last_connection_change_(base::TimeTicks::Now()), | 137 last_connection_change_(base::TimeTicks::Now()), |
| 138 current_network_id_( | 138 current_network_id_( |
| 139 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, | 139 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, |
| 140 std::string())), | 140 std::string())), |
| 141 downstream_throughput_kbps_observations_( | 141 downstream_throughput_kbps_observations_( |
| 142 GetWeightMultiplierPerSecond(variation_params)), | 142 GetWeightMultiplierPerSecond(variation_params)), |
| 143 rtt_msec_observations_(GetWeightMultiplierPerSecond(variation_params)), | 143 rtt_msec_observations_(GetWeightMultiplierPerSecond(variation_params)), |
| 144 packet_loss_rate_observations_( |
| 145 GetWeightMultiplierPerSecond(variation_params)), |
| 144 external_estimate_provider_(std::move(external_estimates_provider)) { | 146 external_estimate_provider_(std::move(external_estimates_provider)) { |
| 145 static_assert(kMinRequestDurationMicroseconds > 0, | 147 static_assert(kMinRequestDurationMicroseconds > 0, |
| 146 "Minimum request duration must be > 0"); | 148 "Minimum request duration must be > 0"); |
| 147 static_assert(kDefaultHalfLifeSeconds > 0, | 149 static_assert(kDefaultHalfLifeSeconds > 0, |
| 148 "Default half life duration must be > 0"); | 150 "Default half life duration must be > 0"); |
| 149 static_assert(kMaximumNetworkQualityCacheSize > 0, | 151 static_assert(kMaximumNetworkQualityCacheSize > 0, |
| 150 "Size of the network quality cache must be > 0"); | 152 "Size of the network quality cache must be > 0"); |
| 151 // This limit should not be increased unless the logic for removing the | 153 // This limit should not be increased unless the logic for removing the |
| 152 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. | 154 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. |
| 153 static_assert(kMaximumNetworkQualityCacheSize <= 10, | 155 static_assert(kMaximumNetworkQualityCacheSize <= 10, |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 DCHECK(thread_checker_.CalledOnValidThread()); | 245 DCHECK(thread_checker_.CalledOnValidThread()); |
| 244 | 246 |
| 245 if (!RequestProvidesUsefulObservations(request)) | 247 if (!RequestProvidesUsefulObservations(request)) |
| 246 return; | 248 return; |
| 247 | 249 |
| 248 // Update |estimated_median_network_quality_| if this is a main frame request. | 250 // Update |estimated_median_network_quality_| if this is a main frame request. |
| 249 if (request.load_flags() & LOAD_MAIN_FRAME) { | 251 if (request.load_flags() & LOAD_MAIN_FRAME) { |
| 250 estimated_median_network_quality_ = NetworkQuality( | 252 estimated_median_network_quality_ = NetworkQuality( |
| 251 GetRTTEstimateInternal(base::TimeTicks(), 50), | 253 GetRTTEstimateInternal(base::TimeTicks(), 50), |
| 252 GetDownlinkThroughputKbpsEstimateInternal(base::TimeTicks(), 50)); | 254 GetDownlinkThroughputKbpsEstimateInternal(base::TimeTicks(), 50)); |
| 255 |
| 256 float packet_loss_rate; |
| 257 if (GetPacketLossRateEstimate(&packet_loss_rate)) { |
| 258 DCHECK_LE(0.0f, packet_loss_rate); |
| 259 DCHECK_GE(1.0f, packet_loss_rate); |
| 260 |
| 261 // Largest bucket is 101. |
| 262 base::HistogramBase* packet_loss_histogram = |
| 263 GetHistogram("PacketLossRate.", current_network_id_.type, 101); |
| 264 packet_loss_histogram->Add(packet_loss_rate * 100.0f); |
| 265 } |
| 253 } | 266 } |
| 254 | 267 |
| 255 base::TimeTicks now = base::TimeTicks::Now(); | 268 base::TimeTicks now = base::TimeTicks::Now(); |
| 256 LoadTimingInfo load_timing_info; | 269 LoadTimingInfo load_timing_info; |
| 257 request.GetLoadTimingInfo(&load_timing_info); | 270 request.GetLoadTimingInfo(&load_timing_info); |
| 258 | 271 |
| 259 // If the load timing info is unavailable, it probably means that the request | 272 // If the load timing info is unavailable, it probably means that the request |
| 260 // did not go over the network. | 273 // did not go over the network. |
| 261 if (load_timing_info.send_start.is_null() || | 274 if (load_timing_info.send_start.is_null() || |
| 262 load_timing_info.receive_headers_end.is_null()) { | 275 load_timing_info.receive_headers_end.is_null()) { |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 DCHECK(thread_checker_.CalledOnValidThread()); | 382 DCHECK(thread_checker_.CalledOnValidThread()); |
| 370 throughput_observer_list_.AddObserver(throughput_observer); | 383 throughput_observer_list_.AddObserver(throughput_observer); |
| 371 } | 384 } |
| 372 | 385 |
| 373 void NetworkQualityEstimator::RemoveThroughputObserver( | 386 void NetworkQualityEstimator::RemoveThroughputObserver( |
| 374 ThroughputObserver* throughput_observer) { | 387 ThroughputObserver* throughput_observer) { |
| 375 DCHECK(thread_checker_.CalledOnValidThread()); | 388 DCHECK(thread_checker_.CalledOnValidThread()); |
| 376 throughput_observer_list_.RemoveObserver(throughput_observer); | 389 throughput_observer_list_.RemoveObserver(throughput_observer); |
| 377 } | 390 } |
| 378 | 391 |
| 392 void NetworkQualityEstimator::AddPacketLossObserver( |
| 393 PacketLossObserver* packet_loss_observer) { |
| 394 DCHECK(thread_checker_.CalledOnValidThread()); |
| 395 packet_loss_observer_list_.AddObserver(packet_loss_observer); |
| 396 } |
| 397 |
| 398 void NetworkQualityEstimator::RemovePacketLossObserver( |
| 399 PacketLossObserver* packet_loss_observer) { |
| 400 DCHECK(thread_checker_.CalledOnValidThread()); |
| 401 packet_loss_observer_list_.RemoveObserver(packet_loss_observer); |
| 402 } |
| 403 |
| 379 void NetworkQualityEstimator::RecordRTTUMA(int32_t estimated_value_msec, | 404 void NetworkQualityEstimator::RecordRTTUMA(int32_t estimated_value_msec, |
| 380 int32_t actual_value_msec) const { | 405 int32_t actual_value_msec) const { |
| 381 DCHECK(thread_checker_.CalledOnValidThread()); | 406 DCHECK(thread_checker_.CalledOnValidThread()); |
| 382 | 407 |
| 383 // Record the difference between the actual and the estimated value. | 408 // Record the difference between the actual and the estimated value. |
| 384 if (estimated_value_msec >= actual_value_msec) { | 409 if (estimated_value_msec >= actual_value_msec) { |
| 385 base::HistogramBase* difference_rtt = | 410 base::HistogramBase* difference_rtt = |
| 386 GetHistogram("DifferenceRTTEstimatedAndActual.", | 411 GetHistogram("DifferenceRTTEstimatedAndActual.", |
| 387 current_network_id_.type, 10 * 1000); // 10 seconds | 412 current_network_id_.type, 10 * 1000); // 10 seconds |
| 388 difference_rtt->Add(estimated_value_msec - actual_value_msec); | 413 difference_rtt->Add(estimated_value_msec - actual_value_msec); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 !request.was_cached() && | 447 !request.was_cached() && |
| 423 request.creation_time() >= last_connection_change_; | 448 request.creation_time() >= last_connection_change_; |
| 424 } | 449 } |
| 425 | 450 |
| 426 void NetworkQualityEstimator::RecordExternalEstimateProviderMetrics( | 451 void NetworkQualityEstimator::RecordExternalEstimateProviderMetrics( |
| 427 NQEExternalEstimateProviderStatus status) const { | 452 NQEExternalEstimateProviderStatus status) const { |
| 428 UMA_HISTOGRAM_ENUMERATION("NQE.ExternalEstimateProviderStatus", status, | 453 UMA_HISTOGRAM_ENUMERATION("NQE.ExternalEstimateProviderStatus", status, |
| 429 EXTERNAL_ESTIMATE_PROVIDER_STATUS_BOUNDARY); | 454 EXTERNAL_ESTIMATE_PROVIDER_STATUS_BOUNDARY); |
| 430 } | 455 } |
| 431 | 456 |
| 457 bool NetworkQualityEstimator::GetObservationSourceForProtocol( |
| 458 Protocol protocol, |
| 459 NetworkQualityEstimator::ObservationSource* observation_source) const { |
| 460 switch (protocol) { |
| 461 case PROTOCOL_TCP: |
| 462 *observation_source = TCP; |
| 463 return true; |
| 464 case PROTOCOL_QUIC: |
| 465 *observation_source = QUIC; |
| 466 return true; |
| 467 default: |
| 468 NOTREACHED(); |
| 469 return false; |
| 470 } |
| 471 } |
| 472 |
| 432 void NetworkQualityEstimator::OnConnectionTypeChanged( | 473 void NetworkQualityEstimator::OnConnectionTypeChanged( |
| 433 NetworkChangeNotifier::ConnectionType type) { | 474 NetworkChangeNotifier::ConnectionType type) { |
| 434 DCHECK(thread_checker_.CalledOnValidThread()); | 475 DCHECK(thread_checker_.CalledOnValidThread()); |
| 435 if (peak_network_quality_.rtt() != InvalidRTT()) { | 476 if (peak_network_quality_.rtt() != InvalidRTT()) { |
| 436 switch (current_network_id_.type) { | 477 switch (current_network_id_.type) { |
| 437 case NetworkChangeNotifier::CONNECTION_UNKNOWN: | 478 case NetworkChangeNotifier::CONNECTION_UNKNOWN: |
| 438 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Unknown", | 479 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Unknown", |
| 439 peak_network_quality_.rtt()); | 480 peak_network_quality_.rtt()); |
| 440 break; | 481 break; |
| 441 case NetworkChangeNotifier::CONNECTION_ETHERNET: | 482 case NetworkChangeNotifier::CONNECTION_ETHERNET: |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 } | 580 } |
| 540 | 581 |
| 541 // Write the estimates of the previous network to the cache. | 582 // Write the estimates of the previous network to the cache. |
| 542 CacheNetworkQualityEstimate(); | 583 CacheNetworkQualityEstimate(); |
| 543 | 584 |
| 544 // Clear the local state. | 585 // Clear the local state. |
| 545 last_connection_change_ = base::TimeTicks::Now(); | 586 last_connection_change_ = base::TimeTicks::Now(); |
| 546 peak_network_quality_ = NetworkQuality(); | 587 peak_network_quality_ = NetworkQuality(); |
| 547 downstream_throughput_kbps_observations_.Clear(); | 588 downstream_throughput_kbps_observations_.Clear(); |
| 548 rtt_msec_observations_.Clear(); | 589 rtt_msec_observations_.Clear(); |
| 590 packet_loss_rate_observations_.Clear(); |
| 549 current_network_id_ = GetCurrentNetworkID(); | 591 current_network_id_ = GetCurrentNetworkID(); |
| 550 | 592 |
| 551 QueryExternalEstimateProvider(); | 593 QueryExternalEstimateProvider(); |
| 552 | 594 |
| 553 // Read any cached estimates for the new network. If cached estimates are | 595 // Read any cached estimates for the new network. If cached estimates are |
| 554 // unavailable, add the default estimates. | 596 // unavailable, add the default estimates. |
| 555 if (!ReadCachedNetworkQualityEstimate()) | 597 if (!ReadCachedNetworkQualityEstimate()) |
| 556 AddDefaultEstimates(); | 598 AddDefaultEstimates(); |
| 557 estimated_median_network_quality_ = NetworkQuality(); | 599 estimated_median_network_quality_ = NetworkQuality(); |
| 558 } | 600 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 573 DCHECK(thread_checker_.CalledOnValidThread()); | 615 DCHECK(thread_checker_.CalledOnValidThread()); |
| 574 DCHECK(kbps); | 616 DCHECK(kbps); |
| 575 if (downstream_throughput_kbps_observations_.Size() == 0) { | 617 if (downstream_throughput_kbps_observations_.Size() == 0) { |
| 576 *kbps = kInvalidThroughput; | 618 *kbps = kInvalidThroughput; |
| 577 return false; | 619 return false; |
| 578 } | 620 } |
| 579 *kbps = GetDownlinkThroughputKbpsEstimateInternal(base::TimeTicks(), 50); | 621 *kbps = GetDownlinkThroughputKbpsEstimateInternal(base::TimeTicks(), 50); |
| 580 return (*kbps != kInvalidThroughput); | 622 return (*kbps != kInvalidThroughput); |
| 581 } | 623 } |
| 582 | 624 |
| 625 bool NetworkQualityEstimator::GetPacketLossRateEstimate( |
| 626 float* packet_loss_rate_estimate) const { |
| 627 DCHECK(thread_checker_.CalledOnValidThread()); |
| 628 |
| 629 float estimate = GetPacketLossRateEstimateInternal(base::TimeTicks()); |
| 630 if (estimate < 0.0f || estimate > 1.0f) |
| 631 return false; |
| 632 *packet_loss_rate_estimate = estimate; |
| 633 return true; |
| 634 } |
| 635 |
| 583 bool NetworkQualityEstimator::GetRecentMedianRTT( | 636 bool NetworkQualityEstimator::GetRecentMedianRTT( |
| 584 const base::TimeTicks& begin_timestamp, | 637 const base::TimeTicks& begin_timestamp, |
| 585 base::TimeDelta* rtt) const { | 638 base::TimeDelta* rtt) const { |
| 586 DCHECK(thread_checker_.CalledOnValidThread()); | 639 DCHECK(thread_checker_.CalledOnValidThread()); |
| 587 DCHECK(rtt); | 640 DCHECK(rtt); |
| 588 *rtt = GetRTTEstimateInternal(begin_timestamp, 50); | 641 *rtt = GetRTTEstimateInternal(begin_timestamp, 50); |
| 589 return (*rtt != InvalidRTT()); | 642 return (*rtt != InvalidRTT()); |
| 590 } | 643 } |
| 591 | 644 |
| 592 bool NetworkQualityEstimator::GetRecentMedianDownlinkThroughputKbps( | 645 bool NetworkQualityEstimator::GetRecentMedianDownlinkThroughputKbps( |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 637 return kInvalidThroughput; | 690 return kInvalidThroughput; |
| 638 | 691 |
| 639 // Throughput observations are sorted by kbps from slowest to fastest, | 692 // Throughput observations are sorted by kbps from slowest to fastest, |
| 640 // thus a higher percentile throughput will be faster than a lower one. | 693 // thus a higher percentile throughput will be faster than a lower one. |
| 641 int32_t kbps = kInvalidThroughput; | 694 int32_t kbps = kInvalidThroughput; |
| 642 downstream_throughput_kbps_observations_.GetPercentile(begin_timestamp, &kbps, | 695 downstream_throughput_kbps_observations_.GetPercentile(begin_timestamp, &kbps, |
| 643 100 - percentile); | 696 100 - percentile); |
| 644 return kbps; | 697 return kbps; |
| 645 } | 698 } |
| 646 | 699 |
| 700 float NetworkQualityEstimator::GetPacketLossRateEstimateInternal( |
| 701 const base::TimeTicks& begin_timestamp) const { |
| 702 DCHECK(thread_checker_.CalledOnValidThread()); |
| 703 |
| 704 if (packet_loss_rate_observations_.Size() == 0) |
| 705 return -1.0f; |
| 706 |
| 707 float packet_loss_rate; |
| 708 if (!packet_loss_rate_observations_.GetWeightedAverage(begin_timestamp, |
| 709 &packet_loss_rate)) { |
| 710 return -1.0f; |
| 711 } |
| 712 DCHECK_LE(0.0f, packet_loss_rate); |
| 713 DCHECK_GE(1.0f, packet_loss_rate); |
| 714 return packet_loss_rate; |
| 715 } |
| 716 |
| 647 template <typename ValueType> | 717 template <typename ValueType> |
| 648 void NetworkQualityEstimator::ObservationBuffer<ValueType>:: | 718 void NetworkQualityEstimator::ObservationBuffer<ValueType>:: |
| 649 ComputeWeightedObservations( | 719 ComputeWeightedObservations( |
| 650 const base::TimeTicks& begin_timestamp, | 720 const base::TimeTicks& begin_timestamp, |
| 651 std::vector<WeightedObservation<ValueType>>& weighted_observations, | 721 std::vector<WeightedObservation<ValueType>>& weighted_observations, |
| 652 double* total_weight) const { | 722 double* total_weight) const { |
| 653 weighted_observations.clear(); | 723 weighted_observations.clear(); |
| 654 double total_weight_observations = 0.0; | 724 double total_weight_observations = 0.0; |
| 655 base::TimeTicks now = base::TimeTicks::Now(); | 725 base::TimeTicks now = base::TimeTicks::Now(); |
| 656 | 726 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 | 780 |
| 711 // Computation may reach here due to floating point errors. This may happen | 781 // Computation may reach here due to floating point errors. This may happen |
| 712 // if |percentile| was 100 (or close to 100), and |desired_weight| was | 782 // if |percentile| was 100 (or close to 100), and |desired_weight| was |
| 713 // slightly larger than |total_weight| (due to floating point errors). | 783 // slightly larger than |total_weight| (due to floating point errors). |
| 714 // In this case, we return the highest |value| among all observations. | 784 // In this case, we return the highest |value| among all observations. |
| 715 // This is same as value of the last observation in the sorted vector. | 785 // This is same as value of the last observation in the sorted vector. |
| 716 *result = weighted_observations.at(weighted_observations.size() - 1).value; | 786 *result = weighted_observations.at(weighted_observations.size() - 1).value; |
| 717 return true; | 787 return true; |
| 718 } | 788 } |
| 719 | 789 |
| 790 template <typename ValueType> |
| 791 bool NetworkQualityEstimator::ObservationBuffer<ValueType>::GetWeightedAverage( |
| 792 const base::TimeTicks& begin_timestamp, |
| 793 ValueType* result) const { |
| 794 DCHECK(result); |
| 795 |
| 796 // Stores |weighted_observations| in the increasing order of value with lower |
| 797 // values at the front of the vector. |
| 798 std::vector<WeightedObservation<ValueType>> weighted_observations; |
| 799 |
| 800 // The sum of the weights of all observations in |weighted_observations|. |
| 801 double total_weight = 0.0; |
| 802 |
| 803 ComputeWeightedObservations(begin_timestamp, weighted_observations, |
| 804 &total_weight); |
| 805 if (weighted_observations.empty()) |
| 806 return false; |
| 807 |
| 808 DCHECK_GT(total_weight, 0.0); |
| 809 |
| 810 // |weighted_observations| may have a smaller size than |observations_| since |
| 811 // the former only contains the observations later than |begin_timestamp|. |
| 812 DCHECK_GE(observations_.size(), weighted_observations.size()); |
| 813 |
| 814 double total_weight_times_value = 0.0; |
| 815 for (const auto& weighted_observation : weighted_observations) { |
| 816 total_weight_times_value += |
| 817 (weighted_observation.weight * weighted_observation.value); |
| 818 } |
| 819 *result = total_weight_times_value / total_weight; |
| 820 return true; |
| 821 } |
| 822 |
| 720 NetworkQualityEstimator::NetworkID | 823 NetworkQualityEstimator::NetworkID |
| 721 NetworkQualityEstimator::GetCurrentNetworkID() const { | 824 NetworkQualityEstimator::GetCurrentNetworkID() const { |
| 722 DCHECK(thread_checker_.CalledOnValidThread()); | 825 DCHECK(thread_checker_.CalledOnValidThread()); |
| 723 | 826 |
| 724 // TODO(tbansal): crbug.com/498068 Add NetworkQualityEstimatorAndroid class | 827 // TODO(tbansal): crbug.com/498068 Add NetworkQualityEstimatorAndroid class |
| 725 // that overrides this method on the Android platform. | 828 // that overrides this method on the Android platform. |
| 726 | 829 |
| 727 // It is possible that the connection type changed between when | 830 // It is possible that the connection type changed between when |
| 728 // GetConnectionType() was called and when the API to determine the | 831 // GetConnectionType() was called and when the API to determine the |
| 729 // network name was called. Check if that happened and retry until the | 832 // network name was called. Check if that happened and retry until the |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 893 | 996 |
| 894 return scoped_ptr<SocketPerformanceWatcher>( | 997 return scoped_ptr<SocketPerformanceWatcher>( |
| 895 new SocketPerformanceWatcher(protocol, this)); | 998 new SocketPerformanceWatcher(protocol, this)); |
| 896 } | 999 } |
| 897 | 1000 |
| 898 void NetworkQualityEstimator::OnUpdatedRTTAvailable( | 1001 void NetworkQualityEstimator::OnUpdatedRTTAvailable( |
| 899 const Protocol protocol, | 1002 const Protocol protocol, |
| 900 const base::TimeDelta& rtt) { | 1003 const base::TimeDelta& rtt) { |
| 901 DCHECK(thread_checker_.CalledOnValidThread()); | 1004 DCHECK(thread_checker_.CalledOnValidThread()); |
| 902 | 1005 |
| 903 switch (protocol) { | 1006 ObservationSource observation_source; |
| 904 case PROTOCOL_TCP: | 1007 if (!GetObservationSourceForProtocol(protocol, &observation_source)) |
| 905 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), TCP)); | 1008 return; |
| 906 return; | 1009 |
| 907 case PROTOCOL_QUIC: | 1010 NotifyObserversOfRTT( |
| 908 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), QUIC)); | 1011 RttObservation(rtt, base::TimeTicks::Now(), observation_source)); |
| 909 return; | 1012 } |
| 910 default: | 1013 |
| 911 NOTREACHED(); | 1014 void NetworkQualityEstimator::OnUpdatedPacketCountAvailable( |
| 1015 Protocol protocol, |
| 1016 size_t packets_lost, |
| 1017 size_t packets_received_in_order, |
| 1018 size_t packets_received_out_of_order) { |
| 1019 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1020 |
| 1021 const base::TimeTicks now = base::TimeTicks::Now(); |
| 1022 |
| 1023 ObservationSource observation_source; |
| 1024 if (!GetObservationSourceForProtocol(protocol, &observation_source)) |
| 1025 return; |
| 1026 |
| 1027 for (size_t i = 0; i < packets_lost; ++i) { |
| 1028 packet_loss_rate_observations_.AddObservation( |
| 1029 PacketLossRateObservation(1.0, now, observation_source)); |
| 912 } | 1030 } |
| 1031 for (size_t i = 0; i < packets_received_in_order; ++i) { |
| 1032 packet_loss_rate_observations_.AddObservation( |
| 1033 PacketLossRateObservation(0.0, now, observation_source)); |
| 1034 } |
| 1035 // For packet loss estimation, we neglect the packets that were previously |
| 1036 // marked as lost but are later received out-of-order. |
| 1037 NotifyObserversOfPacketLoss(packets_lost, packets_received_in_order, |
| 1038 packets_received_out_of_order, now, |
| 1039 observation_source); |
| 913 } | 1040 } |
| 914 | 1041 |
| 915 void NetworkQualityEstimator::NotifyObserversOfRTT( | 1042 void NetworkQualityEstimator::NotifyObserversOfRTT( |
| 916 const RttObservation& observation) { | 1043 const RttObservation& observation) { |
| 1044 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1045 DCHECK_NE(EXTERNAL_ESTIMATE, observation.source); |
| 1046 |
| 917 FOR_EACH_OBSERVER( | 1047 FOR_EACH_OBSERVER( |
| 918 RTTObserver, rtt_observer_list_, | 1048 RTTObserver, rtt_observer_list_, |
| 919 OnRTTObservation(observation.value.InMilliseconds(), | 1049 OnRTTObservation(observation.value.InMilliseconds(), |
| 920 observation.timestamp, observation.source)); | 1050 observation.timestamp, observation.source)); |
| 921 } | 1051 } |
| 922 | 1052 |
| 923 void NetworkQualityEstimator::NotifyObserversOfThroughput( | 1053 void NetworkQualityEstimator::NotifyObserversOfThroughput( |
| 924 const ThroughputObservation& observation) { | 1054 const ThroughputObservation& observation) { |
| 1055 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1056 DCHECK_NE(EXTERNAL_ESTIMATE, observation.source); |
| 1057 |
| 925 FOR_EACH_OBSERVER( | 1058 FOR_EACH_OBSERVER( |
| 926 ThroughputObserver, throughput_observer_list_, | 1059 ThroughputObserver, throughput_observer_list_, |
| 927 OnThroughputObservation(observation.value, observation.timestamp, | 1060 OnThroughputObservation(observation.value, observation.timestamp, |
| 928 observation.source)); | 1061 observation.source)); |
| 929 } | 1062 } |
| 930 | 1063 |
| 1064 void NetworkQualityEstimator::NotifyObserversOfPacketLoss( |
| 1065 size_t packets_lost, |
| 1066 size_t packets_received_in_order, |
| 1067 size_t packets_received_out_of_order, |
| 1068 const base::TimeTicks& timestamp, |
| 1069 ObservationSource source) { |
| 1070 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1071 DCHECK_NE(EXTERNAL_ESTIMATE, source); |
| 1072 |
| 1073 FOR_EACH_OBSERVER(PacketLossObserver, packet_loss_observer_list_, |
| 1074 OnPacketLossObservation( |
| 1075 packets_lost, packets_received_in_order, |
| 1076 packets_received_out_of_order, timestamp, source)); |
| 1077 } |
| 1078 |
| 931 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( | 1079 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( |
| 932 const NetworkQuality& network_quality) | 1080 const NetworkQuality& network_quality) |
| 933 : last_update_time_(base::TimeTicks::Now()), | 1081 : last_update_time_(base::TimeTicks::Now()), |
| 934 network_quality_(network_quality) { | 1082 network_quality_(network_quality) { |
| 935 } | 1083 } |
| 936 | 1084 |
| 937 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( | 1085 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( |
| 938 const CachedNetworkQuality& other) | 1086 const CachedNetworkQuality& other) |
| 939 : last_update_time_(other.last_update_time_), | 1087 : last_update_time_(other.last_update_time_), |
| 940 network_quality_(other.network_quality_) { | 1088 network_quality_(other.network_quality_) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 968 | 1116 |
| 969 NetworkQualityEstimator::NetworkQuality& | 1117 NetworkQualityEstimator::NetworkQuality& |
| 970 NetworkQualityEstimator::NetworkQuality:: | 1118 NetworkQualityEstimator::NetworkQuality:: |
| 971 operator=(const NetworkQuality& other) { | 1119 operator=(const NetworkQuality& other) { |
| 972 rtt_ = other.rtt_; | 1120 rtt_ = other.rtt_; |
| 973 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; | 1121 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; |
| 974 return *this; | 1122 return *this; |
| 975 } | 1123 } |
| 976 | 1124 |
| 977 } // namespace net | 1125 } // namespace net |
| OLD | NEW |