From b658f3880af6a20f40c4f1bbeb23e61238b1d02a Mon Sep 17 00:00:00 2001 From: tbansal Date: Wed, 19 Aug 2015 14:27:49 -0700 Subject: [PATCH] Record accuracy rate for Lo-Fi. Records false positive, false negative, true positive, true negative counts for Lo-Fi network quality prediction. The counts are recorded even if the LoFi state actually did not change because of hysteresis. Also, added one more API to NQE. BUG=516484 Review URL: https://codereview.chromium.org/1287833002 Cr-Commit-Position: refs/heads/master@{#344321} --- .../core/browser/data_reduction_proxy_config.cc | 182 ++++++++++++++++++--- .../core/browser/data_reduction_proxy_config.h | 33 +++- .../data_reduction_proxy_config_unittest.cc | 107 +++++++++++- net/base/network_quality_estimator.cc | 16 +- net/base/network_quality_estimator.h | 16 +- net/base/network_quality_estimator_unittest.cc | 13 +- tools/metrics/histograms/histograms.xml | 23 +++ 7 files changed, 351 insertions(+), 39 deletions(-) diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc index 6ef86729fc77..146af5c18ede 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc @@ -13,7 +13,6 @@ #include "base/metrics/sparse_histogram.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" -#include "base/time/time.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_config_values.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h" @@ -78,24 +77,24 @@ bool FindProxyInList(const std::vector& proxy_list, return false; } -// Values of change in the state of Auto Lo-Fi request headers. -// Possible Lo-Fi headers are: empty (""), low ("low"). -// This enum must remain synchronized with the enum of the same name in -// metrics/histograms/histograms.xml. -enum AutoLoFiRequestHeaderState { - AUTO_LOFI_REQUEST_HEADER_STATE_EMPTY_TO_EMPTY = 0, - AUTO_LOFI_REQUEST_HEADER_STATE_EMPTY_TO_LOW = 1, - AUTO_LOFI_REQUEST_HEADER_STATE_LOW_TO_EMPTY = 2, - AUTO_LOFI_REQUEST_HEADER_STATE_LOW_TO_LOW = 3, - AUTO_LOFI_REQUEST_HEADER_STATE_INDEX_BOUNDARY -}; - // Following UMA is plotted to measure how frequently Lo-Fi state changes. // Too frequent changes are undesirable. void RecordAutoLoFiRequestHeaderStateChange( net::NetworkChangeNotifier::ConnectionType connection_type, bool previous_header_low, bool current_header_low) { + // Auto Lo-Fi request header state changes. + // Possible Lo-Fi header directives are empty ("") and low ("q=low"). + // This enum must remain synchronized with the enum of the same name in + // metrics/histograms/histograms.xml. + enum AutoLoFiRequestHeaderState { + AUTO_LOFI_REQUEST_HEADER_STATE_EMPTY_TO_EMPTY = 0, + AUTO_LOFI_REQUEST_HEADER_STATE_EMPTY_TO_LOW = 1, + AUTO_LOFI_REQUEST_HEADER_STATE_LOW_TO_EMPTY = 2, + AUTO_LOFI_REQUEST_HEADER_STATE_LOW_TO_LOW = 3, + AUTO_LOFI_REQUEST_HEADER_STATE_INDEX_BOUNDARY + }; + AutoLoFiRequestHeaderState state; if (!previous_header_low) { if (current_header_low) @@ -244,7 +243,10 @@ DataReductionProxyConfig::DataReductionProxyConfig( network_quality_last_updated_(base::TimeTicks()), network_prohibitively_slow_(false), connection_type_(net::NetworkChangeNotifier::GetConnectionType()), - lofi_status_(LOFI_STATUS_TEMPORARILY_OFF) { + lofi_status_(LOFI_STATUS_TEMPORARILY_OFF), + last_main_frame_request_(base::TimeTicks::Now()), + network_quality_at_last_main_frame_request_( + NETWORK_QUALITY_AT_LAST_MAIN_FRAME_REQUEST_UNKNOWN) { DCHECK(configurator); DCHECK(event_creator); if (params::IsLoFiDisabledViaFlags()) @@ -391,6 +393,9 @@ bool DataReductionProxyConfig::AreProxiesBypassed( bool DataReductionProxyConfig::IsNetworkQualityProhibitivelySlow( const net::NetworkQualityEstimator* network_quality_estimator) { DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(IsIncludedInLoFiEnabledFieldTrial() || + IsIncludedInLoFiControlFieldTrial() || + params::IsLoFiSlowConnectionsOnlyViaFlags()); if (!network_quality_estimator) return false; @@ -403,6 +408,31 @@ bool DataReductionProxyConfig::IsNetworkQualityProhibitivelySlow( connection_type_ = net::NetworkChangeNotifier::GetConnectionType(); network_type_changed = true; } + + // Initialize to fastest RTT and fastest bandwidth. + base::TimeDelta rtt = base::TimeDelta(); + int32_t kbps = INT32_MAX; + + bool is_network_quality_available = + network_quality_estimator->GetRTTEstimate(&rtt) && + network_quality_estimator->GetDownlinkThroughputKbpsEstimate(&kbps); + + // True only if the network is currently estimated to be slower than the + // defined thresholds. + bool is_network_currently_slow = false; + + if (is_network_quality_available) { + // Network is slow if either the downlink bandwidth is too low or the RTT is + // too high. + is_network_currently_slow = + kbps < auto_lofi_maximum_kbps_ || rtt > auto_lofi_minimum_rtt_; + + network_quality_at_last_main_frame_request_ = + is_network_currently_slow + ? NETWORK_QUALITY_AT_LAST_MAIN_FRAME_REQUEST_SLOW + : NETWORK_QUALITY_AT_LAST_MAIN_FRAME_REQUEST_NOT_SLOW; + } + // Return the cached entry if the last update was within the hysteresis // duration and if the connection type has not changed. if (!network_type_changed && !network_quality_last_updated_.is_null() && @@ -413,19 +443,10 @@ bool DataReductionProxyConfig::IsNetworkQualityProhibitivelySlow( network_quality_last_updated_ = base::TimeTicks::Now(); - // Initialize to fastest RTT and fastest bandwidth. - base::TimeDelta rtt = base::TimeDelta(); - int32_t kbps = INT32_MAX; - - if (!network_quality_estimator->GetRTTEstimate(&rtt) || - !network_quality_estimator->GetDownlinkThroughputKbpsEstimate(&kbps)) { + if (!is_network_quality_available) return false; - } - // Network is prohibitvely slow if either the downlink bandwidth is too low - // or the RTT is too high. - network_prohibitively_slow_ = - kbps < auto_lofi_maximum_kbps_ || rtt > auto_lofi_minimum_rtt_; + network_prohibitively_slow_ = is_network_currently_slow; return network_prohibitively_slow_; } @@ -745,11 +766,122 @@ void DataReductionProxyConfig::SetLoFiModeOff() { lofi_status_ = LOFI_STATUS_OFF; } +void DataReductionProxyConfig::RecordAutoLoFiAccuracyRate( + const net::NetworkQualityEstimator* network_quality_estimator) const { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(network_quality_estimator); + DCHECK(IsIncludedInLoFiEnabledFieldTrial()); + DCHECK_NE(network_quality_at_last_main_frame_request_, + NETWORK_QUALITY_AT_LAST_MAIN_FRAME_REQUEST_UNKNOWN); + + base::TimeDelta rtt_since_last_page_load; + if (!network_quality_estimator->GetRecentMedianRTT( + last_main_frame_request_, &rtt_since_last_page_load)) { + return; + } + int32_t downstream_throughput_kbps; + if (!network_quality_estimator->GetRecentMedianDownlinkThroughputKbps( + last_main_frame_request_, &downstream_throughput_kbps)) { + return; + } + + // Values of Auto Lo-Fi accuracy. + // This enum must remain synchronized with the enum of the same name in + // metrics/histograms/histograms.xml. + enum AutoLoFiAccuracy { + AUTO_LOFI_ACCURACY_ESTIMATED_SLOW_ACTUAL_SLOW = 0, + AUTO_LOFI_ACCURACY_ESTIMATED_SLOW_ACTUAL_NOT_SLOW = 1, + AUTO_LOFI_ACCURACY_ESTIMATED_NOT_SLOW_ACTUAL_SLOW = 2, + AUTO_LOFI_ACCURACY_ESTIMATED_NOT_SLOW_ACTUAL_NOT_SLOW = 3, + AUTO_LOFI_ACCURACY_INDEX_BOUNDARY + }; + + bool should_have_used_lofi = + rtt_since_last_page_load > auto_lofi_minimum_rtt_ || + downstream_throughput_kbps < auto_lofi_maximum_kbps_; + + AutoLoFiAccuracy accuracy = AUTO_LOFI_ACCURACY_INDEX_BOUNDARY; + + if (should_have_used_lofi) { + if (network_quality_at_last_main_frame_request_ == + NETWORK_QUALITY_AT_LAST_MAIN_FRAME_REQUEST_SLOW) { + accuracy = AUTO_LOFI_ACCURACY_ESTIMATED_SLOW_ACTUAL_SLOW; + } else if (network_quality_at_last_main_frame_request_ == + NETWORK_QUALITY_AT_LAST_MAIN_FRAME_REQUEST_NOT_SLOW) { + accuracy = AUTO_LOFI_ACCURACY_ESTIMATED_NOT_SLOW_ACTUAL_SLOW; + } else { + NOTREACHED(); + } + } else { + if (network_quality_at_last_main_frame_request_ == + NETWORK_QUALITY_AT_LAST_MAIN_FRAME_REQUEST_SLOW) { + accuracy = AUTO_LOFI_ACCURACY_ESTIMATED_SLOW_ACTUAL_NOT_SLOW; + } else if (network_quality_at_last_main_frame_request_ == + NETWORK_QUALITY_AT_LAST_MAIN_FRAME_REQUEST_NOT_SLOW) { + accuracy = AUTO_LOFI_ACCURACY_ESTIMATED_NOT_SLOW_ACTUAL_NOT_SLOW; + } else { + NOTREACHED(); + } + } + + switch (connection_type_) { + case net::NetworkChangeNotifier::CONNECTION_UNKNOWN: + UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.AutoLoFiAccuracy.Unknown", + accuracy, AUTO_LOFI_ACCURACY_INDEX_BOUNDARY); + break; + case net::NetworkChangeNotifier::CONNECTION_ETHERNET: + UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.AutoLoFiAccuracy.Ethernet", + accuracy, AUTO_LOFI_ACCURACY_INDEX_BOUNDARY); + break; + case net::NetworkChangeNotifier::CONNECTION_WIFI: + UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.AutoLoFiAccuracy.WiFi", + accuracy, AUTO_LOFI_ACCURACY_INDEX_BOUNDARY); + break; + case net::NetworkChangeNotifier::CONNECTION_2G: + UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.AutoLoFiAccuracy.2G", + accuracy, AUTO_LOFI_ACCURACY_INDEX_BOUNDARY); + break; + case net::NetworkChangeNotifier::CONNECTION_3G: + UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.AutoLoFiAccuracy.3G", + accuracy, AUTO_LOFI_ACCURACY_INDEX_BOUNDARY); + break; + case net::NetworkChangeNotifier::CONNECTION_4G: + UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.AutoLoFiAccuracy.4G", + accuracy, AUTO_LOFI_ACCURACY_INDEX_BOUNDARY); + break; + case net::NetworkChangeNotifier::CONNECTION_NONE: + UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.AutoLoFiAccuracy.None", + accuracy, AUTO_LOFI_ACCURACY_INDEX_BOUNDARY); + break; + case net::NetworkChangeNotifier::CONNECTION_BLUETOOTH: + UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.AutoLoFiAccuracy.Bluetooth", + accuracy, AUTO_LOFI_ACCURACY_INDEX_BOUNDARY); + break; + default: + NOTREACHED(); + break; + } +} + void DataReductionProxyConfig::UpdateLoFiStatusOnMainFrameRequest( bool user_temporarily_disabled_lofi, const net::NetworkQualityEstimator* network_quality_estimator) { DCHECK(thread_checker_.CalledOnValidThread()); + // Record Lo-Fi accuracy rate only if the session is Lo-Fi enabled + // field trial, and the user has not enabled Lo-Fi on slow connections + // via flags. + if (network_quality_estimator && + network_quality_at_last_main_frame_request_ != + NETWORK_QUALITY_AT_LAST_MAIN_FRAME_REQUEST_UNKNOWN && + IsIncludedInLoFiEnabledFieldTrial() && + !params::IsLoFiSlowConnectionsOnlyViaFlags()) { + RecordAutoLoFiAccuracyRate(network_quality_estimator); + } + last_main_frame_request_ = base::TimeTicks::Now(); + network_quality_at_last_main_frame_request_ = + NETWORK_QUALITY_AT_LAST_MAIN_FRAME_REQUEST_UNKNOWN; + // If Lo-Fi has been permanently turned off, its status can't change. if (lofi_status_ == LOFI_STATUS_OFF) return; diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h index c85f6d1a5238..16f62c51412f 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h @@ -15,6 +15,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/threading/thread_checker.h" +#include "base/time/time.h" #include "net/base/net_errors.h" #include "net/base/net_util.h" #include "net/base/network_change_notifier.h" @@ -24,10 +25,6 @@ class GURL; -namespace base { -class TimeDelta; -} - namespace net { class HostPortPair; class NetLog; @@ -269,6 +266,15 @@ class DataReductionProxyConfig FRIEND_TEST_ALL_PREFIXES(DataReductionProxyConfigTest, AutoLoFiParams); FRIEND_TEST_ALL_PREFIXES(DataReductionProxyConfigTest, AutoLoFiParamsSlowConnectionsFlag); + FRIEND_TEST_ALL_PREFIXES(DataReductionProxyConfigTest, AutoLoFiAccuracy); + + // Values of the estimated network quality at the beginning of the most + // recent main frame request. + enum NetworkQualityAtLastMainFrameRequest { + NETWORK_QUALITY_AT_LAST_MAIN_FRAME_REQUEST_UNKNOWN, + NETWORK_QUALITY_AT_LAST_MAIN_FRAME_REQUEST_SLOW, + NETWORK_QUALITY_AT_LAST_MAIN_FRAME_REQUEST_NOT_SLOW + }; // NetworkChangeNotifier::IPAddressObserver: void OnIPAddressChanged() override; @@ -325,7 +331,7 @@ class DataReductionProxyConfig // Auto Lo-Fi field trial parameters OR if the expected round trip time is // higher than the one specified in the Auto Lo-Fi field trial parameters. // |network_quality_estimator| may be NULL. - // Virtualized for unit testing. + // Virtualized for unit testing. Should be called only on main frame loads. virtual bool IsNetworkQualityProhibitivelySlow( const net::NetworkQualityEstimator* network_quality_estimator); @@ -333,6 +339,10 @@ class DataReductionProxyConfig // Proxy header based on the value of |lofi_status|. static bool ShouldUseLoFiHeaderForRequests(LoFiStatus lofi_status); + // Records Lo-Fi accuracy metric. Should be called only on main frame loads. + void RecordAutoLoFiAccuracyRate( + const net::NetworkQualityEstimator* network_quality_estimator) const; + scoped_ptr secure_proxy_checker_; // Indicates if the secure Data Reduction Proxy can be used or not. @@ -379,7 +389,9 @@ class DataReductionProxyConfig base::TimeTicks network_quality_last_updated_; // True iff the network was determined to be prohibitively slow when the - // network quality was last updated (most recent main frame request). + // network quality was last updated. This happens on main frame request, and + // not more than once in any window of duration shorter than + // |auto_lofi_hysteresis_|. bool network_prohibitively_slow_; // Set to the connection type reported by NetworkChangeNotifier when the @@ -390,6 +402,15 @@ class DataReductionProxyConfig // The value changes only on main frame load. LoFiStatus lofi_status_; + // Timestamp when the most recent main frame request started. + base::TimeTicks last_main_frame_request_; + + // Holds the estimated network quality at the beginning of the most recent + // main frame request. This should be used only for the purpose of recording + // Lo-Fi accuracy UMA. + NetworkQualityAtLastMainFrameRequest + network_quality_at_last_main_frame_request_; + DISALLOW_COPY_AND_ASSIGN(DataReductionProxyConfig); }; diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc index d8babe258501..6bf0dfb65e02 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc @@ -4,12 +4,15 @@ #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h" +#include + #include #include #include "base/command_line.h" #include "base/metrics/field_trial.h" #include "base/strings/safe_sprintf.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/test/histogram_tester.h" #include "base/time/time.h" @@ -989,7 +992,8 @@ class TestNetworkQualityEstimator : public net::NetworkQualityEstimator { : NetworkQualityEstimator(scoped_ptr(), variation_params), rtt_estimate_(base::TimeDelta()), - downstream_throughput_kbps_estimate_(INT32_MAX) {} + downstream_throughput_kbps_estimate_(INT32_MAX), + rtt_since_(base::TimeDelta()) {} ~TestNetworkQualityEstimator() override {} @@ -1007,10 +1011,31 @@ class TestNetworkQualityEstimator : public net::NetworkQualityEstimator { void SetRTT(base::TimeDelta rtt) { rtt_estimate_ = rtt; } + bool GetRecentMedianRTT(const base::TimeTicks& begin_timestamp, + base::TimeDelta* rtt) const override { + DCHECK(rtt); + *rtt = rtt_since_; + return true; + } + + bool GetRecentMedianDownlinkThroughputKbps( + const base::TimeTicks& begin_timestamp, + int32_t* kbps) const override { + DCHECK(kbps); + *kbps = INT32_MAX; + return true; + } + + void SetMedianRTTSince(const base::TimeDelta& rtt_since) { + rtt_since_ = rtt_since; + } + private: // Estimate of the quality of the network. base::TimeDelta rtt_estimate_; int32_t downstream_throughput_kbps_estimate_; + + base::TimeDelta rtt_since_; }; TEST_F(DataReductionProxyConfigTest, AutoLoFiParams) { @@ -1174,4 +1199,84 @@ TEST_F(DataReductionProxyConfigTest, AutoLoFiParamsSlowConnectionsFlag) { &test_network_quality_estimator)); } +// Tests if metrics for LoFi accuracy are recorded properly. +TEST_F(DataReductionProxyConfigTest, AutoLoFiAccuracy) { + base::HistogramTester histogram_tester; + + DataReductionProxyConfig config(nullptr, nullptr, configurator(), + event_creator()); + variations::testing::ClearAllVariationParams(); + std::map variation_params; + + int expected_rtt_msec = 120; + int expected_hysteresis_sec = 360; + + variation_params["rtt_msec"] = base::IntToString(expected_rtt_msec); + variation_params["hysteresis_period_seconds"] = + base::IntToString(expected_hysteresis_sec); + + ASSERT_TRUE(variations::AssociateVariationParams( + params::GetLoFiFieldTrialName(), "Enabled", variation_params)); + + base::FieldTrialList field_trial_list(nullptr); + base::FieldTrialList::CreateFieldTrial(params::GetLoFiFieldTrialName(), + "Enabled"); + config.PopulateAutoLoFiParams(); + + std::map network_quality_estimator_params; + TestNetworkQualityEstimator test_network_quality_estimator( + network_quality_estimator_params); + + // RTT is higher than threshold. Network is slow. + // Network was predicted to be slow and actually was slow. + test_network_quality_estimator.SetRTT( + base::TimeDelta::FromMilliseconds(expected_rtt_msec + 1)); + test_network_quality_estimator.SetMedianRTTSince( + base::TimeDelta::FromMilliseconds(expected_rtt_msec + 1)); + EXPECT_TRUE(config.IsNetworkQualityProhibitivelySlow( + &test_network_quality_estimator)); + config.RecordAutoLoFiAccuracyRate(&test_network_quality_estimator); + histogram_tester.ExpectBucketCount( + "DataReductionProxy.AutoLoFiAccuracy.Unknown", 0, 1); + + // Network was predicted to be slow but actually was not slow. + test_network_quality_estimator.SetMedianRTTSince( + base::TimeDelta::FromMilliseconds(expected_rtt_msec - 1)); + EXPECT_TRUE(config.IsNetworkQualityProhibitivelySlow( + &test_network_quality_estimator)); + config.RecordAutoLoFiAccuracyRate(&test_network_quality_estimator); + histogram_tester.ExpectBucketCount( + "DataReductionProxy.AutoLoFiAccuracy.Unknown", 1, 1); + + config.network_quality_last_updated_ = + base::TimeTicks::Now() - + base::TimeDelta::FromSeconds(expected_hysteresis_sec + 1); + + // Network was predicted to be not slow but actually was slow. + test_network_quality_estimator.SetRTT( + base::TimeDelta::FromMilliseconds(expected_rtt_msec - 1)); + test_network_quality_estimator.SetMedianRTTSince( + base::TimeDelta::FromMilliseconds(expected_rtt_msec + 1)); + EXPECT_FALSE(config.IsNetworkQualityProhibitivelySlow( + &test_network_quality_estimator)); + config.RecordAutoLoFiAccuracyRate(&test_network_quality_estimator); + histogram_tester.ExpectBucketCount( + "DataReductionProxy.AutoLoFiAccuracy.Unknown", 2, 1); + + // Network was predicted to be not slow but actually was not slow. + test_network_quality_estimator.SetMedianRTTSince( + base::TimeDelta::FromMilliseconds(expected_rtt_msec - 1)); + EXPECT_FALSE(config.IsNetworkQualityProhibitivelySlow( + &test_network_quality_estimator)); + config.RecordAutoLoFiAccuracyRate(&test_network_quality_estimator); + histogram_tester.ExpectBucketCount( + "DataReductionProxy.AutoLoFiAccuracy.Unknown", 3, 1); + + // Make sure that all buckets contain exactly one value. + for (size_t bucket = 0; bucket < 4; ++bucket) { + histogram_tester.ExpectBucketCount( + "DataReductionProxy.AutoLoFiAccuracy.Unknown", bucket, 1); + } +} + } // namespace data_reduction_proxy diff --git a/net/base/network_quality_estimator.cc b/net/base/network_quality_estimator.cc index e7401de51838..fdd2212adfb1 100644 --- a/net/base/network_quality_estimator.cc +++ b/net/base/network_quality_estimator.cc @@ -508,6 +508,8 @@ void NetworkQualityEstimator::OnConnectionTypeChanged( } bool NetworkQualityEstimator::GetRTTEstimate(base::TimeDelta* rtt) const { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(rtt); if (rtt_msec_observations_.Size() == 0) { *rtt = InvalidRTT(); return false; @@ -518,6 +520,8 @@ bool NetworkQualityEstimator::GetRTTEstimate(base::TimeDelta* rtt) const { bool NetworkQualityEstimator::GetDownlinkThroughputKbpsEstimate( int32_t* kbps) const { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(kbps); if (downstream_throughput_kbps_observations_.Size() == 0) { *kbps = kInvalidThroughput; return false; @@ -526,14 +530,24 @@ bool NetworkQualityEstimator::GetDownlinkThroughputKbpsEstimate( return (*kbps != kInvalidThroughput); } -bool NetworkQualityEstimator::GetMedianRTTSince( +bool NetworkQualityEstimator::GetRecentMedianRTT( const base::TimeTicks& begin_timestamp, base::TimeDelta* rtt) const { DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(rtt); *rtt = GetRTTEstimateInternal(begin_timestamp, 50); return (*rtt != InvalidRTT()); } +bool NetworkQualityEstimator::GetRecentMedianDownlinkThroughputKbps( + const base::TimeTicks& begin_timestamp, + int32_t* kbps) const { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(kbps); + *kbps = GetDownlinkThroughputKbpsEstimateInternal(begin_timestamp, 50); + return (*kbps != kInvalidThroughput); +} + NetworkQualityEstimator::Observation::Observation(int32_t value, base::TimeTicks timestamp) : value(value), timestamp(timestamp) { diff --git a/net/base/network_quality_estimator.h b/net/base/network_quality_estimator.h index b899fa54b0d2..a32264f89703 100644 --- a/net/base/network_quality_estimator.h +++ b/net/base/network_quality_estimator.h @@ -47,12 +47,12 @@ class NET_EXPORT_PRIVATE NetworkQualityEstimator ~NetworkQualityEstimator() override; // Returns true if RTT is available and sets |rtt| to estimated RTT. - // Virtualized for testing. + // Virtualized for testing. |rtt| should not be null. virtual bool GetRTTEstimate(base::TimeDelta* rtt) const; // Returns true if downlink throughput is available and sets |kbps| to // estimated downlink throughput (in Kilobits per second). - // Virtualized for testing. + // Virtualized for testing. |kbps| should not be null. virtual bool GetDownlinkThroughputKbpsEstimate(int32_t* kbps) const; // Notifies NetworkQualityEstimator that the response header of |request| has @@ -65,8 +65,16 @@ class NET_EXPORT_PRIVATE NetworkQualityEstimator // Returns true if median RTT is available and sets |rtt| to the median of // RTT observations since |begin_timestamp|. - bool GetMedianRTTSince(const base::TimeTicks& begin_timestamp, - base::TimeDelta* rtt) const; + // Virtualized for testing. |rtt| should not be null. + virtual bool GetRecentMedianRTT(const base::TimeTicks& begin_timestamp, + base::TimeDelta* rtt) const; + + // Returns true if median downstream throughput is available and sets |kbps| + // to the median of downstream Kbps observations since |begin_timestamp|. + // Virtualized for testing. |kbps| should not be null. + virtual bool GetRecentMedianDownlinkThroughputKbps( + const base::TimeTicks& begin_timestamp, + int32_t* kbps) const; protected: // NetworkID is used to uniquely identify a network. diff --git a/net/base/network_quality_estimator_unittest.cc b/net/base/network_quality_estimator_unittest.cc index 6ebf40fbd704..6790bb7637b6 100644 --- a/net/base/network_quality_estimator_unittest.cc +++ b/net/base/network_quality_estimator_unittest.cc @@ -4,6 +4,8 @@ #include "net/base/network_quality_estimator.h" +#include + #include #include @@ -637,10 +639,17 @@ TEST(NetworkQualityEstimatorTest, TestGetMedianRTTSince) { NetworkQualityEstimator::Observation(100, now)); base::TimeDelta rtt; - EXPECT_FALSE(estimator.GetMedianRTTSince( + EXPECT_FALSE(estimator.GetRecentMedianRTT( now + base::TimeDelta::FromSeconds(10), &rtt)); - EXPECT_TRUE(estimator.GetMedianRTTSince(now, &rtt)); + EXPECT_TRUE(estimator.GetRecentMedianRTT(now, &rtt)); EXPECT_EQ(100, rtt.InMilliseconds()); + + int32_t downstream_throughput_kbps; + EXPECT_FALSE(estimator.GetRecentMedianDownlinkThroughputKbps( + now + base::TimeDelta::FromSeconds(10), &downstream_throughput_kbps)); + EXPECT_TRUE(estimator.GetRecentMedianDownlinkThroughputKbps( + now, &downstream_throughput_kbps)); + EXPECT_EQ(100, downstream_throughput_kbps); } } // namespace net diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 37e1aa4c90e8..3e7c5c170d39 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -4997,6 +4997,17 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries. + + bengr@chromium.org + tbansal@chromium.org + + Counts the accuracy of estimated network quality when using Lo-Fi. Counters + are incremented when a main frame URL request is handled by Data Reduction + Proxy and session was in Auto Lo-Fi enabled field trial. + + + tbansal@chromium.org @@ -54344,6 +54355,17 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries. + + + + + + + @@ -73421,6 +73443,7 @@ To add a new entry, add it with any value and run test to compute valid value. + -- 2.11.4.GIT