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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 prefix + statistic_name + GetNameForConnectionType(type), kLowerLimit, | 112 prefix + statistic_name + GetNameForConnectionType(type), kLowerLimit, |
113 max_limit, kBucketCount, base::HistogramBase::kUmaTargetedHistogramFlag); | 113 max_limit, kBucketCount, base::HistogramBase::kUmaTargetedHistogramFlag); |
114 } | 114 } |
115 | 115 |
116 } // namespace | 116 } // namespace |
117 | 117 |
118 namespace net { | 118 namespace net { |
119 | 119 |
120 const int32_t NetworkQualityEstimator::kInvalidThroughput = 0; | 120 const int32_t NetworkQualityEstimator::kInvalidThroughput = 0; |
121 | 121 |
122 const float NetworkQualityEstimator::kInvalidPacketLossRate = -1; | |
bengr
2016/02/09 15:41:02
-1.0f?
tbansal1
2016/02/09 17:54:11
Done.
| |
123 | |
122 NetworkQualityEstimator::NetworkQualityEstimator( | 124 NetworkQualityEstimator::NetworkQualityEstimator( |
123 scoped_ptr<ExternalEstimateProvider> external_estimates_provider, | 125 scoped_ptr<ExternalEstimateProvider> external_estimates_provider, |
124 const std::map<std::string, std::string>& variation_params) | 126 const std::map<std::string, std::string>& variation_params) |
125 : NetworkQualityEstimator(std::move(external_estimates_provider), | 127 : NetworkQualityEstimator(std::move(external_estimates_provider), |
126 variation_params, | 128 variation_params, |
127 false, | 129 false, |
128 false) {} | 130 false) {} |
129 | 131 |
130 NetworkQualityEstimator::NetworkQualityEstimator( | 132 NetworkQualityEstimator::NetworkQualityEstimator( |
131 scoped_ptr<ExternalEstimateProvider> external_estimates_provider, | 133 scoped_ptr<ExternalEstimateProvider> external_estimates_provider, |
132 const std::map<std::string, std::string>& variation_params, | 134 const std::map<std::string, std::string>& variation_params, |
133 bool allow_local_host_requests_for_tests, | 135 bool allow_local_host_requests_for_tests, |
134 bool allow_smaller_responses_for_tests) | 136 bool allow_smaller_responses_for_tests) |
135 : allow_localhost_requests_(allow_local_host_requests_for_tests), | 137 : allow_localhost_requests_(allow_local_host_requests_for_tests), |
136 allow_small_responses_(allow_smaller_responses_for_tests), | 138 allow_small_responses_(allow_smaller_responses_for_tests), |
137 last_connection_change_(base::TimeTicks::Now()), | 139 last_connection_change_(base::TimeTicks::Now()), |
138 current_network_id_( | 140 current_network_id_( |
139 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, | 141 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, |
140 std::string())), | 142 std::string())), |
141 downstream_throughput_kbps_observations_( | 143 downstream_throughput_kbps_observations_( |
142 GetWeightMultiplierPerSecond(variation_params)), | 144 GetWeightMultiplierPerSecond(variation_params)), |
143 rtt_msec_observations_(GetWeightMultiplierPerSecond(variation_params)), | 145 rtt_msec_observations_(GetWeightMultiplierPerSecond(variation_params)), |
146 packet_loss_rate_observations_( | |
147 GetWeightMultiplierPerSecond(variation_params)), | |
144 external_estimate_provider_(std::move(external_estimates_provider)) { | 148 external_estimate_provider_(std::move(external_estimates_provider)) { |
145 static_assert(kMinRequestDurationMicroseconds > 0, | 149 static_assert(kMinRequestDurationMicroseconds > 0, |
146 "Minimum request duration must be > 0"); | 150 "Minimum request duration must be > 0"); |
147 static_assert(kDefaultHalfLifeSeconds > 0, | 151 static_assert(kDefaultHalfLifeSeconds > 0, |
148 "Default half life duration must be > 0"); | 152 "Default half life duration must be > 0"); |
149 static_assert(kMaximumNetworkQualityCacheSize > 0, | 153 static_assert(kMaximumNetworkQualityCacheSize > 0, |
150 "Size of the network quality cache must be > 0"); | 154 "Size of the network quality cache must be > 0"); |
151 // This limit should not be increased unless the logic for removing the | 155 // 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. | 156 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. |
153 static_assert(kMaximumNetworkQualityCacheSize <= 10, | 157 static_assert(kMaximumNetworkQualityCacheSize <= 10, |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
369 DCHECK(thread_checker_.CalledOnValidThread()); | 373 DCHECK(thread_checker_.CalledOnValidThread()); |
370 throughput_observer_list_.AddObserver(throughput_observer); | 374 throughput_observer_list_.AddObserver(throughput_observer); |
371 } | 375 } |
372 | 376 |
373 void NetworkQualityEstimator::RemoveThroughputObserver( | 377 void NetworkQualityEstimator::RemoveThroughputObserver( |
374 ThroughputObserver* throughput_observer) { | 378 ThroughputObserver* throughput_observer) { |
375 DCHECK(thread_checker_.CalledOnValidThread()); | 379 DCHECK(thread_checker_.CalledOnValidThread()); |
376 throughput_observer_list_.RemoveObserver(throughput_observer); | 380 throughput_observer_list_.RemoveObserver(throughput_observer); |
377 } | 381 } |
378 | 382 |
383 void NetworkQualityEstimator::AddPacketLossObserver( | |
384 PacketLossObserver* packet_loss_observer) { | |
385 DCHECK(thread_checker_.CalledOnValidThread()); | |
386 packet_loss_observer_list_.AddObserver(packet_loss_observer); | |
387 } | |
388 | |
389 void NetworkQualityEstimator::RemovePacketLossObserver( | |
390 PacketLossObserver* packet_loss_observer) { | |
391 DCHECK(thread_checker_.CalledOnValidThread()); | |
392 packet_loss_observer_list_.RemoveObserver(packet_loss_observer); | |
393 } | |
394 | |
379 void NetworkQualityEstimator::RecordRTTUMA(int32_t estimated_value_msec, | 395 void NetworkQualityEstimator::RecordRTTUMA(int32_t estimated_value_msec, |
380 int32_t actual_value_msec) const { | 396 int32_t actual_value_msec) const { |
381 DCHECK(thread_checker_.CalledOnValidThread()); | 397 DCHECK(thread_checker_.CalledOnValidThread()); |
382 | 398 |
383 // Record the difference between the actual and the estimated value. | 399 // Record the difference between the actual and the estimated value. |
384 if (estimated_value_msec >= actual_value_msec) { | 400 if (estimated_value_msec >= actual_value_msec) { |
385 base::HistogramBase* difference_rtt = | 401 base::HistogramBase* difference_rtt = |
386 GetHistogram("DifferenceRTTEstimatedAndActual.", | 402 GetHistogram("DifferenceRTTEstimatedAndActual.", |
387 current_network_id_.type, 10 * 1000); // 10 seconds | 403 current_network_id_.type, 10 * 1000); // 10 seconds |
388 difference_rtt->Add(estimated_value_msec - actual_value_msec); | 404 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() && | 438 !request.was_cached() && |
423 request.creation_time() >= last_connection_change_; | 439 request.creation_time() >= last_connection_change_; |
424 } | 440 } |
425 | 441 |
426 void NetworkQualityEstimator::RecordExternalEstimateProviderMetrics( | 442 void NetworkQualityEstimator::RecordExternalEstimateProviderMetrics( |
427 NQEExternalEstimateProviderStatus status) const { | 443 NQEExternalEstimateProviderStatus status) const { |
428 UMA_HISTOGRAM_ENUMERATION("NQE.ExternalEstimateProviderStatus", status, | 444 UMA_HISTOGRAM_ENUMERATION("NQE.ExternalEstimateProviderStatus", status, |
429 EXTERNAL_ESTIMATE_PROVIDER_STATUS_BOUNDARY); | 445 EXTERNAL_ESTIMATE_PROVIDER_STATUS_BOUNDARY); |
430 } | 446 } |
431 | 447 |
448 NetworkQualityEstimator::ObservationSource | |
449 NetworkQualityEstimator::GetObservationSourceForProtocol( | |
450 const Protocol protocol) const { | |
451 switch (protocol) { | |
452 case PROTOCOL_TCP: | |
453 return TCP; | |
454 case PROTOCOL_QUIC: | |
455 return QUIC; | |
456 default: | |
457 NOTREACHED(); | |
458 return UNKNOWN; | |
459 } | |
460 } | |
461 | |
432 void NetworkQualityEstimator::OnConnectionTypeChanged( | 462 void NetworkQualityEstimator::OnConnectionTypeChanged( |
433 NetworkChangeNotifier::ConnectionType type) { | 463 NetworkChangeNotifier::ConnectionType type) { |
434 DCHECK(thread_checker_.CalledOnValidThread()); | 464 DCHECK(thread_checker_.CalledOnValidThread()); |
465 | |
435 if (peak_network_quality_.rtt() != InvalidRTT()) { | 466 if (peak_network_quality_.rtt() != InvalidRTT()) { |
436 switch (current_network_id_.type) { | 467 // Largest bucket is 10 seconds. |
437 case NetworkChangeNotifier::CONNECTION_UNKNOWN: | 468 base::HistogramBase* fastest_rtt_histogram = |
438 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Unknown", | 469 GetHistogram("FastestRTT.", current_network_id_.type, 10 * 1000); |
439 peak_network_quality_.rtt()); | 470 fastest_rtt_histogram->Add(peak_network_quality_.rtt().InMilliseconds()); |
440 break; | |
441 case NetworkChangeNotifier::CONNECTION_ETHERNET: | |
442 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Ethernet", | |
443 peak_network_quality_.rtt()); | |
444 break; | |
445 case NetworkChangeNotifier::CONNECTION_WIFI: | |
446 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Wifi", peak_network_quality_.rtt()); | |
447 break; | |
448 case NetworkChangeNotifier::CONNECTION_2G: | |
449 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.2G", peak_network_quality_.rtt()); | |
450 break; | |
451 case NetworkChangeNotifier::CONNECTION_3G: | |
452 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.3G", peak_network_quality_.rtt()); | |
453 break; | |
454 case NetworkChangeNotifier::CONNECTION_4G: | |
455 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.4G", peak_network_quality_.rtt()); | |
456 break; | |
457 case NetworkChangeNotifier::CONNECTION_NONE: | |
458 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.None", peak_network_quality_.rtt()); | |
459 break; | |
460 case NetworkChangeNotifier::CONNECTION_BLUETOOTH: | |
461 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Bluetooth", | |
462 peak_network_quality_.rtt()); | |
463 break; | |
464 default: | |
465 NOTREACHED() << "Unexpected connection type = " | |
466 << current_network_id_.type; | |
467 break; | |
468 } | |
469 } | 471 } |
470 | 472 |
471 if (peak_network_quality_.downstream_throughput_kbps() != | 473 if (peak_network_quality_.downstream_throughput_kbps() != |
472 kInvalidThroughput) { | 474 kInvalidThroughput) { |
473 switch (current_network_id_.type) { | 475 // Largest bucket is 1000000 Kbps (~1 Gbps). |
474 case NetworkChangeNotifier::CONNECTION_UNKNOWN: | 476 base::HistogramBase* peak_kbps_histogram = |
475 UMA_HISTOGRAM_COUNTS( | 477 GetHistogram("PeakKbps.", current_network_id_.type, |
476 "NQE.PeakKbps.Unknown", | 478 1000000); // UMA_HISTOGRAM_COUNTS |
477 peak_network_quality_.downstream_throughput_kbps()); | 479 peak_kbps_histogram->Add( |
478 break; | 480 peak_network_quality_.downstream_throughput_kbps()); |
479 case NetworkChangeNotifier::CONNECTION_ETHERNET: | 481 } |
480 UMA_HISTOGRAM_COUNTS( | 482 |
481 "NQE.PeakKbps.Ethernet", | 483 float packet_loss_rate = kInvalidPacketLossRate; |
482 peak_network_quality_.downstream_throughput_kbps()); | 484 if (GetPacketLossRateEstimate(&packet_loss_rate)) { |
483 break; | 485 DCHECK_NE(kInvalidPacketLossRate, packet_loss_rate); |
484 case NetworkChangeNotifier::CONNECTION_WIFI: | 486 |
485 UMA_HISTOGRAM_COUNTS( | 487 // Largest bucket is 101. |
486 "NQE.PeakKbps.Wifi", | 488 base::HistogramBase* packet_loss_histogram = |
487 peak_network_quality_.downstream_throughput_kbps()); | 489 GetHistogram("PacketLossRate.", current_network_id_.type, 101); |
488 break; | 490 packet_loss_histogram->Add(packet_loss_rate * 100); |
489 case NetworkChangeNotifier::CONNECTION_2G: | |
490 UMA_HISTOGRAM_COUNTS( | |
491 "NQE.PeakKbps.2G", | |
492 peak_network_quality_.downstream_throughput_kbps()); | |
493 break; | |
494 case NetworkChangeNotifier::CONNECTION_3G: | |
495 UMA_HISTOGRAM_COUNTS( | |
496 "NQE.PeakKbps.3G", | |
497 peak_network_quality_.downstream_throughput_kbps()); | |
498 break; | |
499 case NetworkChangeNotifier::CONNECTION_4G: | |
500 UMA_HISTOGRAM_COUNTS( | |
501 "NQE.PeakKbps.4G", | |
502 peak_network_quality_.downstream_throughput_kbps()); | |
503 break; | |
504 case NetworkChangeNotifier::CONNECTION_NONE: | |
505 UMA_HISTOGRAM_COUNTS( | |
506 "NQE.PeakKbps.None", | |
507 peak_network_quality_.downstream_throughput_kbps()); | |
508 break; | |
509 case NetworkChangeNotifier::CONNECTION_BLUETOOTH: | |
510 UMA_HISTOGRAM_COUNTS( | |
511 "NQE.PeakKbps.Bluetooth", | |
512 peak_network_quality_.downstream_throughput_kbps()); | |
513 break; | |
514 default: | |
515 NOTREACHED() << "Unexpected connection type = " | |
516 << current_network_id_.type; | |
517 break; | |
518 } | |
519 } | 491 } |
520 | 492 |
521 base::TimeDelta rtt = GetRTTEstimateInternal(base::TimeTicks(), 50); | 493 base::TimeDelta rtt = GetRTTEstimateInternal(base::TimeTicks(), 50); |
522 if (rtt != InvalidRTT()) { | 494 if (rtt != InvalidRTT()) { |
523 // Add the 50th percentile value. | 495 // Add the 50th percentile value. |
524 base::HistogramBase* rtt_percentile = | 496 base::HistogramBase* rtt_percentile = |
525 GetHistogram("RTT.Percentile50.", current_network_id_.type, | 497 GetHistogram("RTT.Percentile50.", current_network_id_.type, |
526 10 * 1000); // 10 seconds | 498 10 * 1000); // 10 seconds |
527 rtt_percentile->Add(rtt.InMilliseconds()); | 499 rtt_percentile->Add(rtt.InMilliseconds()); |
528 | 500 |
(...skipping 10 matching lines...) Expand all Loading... | |
539 } | 511 } |
540 | 512 |
541 // Write the estimates of the previous network to the cache. | 513 // Write the estimates of the previous network to the cache. |
542 CacheNetworkQualityEstimate(); | 514 CacheNetworkQualityEstimate(); |
543 | 515 |
544 // Clear the local state. | 516 // Clear the local state. |
545 last_connection_change_ = base::TimeTicks::Now(); | 517 last_connection_change_ = base::TimeTicks::Now(); |
546 peak_network_quality_ = NetworkQuality(); | 518 peak_network_quality_ = NetworkQuality(); |
547 downstream_throughput_kbps_observations_.Clear(); | 519 downstream_throughput_kbps_observations_.Clear(); |
548 rtt_msec_observations_.Clear(); | 520 rtt_msec_observations_.Clear(); |
521 packet_loss_rate_observations_.Clear(); | |
549 current_network_id_ = GetCurrentNetworkID(); | 522 current_network_id_ = GetCurrentNetworkID(); |
550 | 523 |
551 QueryExternalEstimateProvider(); | 524 QueryExternalEstimateProvider(); |
552 | 525 |
553 // Read any cached estimates for the new network. If cached estimates are | 526 // Read any cached estimates for the new network. If cached estimates are |
554 // unavailable, add the default estimates. | 527 // unavailable, add the default estimates. |
555 if (!ReadCachedNetworkQualityEstimate()) | 528 if (!ReadCachedNetworkQualityEstimate()) |
556 AddDefaultEstimates(); | 529 AddDefaultEstimates(); |
557 estimated_median_network_quality_ = NetworkQuality(); | 530 estimated_median_network_quality_ = NetworkQuality(); |
558 } | 531 } |
(...skipping 14 matching lines...) Expand all Loading... | |
573 DCHECK(thread_checker_.CalledOnValidThread()); | 546 DCHECK(thread_checker_.CalledOnValidThread()); |
574 DCHECK(kbps); | 547 DCHECK(kbps); |
575 if (downstream_throughput_kbps_observations_.Size() == 0) { | 548 if (downstream_throughput_kbps_observations_.Size() == 0) { |
576 *kbps = kInvalidThroughput; | 549 *kbps = kInvalidThroughput; |
577 return false; | 550 return false; |
578 } | 551 } |
579 *kbps = GetDownlinkThroughputKbpsEstimateInternal(base::TimeTicks(), 50); | 552 *kbps = GetDownlinkThroughputKbpsEstimateInternal(base::TimeTicks(), 50); |
580 return (*kbps != kInvalidThroughput); | 553 return (*kbps != kInvalidThroughput); |
581 } | 554 } |
582 | 555 |
556 bool NetworkQualityEstimator::GetPacketLossRateEstimate( | |
557 float* packet_loss) const { | |
558 DCHECK(thread_checker_.CalledOnValidThread()); | |
559 | |
560 *packet_loss = GetPacketLossRateEstimateInternal(base::TimeTicks()); | |
561 return (*packet_loss != kInvalidPacketLossRate); | |
562 } | |
563 | |
583 bool NetworkQualityEstimator::GetRecentMedianRTT( | 564 bool NetworkQualityEstimator::GetRecentMedianRTT( |
584 const base::TimeTicks& begin_timestamp, | 565 const base::TimeTicks& begin_timestamp, |
585 base::TimeDelta* rtt) const { | 566 base::TimeDelta* rtt) const { |
586 DCHECK(thread_checker_.CalledOnValidThread()); | 567 DCHECK(thread_checker_.CalledOnValidThread()); |
587 DCHECK(rtt); | 568 DCHECK(rtt); |
588 *rtt = GetRTTEstimateInternal(begin_timestamp, 50); | 569 *rtt = GetRTTEstimateInternal(begin_timestamp, 50); |
589 return (*rtt != InvalidRTT()); | 570 return (*rtt != InvalidRTT()); |
590 } | 571 } |
591 | 572 |
592 bool NetworkQualityEstimator::GetRecentMedianDownlinkThroughputKbps( | 573 bool NetworkQualityEstimator::GetRecentMedianDownlinkThroughputKbps( |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
637 return kInvalidThroughput; | 618 return kInvalidThroughput; |
638 | 619 |
639 // Throughput observations are sorted by kbps from slowest to fastest, | 620 // Throughput observations are sorted by kbps from slowest to fastest, |
640 // thus a higher percentile throughput will be faster than a lower one. | 621 // thus a higher percentile throughput will be faster than a lower one. |
641 int32_t kbps = kInvalidThroughput; | 622 int32_t kbps = kInvalidThroughput; |
642 downstream_throughput_kbps_observations_.GetPercentile(begin_timestamp, &kbps, | 623 downstream_throughput_kbps_observations_.GetPercentile(begin_timestamp, &kbps, |
643 100 - percentile); | 624 100 - percentile); |
644 return kbps; | 625 return kbps; |
645 } | 626 } |
646 | 627 |
628 float NetworkQualityEstimator::GetPacketLossRateEstimateInternal( | |
629 const base::TimeTicks& begin_timestamp) const { | |
630 DCHECK(thread_checker_.CalledOnValidThread()); | |
631 | |
632 if (packet_loss_rate_observations_.Size() == 0) | |
633 return kInvalidPacketLossRate; | |
634 | |
635 float packet_loss_rate = kInvalidPacketLossRate; | |
636 packet_loss_rate_observations_.GetWeightedAverage(begin_timestamp, | |
637 &packet_loss_rate); | |
638 return packet_loss_rate; | |
639 } | |
640 | |
647 template <typename ValueType> | 641 template <typename ValueType> |
648 void NetworkQualityEstimator::ObservationBuffer<ValueType>:: | 642 void NetworkQualityEstimator::ObservationBuffer<ValueType>:: |
649 ComputeWeightedObservations( | 643 ComputeWeightedObservations( |
650 const base::TimeTicks& begin_timestamp, | 644 const base::TimeTicks& begin_timestamp, |
651 std::vector<WeightedObservation<ValueType>>& weighted_observations, | 645 std::vector<WeightedObservation<ValueType>>& weighted_observations, |
652 double* total_weight) const { | 646 double* total_weight) const { |
653 weighted_observations.clear(); | 647 weighted_observations.clear(); |
654 double total_weight_observations = 0.0; | 648 double total_weight_observations = 0.0; |
655 base::TimeTicks now = base::TimeTicks::Now(); | 649 base::TimeTicks now = base::TimeTicks::Now(); |
656 | 650 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
710 | 704 |
711 // Computation may reach here due to floating point errors. This may happen | 705 // 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 | 706 // if |percentile| was 100 (or close to 100), and |desired_weight| was |
713 // slightly larger than |total_weight| (due to floating point errors). | 707 // slightly larger than |total_weight| (due to floating point errors). |
714 // In this case, we return the highest |value| among all observations. | 708 // 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. | 709 // This is same as value of the last observation in the sorted vector. |
716 *result = weighted_observations.at(weighted_observations.size() - 1).value; | 710 *result = weighted_observations.at(weighted_observations.size() - 1).value; |
717 return true; | 711 return true; |
718 } | 712 } |
719 | 713 |
714 template <typename ValueType> | |
715 bool NetworkQualityEstimator::ObservationBuffer<ValueType>::GetWeightedAverage( | |
716 const base::TimeTicks& begin_timestamp, | |
717 ValueType* result) const { | |
718 DCHECK(result); | |
719 | |
720 // Stores WeightedObservation in increasing order of value, although for the | |
721 // purpose of computing weighted average, the order does not matter. | |
722 std::vector<WeightedObservation<ValueType>> weighted_observations; | |
723 | |
724 // Total weight of all observations in |weighted_observations|. | |
725 double total_weight = 0.0; | |
726 | |
727 ComputeWeightedObservations(begin_timestamp, weighted_observations, | |
728 &total_weight); | |
729 if (weighted_observations.empty()) | |
730 return false; | |
731 | |
732 DCHECK_GT(total_weight, 0.0); | |
733 | |
734 // |weighted_observations| may have a smaller size than |observations_| since | |
735 // the former only contains the observations later than |begin_timestamp|. | |
736 DCHECK_GE(observations_.size(), weighted_observations.size()); | |
737 | |
738 double total_weight_times_value = 0.0; | |
739 for (const auto& weighted_observation : weighted_observations) { | |
740 total_weight_times_value += | |
741 (weighted_observation.weight * weighted_observation.value); | |
742 } | |
743 *result = total_weight_times_value / total_weight; | |
744 return true; | |
745 } | |
746 | |
720 NetworkQualityEstimator::NetworkID | 747 NetworkQualityEstimator::NetworkID |
721 NetworkQualityEstimator::GetCurrentNetworkID() const { | 748 NetworkQualityEstimator::GetCurrentNetworkID() const { |
722 DCHECK(thread_checker_.CalledOnValidThread()); | 749 DCHECK(thread_checker_.CalledOnValidThread()); |
723 | 750 |
724 // TODO(tbansal): crbug.com/498068 Add NetworkQualityEstimatorAndroid class | 751 // TODO(tbansal): crbug.com/498068 Add NetworkQualityEstimatorAndroid class |
725 // that overrides this method on the Android platform. | 752 // that overrides this method on the Android platform. |
726 | 753 |
727 // It is possible that the connection type changed between when | 754 // It is possible that the connection type changed between when |
728 // GetConnectionType() was called and when the API to determine the | 755 // GetConnectionType() was called and when the API to determine the |
729 // network name was called. Check if that happened and retry until the | 756 // 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 | 920 |
894 return scoped_ptr<SocketPerformanceWatcher>( | 921 return scoped_ptr<SocketPerformanceWatcher>( |
895 new SocketPerformanceWatcher(protocol, this)); | 922 new SocketPerformanceWatcher(protocol, this)); |
896 } | 923 } |
897 | 924 |
898 void NetworkQualityEstimator::OnUpdatedRTTAvailable( | 925 void NetworkQualityEstimator::OnUpdatedRTTAvailable( |
899 const Protocol protocol, | 926 const Protocol protocol, |
900 const base::TimeDelta& rtt) { | 927 const base::TimeDelta& rtt) { |
901 DCHECK(thread_checker_.CalledOnValidThread()); | 928 DCHECK(thread_checker_.CalledOnValidThread()); |
902 | 929 |
903 switch (protocol) { | 930 ObservationSource observation_source = |
904 case PROTOCOL_TCP: | 931 GetObservationSourceForProtocol(protocol); |
905 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), TCP)); | 932 NotifyObserversOfRTT( |
906 return; | 933 RttObservation(rtt, base::TimeTicks::Now(), observation_source)); |
907 case PROTOCOL_QUIC: | 934 } |
908 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), QUIC)); | 935 |
909 return; | 936 void NetworkQualityEstimator::OnUpdatedPacketCountAvailable( |
910 default: | 937 const Protocol protocol, |
911 NOTREACHED(); | 938 uint64_t num_packets_lost, |
939 uint64_t num_packets_received_in_order, | |
940 uint64_t num_packets_received_not_in_order) { | |
941 DCHECK(thread_checker_.CalledOnValidThread()); | |
942 | |
943 const base::TimeTicks now = base::TimeTicks::Now(); | |
944 ObservationSource observation_source = | |
945 GetObservationSourceForProtocol(protocol); | |
946 | |
947 for (size_t i = 0; i < num_packets_lost; ++i) { | |
948 packet_loss_rate_observations_.AddObservation( | |
949 PacketLossObservation(1.0, now, observation_source)); | |
912 } | 950 } |
951 for (size_t i = 0; i < num_packets_received_in_order; ++i) { | |
952 packet_loss_rate_observations_.AddObservation( | |
953 PacketLossObservation(0.0, now, observation_source)); | |
954 } | |
955 // For packet loss estimation, we neglect the packets that were previously | |
956 // marked as lost but are later received out-of-order. | |
957 NotifyObserversOfPacketLoss(num_packets_lost, num_packets_received_in_order, | |
958 num_packets_received_not_in_order, now, | |
959 observation_source); | |
913 } | 960 } |
914 | 961 |
915 void NetworkQualityEstimator::NotifyObserversOfRTT( | 962 void NetworkQualityEstimator::NotifyObserversOfRTT( |
916 const RttObservation& observation) { | 963 const RttObservation& observation) { |
964 DCHECK(thread_checker_.CalledOnValidThread()); | |
965 DCHECK_NE(EXTERNAL_ESTIMATE, observation.source); | |
966 | |
917 FOR_EACH_OBSERVER( | 967 FOR_EACH_OBSERVER( |
918 RTTObserver, rtt_observer_list_, | 968 RTTObserver, rtt_observer_list_, |
919 OnRTTObservation(observation.value.InMilliseconds(), | 969 OnRTTObservation(observation.value.InMilliseconds(), |
920 observation.timestamp, observation.source)); | 970 observation.timestamp, observation.source)); |
921 } | 971 } |
922 | 972 |
923 void NetworkQualityEstimator::NotifyObserversOfThroughput( | 973 void NetworkQualityEstimator::NotifyObserversOfThroughput( |
924 const ThroughputObservation& observation) { | 974 const ThroughputObservation& observation) { |
975 DCHECK(thread_checker_.CalledOnValidThread()); | |
976 DCHECK_NE(EXTERNAL_ESTIMATE, observation.source); | |
977 | |
925 FOR_EACH_OBSERVER( | 978 FOR_EACH_OBSERVER( |
926 ThroughputObserver, throughput_observer_list_, | 979 ThroughputObserver, throughput_observer_list_, |
927 OnThroughputObservation(observation.value, observation.timestamp, | 980 OnThroughputObservation(observation.value, observation.timestamp, |
928 observation.source)); | 981 observation.source)); |
929 } | 982 } |
930 | 983 |
984 void NetworkQualityEstimator::NotifyObserversOfPacketLoss( | |
985 uint64_t num_packets_lost, | |
986 uint64_t num_packets_received_in_order, | |
987 uint64_t num_packets_received_not_in_order, | |
988 const base::TimeTicks timestamp, | |
989 ObservationSource source) { | |
990 DCHECK(thread_checker_.CalledOnValidThread()); | |
991 DCHECK_NE(EXTERNAL_ESTIMATE, source); | |
992 | |
993 FOR_EACH_OBSERVER(PacketLossObserver, packet_loss_observer_list_, | |
994 OnPacketLossObservation( | |
995 num_packets_lost, num_packets_received_in_order, | |
996 num_packets_received_not_in_order, timestamp, source)); | |
997 } | |
998 | |
931 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( | 999 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( |
932 const NetworkQuality& network_quality) | 1000 const NetworkQuality& network_quality) |
933 : last_update_time_(base::TimeTicks::Now()), | 1001 : last_update_time_(base::TimeTicks::Now()), |
934 network_quality_(network_quality) { | 1002 network_quality_(network_quality) { |
935 } | 1003 } |
936 | 1004 |
937 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( | 1005 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( |
938 const CachedNetworkQuality& other) | 1006 const CachedNetworkQuality& other) |
939 : last_update_time_(other.last_update_time_), | 1007 : last_update_time_(other.last_update_time_), |
940 network_quality_(other.network_quality_) { | 1008 network_quality_(other.network_quality_) { |
(...skipping 27 matching lines...) Expand all Loading... | |
968 | 1036 |
969 NetworkQualityEstimator::NetworkQuality& | 1037 NetworkQualityEstimator::NetworkQuality& |
970 NetworkQualityEstimator::NetworkQuality:: | 1038 NetworkQualityEstimator::NetworkQuality:: |
971 operator=(const NetworkQuality& other) { | 1039 operator=(const NetworkQuality& other) { |
972 rtt_ = other.rtt_; | 1040 rtt_ = other.rtt_; |
973 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; | 1041 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; |
974 return *this; | 1042 return *this; |
975 } | 1043 } |
976 | 1044 |
977 } // namespace net | 1045 } // namespace net |
OLD | NEW |