| 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/nqe/network_quality_estimator.h" | 5 #include "net/nqe/network_quality_estimator.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 std::string())), | 245 std::string())), |
| 246 downstream_throughput_kbps_observations_(weight_multiplier_per_second_), | 246 downstream_throughput_kbps_observations_(weight_multiplier_per_second_), |
| 247 rtt_observations_(weight_multiplier_per_second_), | 247 rtt_observations_(weight_multiplier_per_second_), |
| 248 effective_connection_type_at_last_main_frame_( | 248 effective_connection_type_at_last_main_frame_( |
| 249 EFFECTIVE_CONNECTION_TYPE_UNKNOWN), | 249 EFFECTIVE_CONNECTION_TYPE_UNKNOWN), |
| 250 external_estimate_provider_(std::move(external_estimates_provider)), | 250 external_estimate_provider_(std::move(external_estimates_provider)), |
| 251 effective_connection_type_recomputation_interval_( | 251 effective_connection_type_recomputation_interval_( |
| 252 base::TimeDelta::FromSeconds(10)), | 252 base::TimeDelta::FromSeconds(10)), |
| 253 rtt_observations_size_at_last_ect_computation_(0), | 253 rtt_observations_size_at_last_ect_computation_(0), |
| 254 throughput_observations_size_at_last_ect_computation_(0), | 254 throughput_observations_size_at_last_ect_computation_(0), |
| 255 http_rtt_(nqe::internal::InvalidRTT()), | |
| 256 transport_rtt_(nqe::internal::InvalidRTT()), | |
| 257 downstream_throughput_kbps_(nqe::internal::kInvalidThroughput), | |
| 258 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), | 255 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), |
| 259 min_signal_strength_since_connection_change_(INT32_MAX), | 256 min_signal_strength_since_connection_change_(INT32_MAX), |
| 260 max_signal_strength_since_connection_change_(INT32_MIN), | 257 max_signal_strength_since_connection_change_(INT32_MIN), |
| 261 correlation_uma_logging_probability_( | 258 correlation_uma_logging_probability_( |
| 262 nqe::internal::correlation_uma_logging_probability(variation_params)), | 259 nqe::internal::correlation_uma_logging_probability(variation_params)), |
| 263 forced_effective_connection_type_set_( | 260 forced_effective_connection_type_set_( |
| 264 nqe::internal::forced_effective_connection_type_set( | 261 nqe::internal::forced_effective_connection_type_set( |
| 265 variation_params)), | 262 variation_params)), |
| 266 forced_effective_connection_type_( | 263 forced_effective_connection_type_( |
| 267 nqe::internal::forced_effective_connection_type(variation_params)), | 264 nqe::internal::forced_effective_connection_type(variation_params)), |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 !RequestProvidesRTTObservation(request)) { | 372 !RequestProvidesRTTObservation(request)) { |
| 376 return; | 373 return; |
| 377 } | 374 } |
| 378 | 375 |
| 379 const base::TimeTicks now = tick_clock_->NowTicks(); | 376 const base::TimeTicks now = tick_clock_->NowTicks(); |
| 380 | 377 |
| 381 // Update |estimated_quality_at_last_main_frame_| if this is a main frame | 378 // Update |estimated_quality_at_last_main_frame_| if this is a main frame |
| 382 // request. | 379 // request. |
| 383 if (request.load_flags() & LOAD_MAIN_FRAME_DEPRECATED) { | 380 if (request.load_flags() & LOAD_MAIN_FRAME_DEPRECATED) { |
| 384 last_main_frame_request_ = now; | 381 last_main_frame_request_ = now; |
| 385 base::TimeDelta estimated_http_rtt; | |
| 386 if (!GetHttpRTT(&estimated_http_rtt)) | |
| 387 estimated_http_rtt = nqe::internal::InvalidRTT(); | |
| 388 | |
| 389 base::TimeDelta estimated_transport_rtt; | |
| 390 if (!GetTransportRTT(&estimated_transport_rtt)) | |
| 391 estimated_transport_rtt = nqe::internal::InvalidRTT(); | |
| 392 | |
| 393 int32_t downstream_throughput_kbps; | |
| 394 if (!GetDownlinkThroughputKbps(&downstream_throughput_kbps)) | |
| 395 downstream_throughput_kbps = nqe::internal::kInvalidThroughput; | |
| 396 | |
| 397 estimated_quality_at_last_main_frame_ = nqe::internal::NetworkQuality( | |
| 398 estimated_http_rtt, estimated_transport_rtt, | |
| 399 downstream_throughput_kbps); | |
| 400 | 382 |
| 401 ComputeEffectiveConnectionType(); | 383 ComputeEffectiveConnectionType(); |
| 402 effective_connection_type_at_last_main_frame_ = | 384 effective_connection_type_at_last_main_frame_ = effective_connection_type_; |
| 403 GetEffectiveConnectionType(); | 385 estimated_quality_at_last_main_frame_ = network_quality_; |
| 404 | 386 |
| 405 RecordMetricsOnMainFrameRequest(); | 387 RecordMetricsOnMainFrameRequest(); |
| 406 MaybeQueryExternalEstimateProvider(); | 388 MaybeQueryExternalEstimateProvider(); |
| 407 | 389 |
| 408 // Post the tasks which will run in the future and record the estimation | 390 // Post the tasks which will run in the future and record the estimation |
| 409 // accuracy based on the observations received between now and the time of | 391 // accuracy based on the observations received between now and the time of |
| 410 // task execution. Posting the task at different intervals makes it | 392 // task execution. Posting the task at different intervals makes it |
| 411 // possible to measure the accuracy by comparing the estimate with the | 393 // possible to measure the accuracy by comparing the estimate with the |
| 412 // observations received over intervals of varying durations. | 394 // observations received over intervals of varying durations. |
| 413 for (const base::TimeDelta& measuring_delay : | 395 for (const base::TimeDelta& measuring_delay : |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 // time. Returning here ensures that we do not take inaccurate readings. | 452 // time. Returning here ensures that we do not take inaccurate readings. |
| 471 if (now - last_main_frame_request_ > 2 * measuring_duration) | 453 if (now - last_main_frame_request_ > 2 * measuring_duration) |
| 472 return; | 454 return; |
| 473 | 455 |
| 474 // Do not record accuracy if there was a connection change since the last main | 456 // Do not record accuracy if there was a connection change since the last main |
| 475 // frame request. | 457 // frame request. |
| 476 if (last_main_frame_request_ <= last_connection_change_) | 458 if (last_main_frame_request_ <= last_connection_change_) |
| 477 return; | 459 return; |
| 478 | 460 |
| 479 base::TimeDelta recent_http_rtt; | 461 base::TimeDelta recent_http_rtt; |
| 462 if (!GetRecentHttpRTT(last_main_frame_request_, &recent_http_rtt)) |
| 463 recent_http_rtt = nqe::internal::InvalidRTT(); |
| 464 |
| 480 if (estimated_quality_at_last_main_frame_.http_rtt() != | 465 if (estimated_quality_at_last_main_frame_.http_rtt() != |
| 481 nqe::internal::InvalidRTT() && | 466 nqe::internal::InvalidRTT() && |
| 482 GetRecentHttpRTT(last_main_frame_request_, &recent_http_rtt)) { | 467 recent_http_rtt != nqe::internal::InvalidRTT()) { |
| 483 const int estimated_observed_diff_milliseconds = | 468 const int estimated_observed_diff_milliseconds = |
| 484 estimated_quality_at_last_main_frame_.http_rtt().InMilliseconds() - | 469 estimated_quality_at_last_main_frame_.http_rtt().InMilliseconds() - |
| 485 recent_http_rtt.InMilliseconds(); | 470 recent_http_rtt.InMilliseconds(); |
| 486 | 471 |
| 487 RecordRTTAccuracy("NQE.Accuracy.HttpRTT", | 472 RecordRTTAccuracy("NQE.Accuracy.HttpRTT", |
| 488 estimated_observed_diff_milliseconds, measuring_duration, | 473 estimated_observed_diff_milliseconds, measuring_duration, |
| 489 recent_http_rtt); | 474 recent_http_rtt); |
| 490 } | 475 } |
| 491 | 476 |
| 492 base::TimeDelta recent_transport_rtt; | 477 base::TimeDelta recent_transport_rtt; |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 use_small_responses_ = use_small_responses; | 687 use_small_responses_ = use_small_responses; |
| 703 throughput_analyzer_->SetUseSmallResponsesForTesting(use_small_responses_); | 688 throughput_analyzer_->SetUseSmallResponsesForTesting(use_small_responses_); |
| 704 } | 689 } |
| 705 | 690 |
| 706 void NetworkQualityEstimator::ReportEffectiveConnectionTypeForTesting( | 691 void NetworkQualityEstimator::ReportEffectiveConnectionTypeForTesting( |
| 707 EffectiveConnectionType effective_connection_type) { | 692 EffectiveConnectionType effective_connection_type) { |
| 708 DCHECK(thread_checker_.CalledOnValidThread()); | 693 DCHECK(thread_checker_.CalledOnValidThread()); |
| 709 for (auto& observer : effective_connection_type_observer_list_) | 694 for (auto& observer : effective_connection_type_observer_list_) |
| 710 observer.OnEffectiveConnectionTypeChanged(effective_connection_type); | 695 observer.OnEffectiveConnectionTypeChanged(effective_connection_type); |
| 711 | 696 |
| 712 network_quality_store_->Add( | 697 network_quality_store_->Add(current_network_id_, |
| 713 current_network_id_, | 698 nqe::internal::CachedNetworkQuality( |
| 714 nqe::internal::CachedNetworkQuality(tick_clock_->NowTicks(), | 699 tick_clock_->NowTicks(), network_quality_, |
| 715 estimated_quality_at_last_main_frame_, | 700 effective_connection_type)); |
| 716 effective_connection_type)); | |
| 717 } | 701 } |
| 718 | 702 |
| 719 bool NetworkQualityEstimator::RequestProvidesRTTObservation( | 703 bool NetworkQualityEstimator::RequestProvidesRTTObservation( |
| 720 const URLRequest& request) const { | 704 const URLRequest& request) const { |
| 721 DCHECK(thread_checker_.CalledOnValidThread()); | 705 DCHECK(thread_checker_.CalledOnValidThread()); |
| 722 | 706 |
| 723 return (use_localhost_requests_ || !IsLocalhost(request.url().host())) && | 707 return (use_localhost_requests_ || !IsLocalhost(request.url().host())) && |
| 724 // Verify that response headers are received, so it can be ensured that | 708 // Verify that response headers are received, so it can be ensured that |
| 725 // response is not cached. | 709 // response is not cached. |
| 726 !request.response_info().response_time.is_null() && | 710 !request.response_info().response_time.is_null() && |
| 727 !request.was_cached() && | 711 !request.was_cached() && |
| 728 request.creation_time() >= last_connection_change_; | 712 request.creation_time() >= last_connection_change_; |
| 729 } | 713 } |
| 730 | 714 |
| 731 void NetworkQualityEstimator::RecordExternalEstimateProviderMetrics( | 715 void NetworkQualityEstimator::RecordExternalEstimateProviderMetrics( |
| 732 NQEExternalEstimateProviderStatus status) const { | 716 NQEExternalEstimateProviderStatus status) const { |
| 733 UMA_HISTOGRAM_ENUMERATION("NQE.ExternalEstimateProviderStatus", status, | 717 UMA_HISTOGRAM_ENUMERATION("NQE.ExternalEstimateProviderStatus", status, |
| 734 EXTERNAL_ESTIMATE_PROVIDER_STATUS_BOUNDARY); | 718 EXTERNAL_ESTIMATE_PROVIDER_STATUS_BOUNDARY); |
| 735 } | 719 } |
| 736 | 720 |
| 737 void NetworkQualityEstimator::OnConnectionTypeChanged( | 721 void NetworkQualityEstimator::OnConnectionTypeChanged( |
| 738 NetworkChangeNotifier::ConnectionType type) { | 722 NetworkChangeNotifier::ConnectionType type) { |
| 739 DCHECK(thread_checker_.CalledOnValidThread()); | 723 DCHECK(thread_checker_.CalledOnValidThread()); |
| 740 | 724 |
| 741 RecordMetricsOnConnectionTypeChanged(); | 725 RecordMetricsOnConnectionTypeChanged(); |
| 742 | 726 |
| 743 // Write the estimates of the previous network to the cache. | 727 // Write the estimates of the previous network to the cache. |
| 744 network_quality_store_->Add( | 728 network_quality_store_->Add( |
| 745 current_network_id_, | 729 current_network_id_, nqe::internal::CachedNetworkQuality( |
| 746 nqe::internal::CachedNetworkQuality( | 730 last_effective_connection_type_computation_, |
| 747 last_effective_connection_type_computation_, | 731 network_quality_, effective_connection_type_)); |
| 748 estimated_quality_at_last_main_frame_, effective_connection_type_)); | |
| 749 | 732 |
| 750 // Clear the local state. | 733 // Clear the local state. |
| 751 last_connection_change_ = tick_clock_->NowTicks(); | 734 last_connection_change_ = tick_clock_->NowTicks(); |
| 752 peak_network_quality_ = nqe::internal::NetworkQuality(); | 735 peak_network_quality_ = nqe::internal::NetworkQuality(); |
| 753 downstream_throughput_kbps_observations_.Clear(); | 736 downstream_throughput_kbps_observations_.Clear(); |
| 754 rtt_observations_.Clear(); | 737 rtt_observations_.Clear(); |
| 755 | 738 |
| 756 #if defined(OS_ANDROID) | 739 #if defined(OS_ANDROID) |
| 757 if (NetworkChangeNotifier::IsConnectionCellular(current_network_id_.type)) { | 740 if (NetworkChangeNotifier::IsConnectionCellular(current_network_id_.type)) { |
| 758 UMA_HISTOGRAM_BOOLEAN( | 741 UMA_HISTOGRAM_BOOLEAN( |
| 759 "NQE.CellularSignalStrengthAvailable", | 742 "NQE.CellularSignalStrengthAvailable", |
| 760 min_signal_strength_since_connection_change_ != INT32_MAX && | 743 min_signal_strength_since_connection_change_ != INT32_MAX && |
| 761 max_signal_strength_since_connection_change_ != INT32_MIN); | 744 max_signal_strength_since_connection_change_ != INT32_MIN); |
| 762 } | 745 } |
| 763 #endif // OS_ANDROID | 746 #endif // OS_ANDROID |
| 764 min_signal_strength_since_connection_change_ = INT32_MAX; | 747 min_signal_strength_since_connection_change_ = INT32_MAX; |
| 765 max_signal_strength_since_connection_change_ = INT32_MIN; | 748 max_signal_strength_since_connection_change_ = INT32_MIN; |
| 766 estimated_quality_at_last_main_frame_ = nqe::internal::NetworkQuality(); | 749 network_quality_ = nqe::internal::NetworkQuality(); |
| 767 http_rtt_ = nqe::internal::InvalidRTT(); | |
| 768 transport_rtt_ = nqe::internal::InvalidRTT(); | |
| 769 downstream_throughput_kbps_ = nqe::internal::kInvalidThroughput; | |
| 770 effective_connection_type_ = EFFECTIVE_CONNECTION_TYPE_UNKNOWN; | 750 effective_connection_type_ = EFFECTIVE_CONNECTION_TYPE_UNKNOWN; |
| 771 effective_connection_type_at_last_main_frame_ = | 751 effective_connection_type_at_last_main_frame_ = |
| 772 EFFECTIVE_CONNECTION_TYPE_UNKNOWN; | 752 EFFECTIVE_CONNECTION_TYPE_UNKNOWN; |
| 773 | 753 |
| 774 // Update the local state as part of preparation for the new connection. | 754 // Update the local state as part of preparation for the new connection. |
| 775 current_network_id_ = GetCurrentNetworkID(); | 755 current_network_id_ = GetCurrentNetworkID(); |
| 776 RecordNetworkIDAvailability(); | 756 RecordNetworkIDAvailability(); |
| 777 | 757 |
| 778 MaybeQueryExternalEstimateProvider(); | 758 MaybeQueryExternalEstimateProvider(); |
| 779 | 759 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 826 | 806 |
| 827 if (peak_network_quality_.downstream_throughput_kbps() != | 807 if (peak_network_quality_.downstream_throughput_kbps() != |
| 828 nqe::internal::kInvalidThroughput) { | 808 nqe::internal::kInvalidThroughput) { |
| 829 base::HistogramBase* downstream_throughput_histogram = | 809 base::HistogramBase* downstream_throughput_histogram = |
| 830 GetHistogram("PeakKbps.", current_network_id_.type, 1000 * 1000); | 810 GetHistogram("PeakKbps.", current_network_id_.type, 1000 * 1000); |
| 831 downstream_throughput_histogram->Add( | 811 downstream_throughput_histogram->Add( |
| 832 peak_network_quality_.downstream_throughput_kbps()); | 812 peak_network_quality_.downstream_throughput_kbps()); |
| 833 } | 813 } |
| 834 | 814 |
| 835 base::TimeDelta rtt; | 815 base::TimeDelta rtt; |
| 836 if (GetHttpRTT(&rtt)) { | 816 if (GetRecentHttpRTT(base::TimeTicks(), &rtt)) { |
| 837 // Add the 50th percentile value. | 817 // Add the 50th percentile value. |
| 838 base::HistogramBase* rtt_percentile = | 818 base::HistogramBase* rtt_percentile = |
| 839 GetHistogram("RTT.Percentile50.", current_network_id_.type, 10 * 1000); | 819 GetHistogram("RTT.Percentile50.", current_network_id_.type, 10 * 1000); |
| 840 rtt_percentile->Add(rtt.InMilliseconds()); | 820 rtt_percentile->Add(rtt.InMilliseconds()); |
| 841 | 821 |
| 842 // Add the remaining percentile values. | 822 // Add the remaining percentile values. |
| 843 static const int kPercentiles[] = {0, 10, 90, 100}; | 823 static const int kPercentiles[] = {0, 10, 90, 100}; |
| 844 std::vector<NetworkQualityObservationSource> disallowed_observation_sources; | 824 std::vector<NetworkQualityObservationSource> disallowed_observation_sources; |
| 845 disallowed_observation_sources.push_back( | 825 disallowed_observation_sources.push_back( |
| 846 NETWORK_QUALITY_OBSERVATION_SOURCE_TCP); | 826 NETWORK_QUALITY_OBSERVATION_SOURCE_TCP); |
| 847 disallowed_observation_sources.push_back( | 827 disallowed_observation_sources.push_back( |
| 848 NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC); | 828 NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC); |
| 849 for (size_t i = 0; i < arraysize(kPercentiles); ++i) { | 829 for (size_t i = 0; i < arraysize(kPercentiles); ++i) { |
| 850 rtt = GetRTTEstimateInternal(disallowed_observation_sources, | 830 rtt = GetRTTEstimateInternal(disallowed_observation_sources, |
| 851 base::TimeTicks(), kPercentiles[i]); | 831 base::TimeTicks(), kPercentiles[i]); |
| 852 | 832 |
| 853 rtt_percentile = GetHistogram( | 833 rtt_percentile = GetHistogram( |
| 854 "RTT.Percentile" + base::IntToString(kPercentiles[i]) + ".", | 834 "RTT.Percentile" + base::IntToString(kPercentiles[i]) + ".", |
| 855 current_network_id_.type, 10 * 1000); // 10 seconds | 835 current_network_id_.type, 10 * 1000); // 10 seconds |
| 856 rtt_percentile->Add(rtt.InMilliseconds()); | 836 rtt_percentile->Add(rtt.InMilliseconds()); |
| 857 } | 837 } |
| 858 } | 838 } |
| 859 | 839 |
| 860 if (GetTransportRTT(&rtt)) { | 840 if (GetRecentTransportRTT(base::TimeTicks(), &rtt)) { |
| 861 // Add the 50th percentile value. | 841 // Add the 50th percentile value. |
| 862 base::HistogramBase* transport_rtt_percentile = GetHistogram( | 842 base::HistogramBase* transport_rtt_percentile = GetHistogram( |
| 863 "TransportRTT.Percentile50.", current_network_id_.type, 10 * 1000); | 843 "TransportRTT.Percentile50.", current_network_id_.type, 10 * 1000); |
| 864 transport_rtt_percentile->Add(rtt.InMilliseconds()); | 844 transport_rtt_percentile->Add(rtt.InMilliseconds()); |
| 865 | 845 |
| 866 // Add the remaining percentile values. | 846 // Add the remaining percentile values. |
| 867 static const int kPercentiles[] = {0, 10, 90, 100}; | 847 static const int kPercentiles[] = {0, 10, 90, 100}; |
| 868 std::vector<NetworkQualityObservationSource> disallowed_observation_sources; | 848 std::vector<NetworkQualityObservationSource> disallowed_observation_sources; |
| 869 disallowed_observation_sources.push_back( | 849 disallowed_observation_sources.push_back( |
| 870 NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP); | 850 NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 893 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI || | 873 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI || |
| 894 NetworkChangeNotifier::IsConnectionCellular(current_network_id_.type)) { | 874 NetworkChangeNotifier::IsConnectionCellular(current_network_id_.type)) { |
| 895 UMA_HISTOGRAM_BOOLEAN("NQE.NetworkIdAvailable", | 875 UMA_HISTOGRAM_BOOLEAN("NQE.NetworkIdAvailable", |
| 896 !current_network_id_.id.empty()); | 876 !current_network_id_.id.empty()); |
| 897 } | 877 } |
| 898 } | 878 } |
| 899 | 879 |
| 900 void NetworkQualityEstimator::RecordMetricsOnMainFrameRequest() const { | 880 void NetworkQualityEstimator::RecordMetricsOnMainFrameRequest() const { |
| 901 DCHECK(thread_checker_.CalledOnValidThread()); | 881 DCHECK(thread_checker_.CalledOnValidThread()); |
| 902 | 882 |
| 903 base::TimeDelta http_rtt; | 883 if (estimated_quality_at_last_main_frame_.http_rtt() != |
| 904 if (GetHttpRTT(&http_rtt)) { | 884 nqe::internal::InvalidRTT()) { |
| 905 // Add the 50th percentile value. | 885 // Add the 50th percentile value. |
| 906 UMA_HISTOGRAM_TIMES("NQE.MainFrame.RTT.Percentile50", http_rtt); | 886 UMA_HISTOGRAM_TIMES("NQE.MainFrame.RTT.Percentile50", |
| 887 estimated_quality_at_last_main_frame_.http_rtt()); |
| 907 base::HistogramBase* rtt_percentile = GetHistogram( | 888 base::HistogramBase* rtt_percentile = GetHistogram( |
| 908 "MainFrame.RTT.Percentile50.", current_network_id_.type, 10 * 1000); | 889 "MainFrame.RTT.Percentile50.", current_network_id_.type, 10 * 1000); |
| 909 rtt_percentile->Add(http_rtt.InMilliseconds()); | 890 rtt_percentile->Add( |
| 891 estimated_quality_at_last_main_frame_.http_rtt().InMilliseconds()); |
| 910 } | 892 } |
| 911 | 893 |
| 912 base::TimeDelta transport_rtt; | 894 if (estimated_quality_at_last_main_frame_.transport_rtt() != |
| 913 if (GetTransportRTT(&transport_rtt)) { | 895 nqe::internal::InvalidRTT()) { |
| 914 // Add the 50th percentile value. | 896 // Add the 50th percentile value. |
| 915 UMA_HISTOGRAM_TIMES("NQE.MainFrame.TransportRTT.Percentile50", | 897 UMA_HISTOGRAM_TIMES("NQE.MainFrame.TransportRTT.Percentile50", |
| 916 transport_rtt); | 898 estimated_quality_at_last_main_frame_.transport_rtt()); |
| 917 base::HistogramBase* transport_rtt_percentile = | 899 base::HistogramBase* transport_rtt_percentile = |
| 918 GetHistogram("MainFrame.TransportRTT.Percentile50.", | 900 GetHistogram("MainFrame.TransportRTT.Percentile50.", |
| 919 current_network_id_.type, 10 * 1000); | 901 current_network_id_.type, 10 * 1000); |
| 920 transport_rtt_percentile->Add(transport_rtt.InMilliseconds()); | 902 transport_rtt_percentile->Add( |
| 903 estimated_quality_at_last_main_frame_.transport_rtt().InMilliseconds()); |
| 921 } | 904 } |
| 922 | 905 |
| 923 int32_t kbps; | 906 if (estimated_quality_at_last_main_frame_.downstream_throughput_kbps() != |
| 924 if (GetDownlinkThroughputKbps(&kbps)) { | 907 nqe::internal::kInvalidThroughput) { |
| 925 // Add the 50th percentile value. | 908 // Add the 50th percentile value. |
| 926 UMA_HISTOGRAM_COUNTS_1M("NQE.MainFrame.Kbps.Percentile50", kbps); | 909 UMA_HISTOGRAM_COUNTS_1M( |
| 910 "NQE.MainFrame.Kbps.Percentile50", |
| 911 estimated_quality_at_last_main_frame_.downstream_throughput_kbps()); |
| 927 base::HistogramBase* throughput_percentile = GetHistogram( | 912 base::HistogramBase* throughput_percentile = GetHistogram( |
| 928 "MainFrame.Kbps.Percentile50.", current_network_id_.type, 1000 * 1000); | 913 "MainFrame.Kbps.Percentile50.", current_network_id_.type, 1000 * 1000); |
| 929 throughput_percentile->Add(kbps); | 914 throughput_percentile->Add( |
| 915 estimated_quality_at_last_main_frame_.downstream_throughput_kbps()); |
| 930 } | 916 } |
| 931 | 917 |
| 932 const EffectiveConnectionType effective_connection_type = | |
| 933 GetEffectiveConnectionType(); | |
| 934 UMA_HISTOGRAM_ENUMERATION("NQE.MainFrame.EffectiveConnectionType", | 918 UMA_HISTOGRAM_ENUMERATION("NQE.MainFrame.EffectiveConnectionType", |
| 935 effective_connection_type, | 919 effective_connection_type_at_last_main_frame_, |
| 936 EFFECTIVE_CONNECTION_TYPE_LAST); | 920 EFFECTIVE_CONNECTION_TYPE_LAST); |
| 937 base::HistogramBase* effective_connection_type_histogram = | 921 base::HistogramBase* effective_connection_type_histogram = |
| 938 base::Histogram::FactoryGet( | 922 base::Histogram::FactoryGet( |
| 939 std::string("NQE.MainFrame.EffectiveConnectionType.") + | 923 std::string("NQE.MainFrame.EffectiveConnectionType.") + |
| 940 nqe::internal::GetNameForConnectionType(current_network_id_.type), | 924 nqe::internal::GetNameForConnectionType(current_network_id_.type), |
| 941 0, EFFECTIVE_CONNECTION_TYPE_LAST, | 925 0, EFFECTIVE_CONNECTION_TYPE_LAST, |
| 942 EFFECTIVE_CONNECTION_TYPE_LAST /* Number of buckets */, | 926 EFFECTIVE_CONNECTION_TYPE_LAST /* Number of buckets */, |
| 943 base::HistogramBase::kUmaTargetedHistogramFlag); | 927 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 944 | 928 |
| 945 effective_connection_type_histogram->Add(effective_connection_type); | 929 effective_connection_type_histogram->Add( |
| 930 effective_connection_type_at_last_main_frame_); |
| 946 } | 931 } |
| 947 | 932 |
| 948 void NetworkQualityEstimator::ComputeEffectiveConnectionType() { | 933 void NetworkQualityEstimator::ComputeEffectiveConnectionType() { |
| 949 DCHECK(thread_checker_.CalledOnValidThread()); | 934 DCHECK(thread_checker_.CalledOnValidThread()); |
| 950 | 935 |
| 951 const base::TimeTicks now = tick_clock_->NowTicks(); | 936 const base::TimeTicks now = tick_clock_->NowTicks(); |
| 952 | 937 |
| 953 const EffectiveConnectionType past_type = effective_connection_type_; | 938 const EffectiveConnectionType past_type = effective_connection_type_; |
| 954 last_effective_connection_type_computation_ = now; | 939 last_effective_connection_type_computation_ = now; |
| 955 | 940 |
| 941 base::TimeDelta http_rtt = nqe::internal::InvalidRTT(); |
| 942 base::TimeDelta transport_rtt = nqe::internal::InvalidRTT(); |
| 943 int32_t downstream_throughput_kbps = nqe::internal::kInvalidThroughput; |
| 944 |
| 956 effective_connection_type_ = | 945 effective_connection_type_ = |
| 957 GetRecentEffectiveConnectionTypeAndNetworkQuality( | 946 GetRecentEffectiveConnectionTypeAndNetworkQuality( |
| 958 base::TimeTicks(), &http_rtt_, &transport_rtt_, | 947 base::TimeTicks(), &http_rtt, &transport_rtt, |
| 959 &downstream_throughput_kbps_); | 948 &downstream_throughput_kbps); |
| 949 |
| 950 network_quality_ = nqe::internal::NetworkQuality(http_rtt, transport_rtt, |
| 951 downstream_throughput_kbps); |
| 952 |
| 960 NotifyObserversOfRTTOrThroughputComputed(); | 953 NotifyObserversOfRTTOrThroughputComputed(); |
| 961 | 954 |
| 962 if (past_type != effective_connection_type_) | 955 if (past_type != effective_connection_type_) |
| 963 NotifyObserversOfEffectiveConnectionTypeChanged(); | 956 NotifyObserversOfEffectiveConnectionTypeChanged(); |
| 964 | 957 |
| 965 rtt_observations_size_at_last_ect_computation_ = rtt_observations_.Size(); | 958 rtt_observations_size_at_last_ect_computation_ = rtt_observations_.Size(); |
| 966 throughput_observations_size_at_last_ect_computation_ = | 959 throughput_observations_size_at_last_ect_computation_ = |
| 967 downstream_throughput_kbps_observations_.Size(); | 960 downstream_throughput_kbps_observations_.Size(); |
| 968 } | 961 } |
| 969 | 962 |
| 970 EffectiveConnectionType NetworkQualityEstimator::GetEffectiveConnectionType() | 963 EffectiveConnectionType NetworkQualityEstimator::GetEffectiveConnectionType() |
| 971 const { | 964 const { |
| 972 DCHECK(thread_checker_.CalledOnValidThread()); | 965 DCHECK(thread_checker_.CalledOnValidThread()); |
| 973 return effective_connection_type_; | 966 return effective_connection_type_; |
| 974 } | 967 } |
| 975 | 968 |
| 976 EffectiveConnectionType | 969 EffectiveConnectionType |
| 977 NetworkQualityEstimator::GetRecentEffectiveConnectionType( | 970 NetworkQualityEstimator::GetRecentEffectiveConnectionType( |
| 978 const base::TimeTicks& start_time) const { | 971 const base::TimeTicks& start_time) const { |
| 979 DCHECK(thread_checker_.CalledOnValidThread()); | 972 DCHECK(thread_checker_.CalledOnValidThread()); |
| 980 | 973 |
| 981 base::TimeDelta http_rtt; | 974 base::TimeDelta http_rtt = nqe::internal::InvalidRTT(); |
| 982 base::TimeDelta transport_rtt; | 975 base::TimeDelta transport_rtt = nqe::internal::InvalidRTT(); |
| 983 int32_t downstream_throughput_kbps; | 976 int32_t downstream_throughput_kbps = nqe::internal::kInvalidThroughput; |
| 984 | 977 |
| 985 return GetRecentEffectiveConnectionTypeAndNetworkQuality( | 978 return GetRecentEffectiveConnectionTypeAndNetworkQuality( |
| 986 start_time, &http_rtt, &transport_rtt, &downstream_throughput_kbps); | 979 start_time, &http_rtt, &transport_rtt, &downstream_throughput_kbps); |
| 987 } | 980 } |
| 988 | 981 |
| 989 EffectiveConnectionType | 982 EffectiveConnectionType |
| 990 NetworkQualityEstimator::GetRecentEffectiveConnectionTypeAndNetworkQuality( | 983 NetworkQualityEstimator::GetRecentEffectiveConnectionTypeAndNetworkQuality( |
| 991 const base::TimeTicks& start_time, | 984 const base::TimeTicks& start_time, |
| 992 base::TimeDelta* http_rtt, | 985 base::TimeDelta* http_rtt, |
| 993 base::TimeDelta* transport_rtt, | 986 base::TimeDelta* transport_rtt, |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1154 DCHECK(thread_checker_.CalledOnValidThread()); | 1147 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1155 rtt_and_throughput_estimates_observer_list_.AddObserver(observer); | 1148 rtt_and_throughput_estimates_observer_list_.AddObserver(observer); |
| 1156 } | 1149 } |
| 1157 | 1150 |
| 1158 void NetworkQualityEstimator::RemoveRTTAndThroughputEstimatesObserver( | 1151 void NetworkQualityEstimator::RemoveRTTAndThroughputEstimatesObserver( |
| 1159 RTTAndThroughputEstimatesObserver* observer) { | 1152 RTTAndThroughputEstimatesObserver* observer) { |
| 1160 DCHECK(thread_checker_.CalledOnValidThread()); | 1153 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1161 rtt_and_throughput_estimates_observer_list_.RemoveObserver(observer); | 1154 rtt_and_throughput_estimates_observer_list_.RemoveObserver(observer); |
| 1162 } | 1155 } |
| 1163 | 1156 |
| 1164 bool NetworkQualityEstimator::GetHttpRTT(base::TimeDelta* rtt) const { | |
| 1165 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 1166 return GetRecentHttpRTT(base::TimeTicks(), rtt); | |
| 1167 } | |
| 1168 | |
| 1169 bool NetworkQualityEstimator::GetTransportRTT(base::TimeDelta* rtt) const { | |
| 1170 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 1171 return GetRecentTransportRTT(base::TimeTicks(), rtt); | |
| 1172 } | |
| 1173 | |
| 1174 bool NetworkQualityEstimator::GetDownlinkThroughputKbps(int32_t* kbps) const { | |
| 1175 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 1176 return GetRecentDownlinkThroughputKbps(base::TimeTicks(), kbps); | |
| 1177 } | |
| 1178 | |
| 1179 bool NetworkQualityEstimator::GetRecentHttpRTT( | 1157 bool NetworkQualityEstimator::GetRecentHttpRTT( |
| 1180 const base::TimeTicks& start_time, | 1158 const base::TimeTicks& start_time, |
| 1181 base::TimeDelta* rtt) const { | 1159 base::TimeDelta* rtt) const { |
| 1182 DCHECK(thread_checker_.CalledOnValidThread()); | 1160 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1183 std::vector<NetworkQualityObservationSource> disallowed_observation_sources; | 1161 std::vector<NetworkQualityObservationSource> disallowed_observation_sources; |
| 1184 disallowed_observation_sources.push_back( | 1162 disallowed_observation_sources.push_back( |
| 1185 NETWORK_QUALITY_OBSERVATION_SOURCE_TCP); | 1163 NETWORK_QUALITY_OBSERVATION_SOURCE_TCP); |
| 1186 disallowed_observation_sources.push_back( | 1164 disallowed_observation_sources.push_back( |
| 1187 NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC); | 1165 NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC); |
| 1188 *rtt = GetRTTEstimateInternal(disallowed_observation_sources, start_time, 50); | 1166 *rtt = GetRTTEstimateInternal(disallowed_observation_sources, start_time, 50); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1306 cached_estimate_available); | 1284 cached_estimate_available); |
| 1307 | 1285 |
| 1308 if (!cached_estimate_available) | 1286 if (!cached_estimate_available) |
| 1309 return false; | 1287 return false; |
| 1310 | 1288 |
| 1311 const base::TimeTicks now = tick_clock_->NowTicks(); | 1289 const base::TimeTicks now = tick_clock_->NowTicks(); |
| 1312 | 1290 |
| 1313 if (effective_connection_type_ == EFFECTIVE_CONNECTION_TYPE_UNKNOWN) { | 1291 if (effective_connection_type_ == EFFECTIVE_CONNECTION_TYPE_UNKNOWN) { |
| 1314 // Read the effective connection type from the cached estimate. | 1292 // Read the effective connection type from the cached estimate. |
| 1315 last_effective_connection_type_computation_ = now; | 1293 last_effective_connection_type_computation_ = now; |
| 1316 http_rtt_ = cached_network_quality.network_quality().http_rtt(); | 1294 network_quality_ = cached_network_quality.network_quality(); |
| 1317 transport_rtt_ = cached_network_quality.network_quality().transport_rtt(); | |
| 1318 downstream_throughput_kbps_ = | |
| 1319 cached_network_quality.network_quality().downstream_throughput_kbps(); | |
| 1320 effective_connection_type_ = | 1295 effective_connection_type_ = |
| 1321 cached_network_quality.effective_connection_type(); | 1296 cached_network_quality.effective_connection_type(); |
| 1322 | 1297 |
| 1323 if (effective_connection_type_ != EFFECTIVE_CONNECTION_TYPE_UNKNOWN) | 1298 if (effective_connection_type_ != EFFECTIVE_CONNECTION_TYPE_UNKNOWN) |
| 1324 NotifyObserversOfEffectiveConnectionTypeChanged(); | 1299 NotifyObserversOfEffectiveConnectionTypeChanged(); |
| 1325 } | 1300 } |
| 1326 | 1301 |
| 1327 if (cached_network_quality.network_quality().downstream_throughput_kbps() != | 1302 if (cached_network_quality.network_quality().downstream_throughput_kbps() != |
| 1328 nqe::internal::kInvalidThroughput) { | 1303 nqe::internal::kInvalidThroughput) { |
| 1329 ThroughputObservation througphput_observation( | 1304 ThroughputObservation througphput_observation( |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1487 NotifyObserversOfEffectiveConnectionTypeChanged() { | 1462 NotifyObserversOfEffectiveConnectionTypeChanged() { |
| 1488 DCHECK(thread_checker_.CalledOnValidThread()); | 1463 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1489 DCHECK_NE(EFFECTIVE_CONNECTION_TYPE_LAST, effective_connection_type_); | 1464 DCHECK_NE(EFFECTIVE_CONNECTION_TYPE_LAST, effective_connection_type_); |
| 1490 | 1465 |
| 1491 // TODO(tbansal): Add hysteresis in the notification. | 1466 // TODO(tbansal): Add hysteresis in the notification. |
| 1492 for (auto& observer : effective_connection_type_observer_list_) | 1467 for (auto& observer : effective_connection_type_observer_list_) |
| 1493 observer.OnEffectiveConnectionTypeChanged(effective_connection_type_); | 1468 observer.OnEffectiveConnectionTypeChanged(effective_connection_type_); |
| 1494 | 1469 |
| 1495 // Add the estimates of the current network to the cache store. | 1470 // Add the estimates of the current network to the cache store. |
| 1496 if (effective_connection_type_ != EFFECTIVE_CONNECTION_TYPE_UNKNOWN) { | 1471 if (effective_connection_type_ != EFFECTIVE_CONNECTION_TYPE_UNKNOWN) { |
| 1497 network_quality_store_->Add( | 1472 network_quality_store_->Add(current_network_id_, |
| 1498 current_network_id_, | 1473 nqe::internal::CachedNetworkQuality( |
| 1499 nqe::internal::CachedNetworkQuality( | 1474 tick_clock_->NowTicks(), network_quality_, |
| 1500 tick_clock_->NowTicks(), estimated_quality_at_last_main_frame_, | 1475 effective_connection_type_)); |
| 1501 effective_connection_type_)); | |
| 1502 } | 1476 } |
| 1503 } | 1477 } |
| 1504 | 1478 |
| 1505 void NetworkQualityEstimator::NotifyObserversOfRTTOrThroughputComputed() const { | 1479 void NetworkQualityEstimator::NotifyObserversOfRTTOrThroughputComputed() const { |
| 1506 DCHECK(thread_checker_.CalledOnValidThread()); | 1480 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1507 | 1481 |
| 1508 // TODO(tbansal): Add hysteresis in the notification. | 1482 // TODO(tbansal): Add hysteresis in the notification. |
| 1509 for (auto& observer : rtt_and_throughput_estimates_observer_list_) { | 1483 for (auto& observer : rtt_and_throughput_estimates_observer_list_) { |
| 1510 observer.OnRTTOrThroughputEstimatesComputed(http_rtt_, transport_rtt_, | 1484 observer.OnRTTOrThroughputEstimatesComputed( |
| 1511 downstream_throughput_kbps_); | 1485 network_quality_.http_rtt(), network_quality_.transport_rtt(), |
| 1486 network_quality_.downstream_throughput_kbps()); |
| 1512 } | 1487 } |
| 1513 } | 1488 } |
| 1514 | 1489 |
| 1515 void NetworkQualityEstimator::AddNetworkQualitiesCacheObserver( | 1490 void NetworkQualityEstimator::AddNetworkQualitiesCacheObserver( |
| 1516 nqe::internal::NetworkQualityStore::NetworkQualitiesCacheObserver* | 1491 nqe::internal::NetworkQualityStore::NetworkQualitiesCacheObserver* |
| 1517 observer) { | 1492 observer) { |
| 1518 DCHECK(thread_checker_.CalledOnValidThread()); | 1493 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1519 network_quality_store_->AddNetworkQualitiesCacheObserver(observer); | 1494 network_quality_store_->AddNetworkQualitiesCacheObserver(observer); |
| 1520 } | 1495 } |
| 1521 | 1496 |
| 1522 void NetworkQualityEstimator::RemoveNetworkQualitiesCacheObserver( | 1497 void NetworkQualityEstimator::RemoveNetworkQualitiesCacheObserver( |
| 1523 nqe::internal::NetworkQualityStore::NetworkQualitiesCacheObserver* | 1498 nqe::internal::NetworkQualityStore::NetworkQualitiesCacheObserver* |
| 1524 observer) { | 1499 observer) { |
| 1525 DCHECK(thread_checker_.CalledOnValidThread()); | 1500 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1526 network_quality_store_->RemoveNetworkQualitiesCacheObserver(observer); | 1501 network_quality_store_->RemoveNetworkQualitiesCacheObserver(observer); |
| 1527 } | 1502 } |
| 1528 | 1503 |
| 1529 void NetworkQualityEstimator::OnPrefsRead( | 1504 void NetworkQualityEstimator::OnPrefsRead( |
| 1530 const std::map<nqe::internal::NetworkID, | 1505 const std::map<nqe::internal::NetworkID, |
| 1531 nqe::internal::CachedNetworkQuality> read_prefs) { | 1506 nqe::internal::CachedNetworkQuality> read_prefs) { |
| 1532 DCHECK(thread_checker_.CalledOnValidThread()); | 1507 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1533 UMA_HISTOGRAM_COUNTS("NQE.Prefs.ReadSize", read_prefs.size()); | 1508 UMA_HISTOGRAM_COUNTS("NQE.Prefs.ReadSize", read_prefs.size()); |
| 1534 // TODO(tbansal): crbug.com/490870. Incorporate the network quality into the | 1509 // TODO(tbansal): crbug.com/490870. Incorporate the network quality into the |
| 1535 // current estimates. | 1510 // current estimates. |
| 1536 } | 1511 } |
| 1537 | 1512 |
| 1538 } // namespace net | 1513 } // namespace net |
| OLD | NEW |