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 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.0f; | |
| 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 bool NetworkQualityEstimator::GetObservationSourceForProtocol( | |
| 449 const Protocol protocol, | |
| 450 NetworkQualityEstimator::ObservationSource* observation_source) const { | |
| 451 switch (protocol) { | |
| 452 case PROTOCOL_TCP: | |
| 453 *observation_source = TCP; | |
| 454 return true; | |
| 455 case PROTOCOL_QUIC: | |
| 456 *observation_source = QUIC; | |
| 457 return true; | |
| 458 default: | |
| 459 NOTREACHED(); | |
| 460 return false; | |
| 461 } | |
| 462 } | |
| 463 | |
| 432 void NetworkQualityEstimator::OnConnectionTypeChanged( | 464 void NetworkQualityEstimator::OnConnectionTypeChanged( |
| 433 NetworkChangeNotifier::ConnectionType type) { | 465 NetworkChangeNotifier::ConnectionType type) { |
| 434 DCHECK(thread_checker_.CalledOnValidThread()); | 466 DCHECK(thread_checker_.CalledOnValidThread()); |
| 467 | |
| 435 if (peak_network_quality_.rtt() != InvalidRTT()) { | 468 if (peak_network_quality_.rtt() != InvalidRTT()) { |
| 436 switch (current_network_id_.type) { | 469 // Largest bucket is 10 seconds. |
| 437 case NetworkChangeNotifier::CONNECTION_UNKNOWN: | 470 base::HistogramBase* fastest_rtt_histogram = |
| 438 UMA_HISTOGRAM_TIMES("NQE.FastestRTT.Unknown", | 471 GetHistogram("FastestRTT.", current_network_id_.type, 10 * 1000); |
| 439 peak_network_quality_.rtt()); | 472 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 } | 473 } |
| 470 | 474 |
| 471 if (peak_network_quality_.downstream_throughput_kbps() != | 475 if (peak_network_quality_.downstream_throughput_kbps() != |
| 472 kInvalidThroughput) { | 476 kInvalidThroughput) { |
| 473 switch (current_network_id_.type) { | 477 // Largest bucket is 1000000 Kbps (~1 Gbps). |
| 474 case NetworkChangeNotifier::CONNECTION_UNKNOWN: | 478 base::HistogramBase* peak_kbps_histogram = |
| 475 UMA_HISTOGRAM_COUNTS( | 479 GetHistogram("PeakKbps.", current_network_id_.type, |
| 476 "NQE.PeakKbps.Unknown", | 480 1000000); // UMA_HISTOGRAM_COUNTS |
| 477 peak_network_quality_.downstream_throughput_kbps()); | 481 peak_kbps_histogram->Add( |
| 478 break; | 482 peak_network_quality_.downstream_throughput_kbps()); |
| 479 case NetworkChangeNotifier::CONNECTION_ETHERNET: | 483 } |
| 480 UMA_HISTOGRAM_COUNTS( | 484 |
| 481 "NQE.PeakKbps.Ethernet", | 485 float packet_loss_rate = kInvalidPacketLossRate; |
| 482 peak_network_quality_.downstream_throughput_kbps()); | 486 if (GetPacketLossRateEstimate(&packet_loss_rate)) { |
| 483 break; | 487 DCHECK_NE(kInvalidPacketLossRate, packet_loss_rate); |
| 484 case NetworkChangeNotifier::CONNECTION_WIFI: | 488 |
| 485 UMA_HISTOGRAM_COUNTS( | 489 // Largest bucket is 101. |
| 486 "NQE.PeakKbps.Wifi", | 490 base::HistogramBase* packet_loss_histogram = |
| 487 peak_network_quality_.downstream_throughput_kbps()); | 491 GetHistogram("PacketLossRate.", current_network_id_.type, 101); |
| 488 break; | 492 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 } | 493 } |
| 520 | 494 |
| 521 base::TimeDelta rtt = GetRTTEstimateInternal(base::TimeTicks(), 50); | 495 base::TimeDelta rtt = GetRTTEstimateInternal(base::TimeTicks(), 50); |
| 522 if (rtt != InvalidRTT()) { | 496 if (rtt != InvalidRTT()) { |
| 523 // Add the 50th percentile value. | 497 // Add the 50th percentile value. |
| 524 base::HistogramBase* rtt_percentile = | 498 base::HistogramBase* rtt_percentile = |
| 525 GetHistogram("RTT.Percentile50.", current_network_id_.type, | 499 GetHistogram("RTT.Percentile50.", current_network_id_.type, |
| 526 10 * 1000); // 10 seconds | 500 10 * 1000); // 10 seconds |
| 527 rtt_percentile->Add(rtt.InMilliseconds()); | 501 rtt_percentile->Add(rtt.InMilliseconds()); |
| 528 | 502 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 539 } | 513 } |
| 540 | 514 |
| 541 // Write the estimates of the previous network to the cache. | 515 // Write the estimates of the previous network to the cache. |
| 542 CacheNetworkQualityEstimate(); | 516 CacheNetworkQualityEstimate(); |
| 543 | 517 |
| 544 // Clear the local state. | 518 // Clear the local state. |
| 545 last_connection_change_ = base::TimeTicks::Now(); | 519 last_connection_change_ = base::TimeTicks::Now(); |
| 546 peak_network_quality_ = NetworkQuality(); | 520 peak_network_quality_ = NetworkQuality(); |
| 547 downstream_throughput_kbps_observations_.Clear(); | 521 downstream_throughput_kbps_observations_.Clear(); |
| 548 rtt_msec_observations_.Clear(); | 522 rtt_msec_observations_.Clear(); |
| 523 packet_loss_rate_observations_.Clear(); | |
| 549 current_network_id_ = GetCurrentNetworkID(); | 524 current_network_id_ = GetCurrentNetworkID(); |
| 550 | 525 |
| 551 QueryExternalEstimateProvider(); | 526 QueryExternalEstimateProvider(); |
| 552 | 527 |
| 553 // Read any cached estimates for the new network. If cached estimates are | 528 // Read any cached estimates for the new network. If cached estimates are |
| 554 // unavailable, add the default estimates. | 529 // unavailable, add the default estimates. |
| 555 if (!ReadCachedNetworkQualityEstimate()) | 530 if (!ReadCachedNetworkQualityEstimate()) |
| 556 AddDefaultEstimates(); | 531 AddDefaultEstimates(); |
| 557 estimated_median_network_quality_ = NetworkQuality(); | 532 estimated_median_network_quality_ = NetworkQuality(); |
| 558 } | 533 } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 573 DCHECK(thread_checker_.CalledOnValidThread()); | 548 DCHECK(thread_checker_.CalledOnValidThread()); |
| 574 DCHECK(kbps); | 549 DCHECK(kbps); |
| 575 if (downstream_throughput_kbps_observations_.Size() == 0) { | 550 if (downstream_throughput_kbps_observations_.Size() == 0) { |
| 576 *kbps = kInvalidThroughput; | 551 *kbps = kInvalidThroughput; |
| 577 return false; | 552 return false; |
| 578 } | 553 } |
| 579 *kbps = GetDownlinkThroughputKbpsEstimateInternal(base::TimeTicks(), 50); | 554 *kbps = GetDownlinkThroughputKbpsEstimateInternal(base::TimeTicks(), 50); |
| 580 return (*kbps != kInvalidThroughput); | 555 return (*kbps != kInvalidThroughput); |
| 581 } | 556 } |
| 582 | 557 |
| 558 bool NetworkQualityEstimator::GetPacketLossRateEstimate( | |
| 559 float* packet_loss) const { | |
| 560 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 561 | |
| 562 *packet_loss = GetPacketLossRateEstimateInternal(base::TimeTicks()); | |
| 563 return (*packet_loss != kInvalidPacketLossRate); | |
|
bengr
2016/02/16 17:02:01
Is any packet loss rate below 0 valid?
tbansal1
2016/02/17 18:35:10
No.
| |
| 564 } | |
| 565 | |
| 583 bool NetworkQualityEstimator::GetRecentMedianRTT( | 566 bool NetworkQualityEstimator::GetRecentMedianRTT( |
| 584 const base::TimeTicks& begin_timestamp, | 567 const base::TimeTicks& begin_timestamp, |
| 585 base::TimeDelta* rtt) const { | 568 base::TimeDelta* rtt) const { |
| 586 DCHECK(thread_checker_.CalledOnValidThread()); | 569 DCHECK(thread_checker_.CalledOnValidThread()); |
| 587 DCHECK(rtt); | 570 DCHECK(rtt); |
| 588 *rtt = GetRTTEstimateInternal(begin_timestamp, 50); | 571 *rtt = GetRTTEstimateInternal(begin_timestamp, 50); |
| 589 return (*rtt != InvalidRTT()); | 572 return (*rtt != InvalidRTT()); |
| 590 } | 573 } |
| 591 | 574 |
| 592 bool NetworkQualityEstimator::GetRecentMedianDownlinkThroughputKbps( | 575 bool NetworkQualityEstimator::GetRecentMedianDownlinkThroughputKbps( |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 637 return kInvalidThroughput; | 620 return kInvalidThroughput; |
| 638 | 621 |
| 639 // Throughput observations are sorted by kbps from slowest to fastest, | 622 // Throughput observations are sorted by kbps from slowest to fastest, |
| 640 // thus a higher percentile throughput will be faster than a lower one. | 623 // thus a higher percentile throughput will be faster than a lower one. |
| 641 int32_t kbps = kInvalidThroughput; | 624 int32_t kbps = kInvalidThroughput; |
| 642 downstream_throughput_kbps_observations_.GetPercentile(begin_timestamp, &kbps, | 625 downstream_throughput_kbps_observations_.GetPercentile(begin_timestamp, &kbps, |
| 643 100 - percentile); | 626 100 - percentile); |
| 644 return kbps; | 627 return kbps; |
| 645 } | 628 } |
| 646 | 629 |
| 630 float NetworkQualityEstimator::GetPacketLossRateEstimateInternal( | |
| 631 const base::TimeTicks& begin_timestamp) const { | |
| 632 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 633 | |
| 634 if (packet_loss_rate_observations_.Size() == 0) | |
| 635 return kInvalidPacketLossRate; | |
| 636 | |
| 637 float packet_loss_rate = kInvalidPacketLossRate; | |
| 638 packet_loss_rate_observations_.GetWeightedAverage(begin_timestamp, | |
| 639 &packet_loss_rate); | |
| 640 return packet_loss_rate; | |
| 641 } | |
| 642 | |
| 647 template <typename ValueType> | 643 template <typename ValueType> |
| 648 void NetworkQualityEstimator::ObservationBuffer<ValueType>:: | 644 void NetworkQualityEstimator::ObservationBuffer<ValueType>:: |
| 649 ComputeWeightedObservations( | 645 ComputeWeightedObservations( |
| 650 const base::TimeTicks& begin_timestamp, | 646 const base::TimeTicks& begin_timestamp, |
| 651 std::vector<WeightedObservation<ValueType>>& weighted_observations, | 647 std::vector<WeightedObservation<ValueType>>& weighted_observations, |
| 652 double* total_weight) const { | 648 double* total_weight) const { |
| 653 weighted_observations.clear(); | 649 weighted_observations.clear(); |
| 654 double total_weight_observations = 0.0; | 650 double total_weight_observations = 0.0; |
| 655 base::TimeTicks now = base::TimeTicks::Now(); | 651 base::TimeTicks now = base::TimeTicks::Now(); |
| 656 | 652 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 710 | 706 |
| 711 // Computation may reach here due to floating point errors. This may happen | 707 // 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 | 708 // if |percentile| was 100 (or close to 100), and |desired_weight| was |
| 713 // slightly larger than |total_weight| (due to floating point errors). | 709 // slightly larger than |total_weight| (due to floating point errors). |
| 714 // In this case, we return the highest |value| among all observations. | 710 // 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. | 711 // This is same as value of the last observation in the sorted vector. |
| 716 *result = weighted_observations.at(weighted_observations.size() - 1).value; | 712 *result = weighted_observations.at(weighted_observations.size() - 1).value; |
| 717 return true; | 713 return true; |
| 718 } | 714 } |
| 719 | 715 |
| 716 template <typename ValueType> | |
| 717 bool NetworkQualityEstimator::ObservationBuffer<ValueType>::GetWeightedAverage( | |
| 718 const base::TimeTicks& begin_timestamp, | |
| 719 ValueType* result) const { | |
| 720 DCHECK(result); | |
| 721 | |
| 722 // Stores WeightedObservation in increasing order of value, although for the | |
| 723 // purpose of computing weighted average, the order does not matter. | |
| 724 std::vector<WeightedObservation<ValueType>> weighted_observations; | |
| 725 | |
| 726 // Total weight of all observations in |weighted_observations|. | |
| 727 double total_weight = 0.0; | |
| 728 | |
| 729 ComputeWeightedObservations(begin_timestamp, weighted_observations, | |
| 730 &total_weight); | |
| 731 if (weighted_observations.empty()) | |
| 732 return false; | |
| 733 | |
| 734 DCHECK_GT(total_weight, 0.0); | |
| 735 | |
| 736 // |weighted_observations| may have a smaller size than |observations_| since | |
|
bengr
2016/02/16 17:02:01
similar size than -> size similar to
tbansal1
2016/02/17 18:35:10
Did you mean "smaller" instead of "similar"?
| |
| 737 // the former only contains the observations later than |begin_timestamp|. | |
| 738 DCHECK_GE(observations_.size(), weighted_observations.size()); | |
| 739 | |
| 740 double total_weight_times_value = 0.0; | |
| 741 for (const auto& weighted_observation : weighted_observations) { | |
| 742 total_weight_times_value += | |
| 743 (weighted_observation.weight * weighted_observation.value); | |
| 744 } | |
| 745 *result = total_weight_times_value / total_weight; | |
| 746 return true; | |
| 747 } | |
| 748 | |
| 720 NetworkQualityEstimator::NetworkID | 749 NetworkQualityEstimator::NetworkID |
| 721 NetworkQualityEstimator::GetCurrentNetworkID() const { | 750 NetworkQualityEstimator::GetCurrentNetworkID() const { |
| 722 DCHECK(thread_checker_.CalledOnValidThread()); | 751 DCHECK(thread_checker_.CalledOnValidThread()); |
| 723 | 752 |
| 724 // TODO(tbansal): crbug.com/498068 Add NetworkQualityEstimatorAndroid class | 753 // TODO(tbansal): crbug.com/498068 Add NetworkQualityEstimatorAndroid class |
| 725 // that overrides this method on the Android platform. | 754 // that overrides this method on the Android platform. |
| 726 | 755 |
| 727 // It is possible that the connection type changed between when | 756 // It is possible that the connection type changed between when |
| 728 // GetConnectionType() was called and when the API to determine the | 757 // GetConnectionType() was called and when the API to determine the |
| 729 // network name was called. Check if that happened and retry until the | 758 // 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 | 922 |
| 894 return scoped_ptr<SocketPerformanceWatcher>( | 923 return scoped_ptr<SocketPerformanceWatcher>( |
| 895 new SocketPerformanceWatcher(protocol, this)); | 924 new SocketPerformanceWatcher(protocol, this)); |
| 896 } | 925 } |
| 897 | 926 |
| 898 void NetworkQualityEstimator::OnUpdatedRTTAvailable( | 927 void NetworkQualityEstimator::OnUpdatedRTTAvailable( |
| 899 const Protocol protocol, | 928 const Protocol protocol, |
| 900 const base::TimeDelta& rtt) { | 929 const base::TimeDelta& rtt) { |
| 901 DCHECK(thread_checker_.CalledOnValidThread()); | 930 DCHECK(thread_checker_.CalledOnValidThread()); |
| 902 | 931 |
| 903 switch (protocol) { | 932 ObservationSource observation_source; |
| 904 case PROTOCOL_TCP: | 933 if (!GetObservationSourceForProtocol(protocol, &observation_source)) |
| 905 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), TCP)); | 934 return; |
| 906 return; | 935 |
| 907 case PROTOCOL_QUIC: | 936 NotifyObserversOfRTT( |
| 908 NotifyObserversOfRTT(RttObservation(rtt, base::TimeTicks::Now(), QUIC)); | 937 RttObservation(rtt, base::TimeTicks::Now(), observation_source)); |
| 909 return; | 938 } |
| 910 default: | 939 |
| 911 NOTREACHED(); | 940 void NetworkQualityEstimator::OnUpdatedPacketCountAvailable( |
| 941 const Protocol protocol, | |
| 942 uint64_t num_packets_lost, | |
| 943 uint64_t num_packets_received_in_order, | |
| 944 uint64_t num_packets_received_not_in_order) { | |
| 945 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 946 | |
| 947 const base::TimeTicks now = base::TimeTicks::Now(); | |
| 948 | |
| 949 ObservationSource observation_source; | |
| 950 if (!GetObservationSourceForProtocol(protocol, &observation_source)) | |
| 951 return; | |
| 952 | |
| 953 for (size_t i = 0; i < num_packets_lost; ++i) { | |
| 954 packet_loss_rate_observations_.AddObservation( | |
| 955 PacketLossObservation(1.0, now, observation_source)); | |
| 912 } | 956 } |
| 957 for (size_t i = 0; i < num_packets_received_in_order; ++i) { | |
| 958 packet_loss_rate_observations_.AddObservation( | |
| 959 PacketLossObservation(0.0, now, observation_source)); | |
| 960 } | |
| 961 // For packet loss estimation, we neglect the packets that were previously | |
| 962 // marked as lost but are later received out-of-order. | |
| 963 NotifyObserversOfPacketLoss(num_packets_lost, num_packets_received_in_order, | |
| 964 num_packets_received_not_in_order, now, | |
| 965 observation_source); | |
| 913 } | 966 } |
| 914 | 967 |
| 915 void NetworkQualityEstimator::NotifyObserversOfRTT( | 968 void NetworkQualityEstimator::NotifyObserversOfRTT( |
| 916 const RttObservation& observation) { | 969 const RttObservation& observation) { |
| 970 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 971 DCHECK_NE(EXTERNAL_ESTIMATE, observation.source); | |
| 972 | |
| 917 FOR_EACH_OBSERVER( | 973 FOR_EACH_OBSERVER( |
| 918 RTTObserver, rtt_observer_list_, | 974 RTTObserver, rtt_observer_list_, |
| 919 OnRTTObservation(observation.value.InMilliseconds(), | 975 OnRTTObservation(observation.value.InMilliseconds(), |
| 920 observation.timestamp, observation.source)); | 976 observation.timestamp, observation.source)); |
| 921 } | 977 } |
| 922 | 978 |
| 923 void NetworkQualityEstimator::NotifyObserversOfThroughput( | 979 void NetworkQualityEstimator::NotifyObserversOfThroughput( |
| 924 const ThroughputObservation& observation) { | 980 const ThroughputObservation& observation) { |
| 981 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 982 DCHECK_NE(EXTERNAL_ESTIMATE, observation.source); | |
| 983 | |
| 925 FOR_EACH_OBSERVER( | 984 FOR_EACH_OBSERVER( |
| 926 ThroughputObserver, throughput_observer_list_, | 985 ThroughputObserver, throughput_observer_list_, |
| 927 OnThroughputObservation(observation.value, observation.timestamp, | 986 OnThroughputObservation(observation.value, observation.timestamp, |
| 928 observation.source)); | 987 observation.source)); |
| 929 } | 988 } |
| 930 | 989 |
| 990 void NetworkQualityEstimator::NotifyObserversOfPacketLoss( | |
| 991 uint64_t num_packets_lost, | |
| 992 uint64_t num_packets_received_in_order, | |
| 993 uint64_t num_packets_received_not_in_order, | |
| 994 const base::TimeTicks& timestamp, | |
| 995 ObservationSource source) { | |
| 996 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 997 DCHECK_NE(EXTERNAL_ESTIMATE, source); | |
| 998 | |
| 999 FOR_EACH_OBSERVER(PacketLossObserver, packet_loss_observer_list_, | |
| 1000 OnPacketLossObservation( | |
| 1001 num_packets_lost, num_packets_received_in_order, | |
| 1002 num_packets_received_not_in_order, timestamp, source)); | |
| 1003 } | |
| 1004 | |
| 931 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( | 1005 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( |
| 932 const NetworkQuality& network_quality) | 1006 const NetworkQuality& network_quality) |
| 933 : last_update_time_(base::TimeTicks::Now()), | 1007 : last_update_time_(base::TimeTicks::Now()), |
| 934 network_quality_(network_quality) { | 1008 network_quality_(network_quality) { |
| 935 } | 1009 } |
| 936 | 1010 |
| 937 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( | 1011 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality( |
| 938 const CachedNetworkQuality& other) | 1012 const CachedNetworkQuality& other) |
| 939 : last_update_time_(other.last_update_time_), | 1013 : last_update_time_(other.last_update_time_), |
| 940 network_quality_(other.network_quality_) { | 1014 network_quality_(other.network_quality_) { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 968 | 1042 |
| 969 NetworkQualityEstimator::NetworkQuality& | 1043 NetworkQualityEstimator::NetworkQuality& |
| 970 NetworkQualityEstimator::NetworkQuality:: | 1044 NetworkQualityEstimator::NetworkQuality:: |
| 971 operator=(const NetworkQuality& other) { | 1045 operator=(const NetworkQuality& other) { |
| 972 rtt_ = other.rtt_; | 1046 rtt_ = other.rtt_; |
| 973 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; | 1047 downstream_throughput_kbps_ = other.downstream_throughput_kbps_; |
| 974 return *this; | 1048 return *this; |
| 975 } | 1049 } |
| 976 | 1050 |
| 977 } // namespace net | 1051 } // namespace net |
| OLD | NEW |