Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(713)

Side by Side Diff: net/nqe/network_quality_estimator.cc

Issue 2113363002: NQE: Add Transport RTT based GetECT algorithm (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/nqe/network_quality_estimator.h ('k') | net/nqe/network_quality_estimator_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 // parameter for Wi-Fi would be "WiFi.DefaultMedianKbps". 87 // parameter for Wi-Fi would be "WiFi.DefaultMedianKbps".
88 const char kDefaultKbpsObservationSuffix[] = ".DefaultMedianKbps"; 88 const char kDefaultKbpsObservationSuffix[] = ".DefaultMedianKbps";
89 89
90 // Suffix of the name of the variation parameter that contains the threshold 90 // Suffix of the name of the variation parameter that contains the threshold
91 // HTTP RTTs (in milliseconds) for different effective connection types. 91 // HTTP RTTs (in milliseconds) for different effective connection types.
92 // Complete name of the variation parameter would be 92 // Complete name of the variation parameter would be
93 // |EffectiveConnectionType|.|kThresholdURLRTTMsecSuffix|. 93 // |EffectiveConnectionType|.|kThresholdURLRTTMsecSuffix|.
94 const char kThresholdURLRTTMsecSuffix[] = ".ThresholdMedianHttpRTTMsec"; 94 const char kThresholdURLRTTMsecSuffix[] = ".ThresholdMedianHttpRTTMsec";
95 95
96 // Suffix of the name of the variation parameter that contains the threshold 96 // Suffix of the name of the variation parameter that contains the threshold
97 // transport RTTs (in milliseconds) for different effective connection types.
98 // Complete name of the variation parameter would be
99 // |EffectiveConnectionType|.|kThresholdTransportRTTMsecSuffix|.
100 const char kThresholdTransportRTTMsecSuffix[] =
101 ".ThresholdMedianTransportRTTMsec";
102
103 // Suffix of the name of the variation parameter that contains the threshold
97 // downlink throughput (in kbps) for different effective connection types. 104 // downlink throughput (in kbps) for different effective connection types.
98 // Complete name of the variation parameter would be 105 // Complete name of the variation parameter would be
99 // |EffectiveConnectionType|.|kThresholdKbpsSuffix|. 106 // |EffectiveConnectionType|.|kThresholdKbpsSuffix|.
100 const char kThresholdKbpsSuffix[] = ".ThresholdMedianKbps"; 107 const char kThresholdKbpsSuffix[] = ".ThresholdMedianKbps";
101 108
102 // Computes and returns the weight multiplier per second. 109 // Computes and returns the weight multiplier per second.
103 // |variation_params| is the map containing all field trial parameters 110 // |variation_params| is the map containing all field trial parameters
104 // related to NetworkQualityEstimator field trial. 111 // related to NetworkQualityEstimator field trial.
105 double GetWeightMultiplierPerSecond( 112 double GetWeightMultiplierPerSecond(
106 const std::map<std::string, std::string>& variation_params) { 113 const std::map<std::string, std::string>& variation_params) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 false, 228 false,
222 false) {} 229 false) {}
223 230
224 NetworkQualityEstimator::NetworkQualityEstimator( 231 NetworkQualityEstimator::NetworkQualityEstimator(
225 std::unique_ptr<ExternalEstimateProvider> external_estimates_provider, 232 std::unique_ptr<ExternalEstimateProvider> external_estimates_provider,
226 const std::map<std::string, std::string>& variation_params, 233 const std::map<std::string, std::string>& variation_params,
227 bool use_local_host_requests_for_tests, 234 bool use_local_host_requests_for_tests,
228 bool use_smaller_responses_for_tests) 235 bool use_smaller_responses_for_tests)
229 : algorithm_name_to_enum_({{"HttpRTTAndDownstreamThroughput", 236 : algorithm_name_to_enum_({{"HttpRTTAndDownstreamThroughput",
230 EffectiveConnectionTypeAlgorithm:: 237 EffectiveConnectionTypeAlgorithm::
231 HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT}}), 238 HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT},
239 {"TransportRTTOrDownstreamThroughput",
240 EffectiveConnectionTypeAlgorithm::
241 TRANSPORT_RTT_OR_DOWNSTREAM_THROUGHOUT}}),
232 use_localhost_requests_(use_local_host_requests_for_tests), 242 use_localhost_requests_(use_local_host_requests_for_tests),
233 use_small_responses_(use_smaller_responses_for_tests), 243 use_small_responses_(use_smaller_responses_for_tests),
234 weight_multiplier_per_second_( 244 weight_multiplier_per_second_(
235 GetWeightMultiplierPerSecond(variation_params)), 245 GetWeightMultiplierPerSecond(variation_params)),
236 effective_connection_type_algorithm_( 246 effective_connection_type_algorithm_(
237 algorithm_name_to_enum_.find(GetEffectiveConnectionTypeAlgorithm( 247 algorithm_name_to_enum_.find(GetEffectiveConnectionTypeAlgorithm(
238 variation_params)) == algorithm_name_to_enum_.end() 248 variation_params)) == algorithm_name_to_enum_.end()
239 ? kDefaultEffectiveConnectionTypeAlgorithm 249 ? kDefaultEffectiveConnectionTypeAlgorithm
240 : algorithm_name_to_enum_ 250 : algorithm_name_to_enum_
241 .find(GetEffectiveConnectionTypeAlgorithm(variation_params)) 251 .find(GetEffectiveConnectionTypeAlgorithm(variation_params))
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 continue; 379 continue;
370 380
371 std::string connection_type_name = std::string( 381 std::string connection_type_name = std::string(
372 GetNameForEffectiveConnectionType(effective_connection_type)); 382 GetNameForEffectiveConnectionType(effective_connection_type));
373 383
374 int32_t variations_value = kMinimumRTTVariationParameterMsec - 1; 384 int32_t variations_value = kMinimumRTTVariationParameterMsec - 1;
375 if (GetValueForVariationParam( 385 if (GetValueForVariationParam(
376 variation_params, connection_type_name + kThresholdURLRTTMsecSuffix, 386 variation_params, connection_type_name + kThresholdURLRTTMsecSuffix,
377 &variations_value) && 387 &variations_value) &&
378 variations_value >= kMinimumRTTVariationParameterMsec) { 388 variations_value >= kMinimumRTTVariationParameterMsec) {
379 base::TimeDelta rtt(base::TimeDelta::FromMilliseconds(variations_value)); 389 connection_thresholds_[i].set_http_rtt(
380 connection_thresholds_[i] = nqe::internal::NetworkQuality( 390 base::TimeDelta(base::TimeDelta::FromMilliseconds(variations_value)));
381 rtt, connection_thresholds_[i].transport_rtt(),
382 connection_thresholds_[i].downstream_throughput_kbps());
383 391
384 // Verify that the RTT values are in decreasing order as the network 392 // Verify that the RTT values are in decreasing order as the network
385 // quality improves. 393 // quality improves.
386 DCHECK(i == 0 || 394 DCHECK(i == 0 ||
387 connection_thresholds_[i - 1].http_rtt() == 395 connection_thresholds_[i - 1].http_rtt() ==
388 nqe::internal::InvalidRTT() || 396 nqe::internal::InvalidRTT() ||
389 rtt <= connection_thresholds_[i - 1].http_rtt()); 397 connection_thresholds_[i].http_rtt() <=
398 connection_thresholds_[i - 1].http_rtt());
399 }
400
401 variations_value = kMinimumRTTVariationParameterMsec - 1;
402 if (GetValueForVariationParam(
403 variation_params,
404 connection_type_name + kThresholdTransportRTTMsecSuffix,
405 &variations_value) &&
406 variations_value >= kMinimumRTTVariationParameterMsec) {
407 connection_thresholds_[i].set_transport_rtt(
408 base::TimeDelta(base::TimeDelta::FromMilliseconds(variations_value)));
409
410 // Verify that the transport RTT values are in decreasing order as the
411 // network quality improves.
412 DCHECK(i == 0 ||
413 connection_thresholds_[i - 1].transport_rtt() ==
414 nqe::internal::InvalidRTT() ||
415 connection_thresholds_[i].transport_rtt() <=
416 connection_thresholds_[i - 1].transport_rtt());
390 } 417 }
391 418
392 variations_value = kMinimumThroughputVariationParameterKbps - 1; 419 variations_value = kMinimumThroughputVariationParameterKbps - 1;
393 if (GetValueForVariationParam(variation_params, 420 if (GetValueForVariationParam(variation_params,
394 connection_type_name + kThresholdKbpsSuffix, 421 connection_type_name + kThresholdKbpsSuffix,
395 &variations_value) && 422 &variations_value) &&
396 variations_value >= kMinimumThroughputVariationParameterKbps) { 423 variations_value >= kMinimumThroughputVariationParameterKbps) {
397 int32_t throughput_kbps = variations_value; 424 connection_thresholds_[i].set_downstream_throughput_kbps(
398 connection_thresholds_[i] = nqe::internal::NetworkQuality( 425 variations_value);
399 connection_thresholds_[i].http_rtt(),
400 connection_thresholds_[i].transport_rtt(), throughput_kbps);
401 426
402 // Verify that the throughput values are in increasing order as the 427 // Verify that the throughput values are in increasing order as the
403 // network quality improves. 428 // network quality improves.
404 DCHECK(i == 0 || 429 DCHECK(i == 0 ||
405 connection_thresholds_[i - 1].downstream_throughput_kbps() == 430 connection_thresholds_[i - 1].downstream_throughput_kbps() ==
406 kMinimumThroughputVariationParameterKbps || 431 kMinimumThroughputVariationParameterKbps ||
407 throughput_kbps >= 432 connection_thresholds_[i].downstream_throughput_kbps() >=
408 connection_thresholds_[i - 1].downstream_throughput_kbps()); 433 connection_thresholds_[i - 1].downstream_throughput_kbps());
409 } 434 }
410 } 435 }
411 } 436 }
412 437
413 void NetworkQualityEstimator::AddDefaultEstimates() { 438 void NetworkQualityEstimator::AddDefaultEstimates() {
414 DCHECK(thread_checker_.CalledOnValidThread()); 439 DCHECK(thread_checker_.CalledOnValidThread());
415 440
416 if (default_observations_[current_network_id_.type].http_rtt() != 441 if (default_observations_[current_network_id_.type].http_rtt() !=
417 nqe::internal::InvalidRTT()) { 442 nqe::internal::InvalidRTT()) {
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 return GetRecentEffectiveConnectionType(base::TimeTicks()); 938 return GetRecentEffectiveConnectionType(base::TimeTicks());
914 } 939 }
915 940
916 NetworkQualityEstimator::EffectiveConnectionType 941 NetworkQualityEstimator::EffectiveConnectionType
917 NetworkQualityEstimator::GetRecentEffectiveConnectionType( 942 NetworkQualityEstimator::GetRecentEffectiveConnectionType(
918 const base::TimeTicks& start_time) const { 943 const base::TimeTicks& start_time) const {
919 DCHECK(thread_checker_.CalledOnValidThread()); 944 DCHECK(thread_checker_.CalledOnValidThread());
920 945
921 if (effective_connection_type_algorithm_ == 946 if (effective_connection_type_algorithm_ ==
922 EffectiveConnectionTypeAlgorithm::HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT) { 947 EffectiveConnectionTypeAlgorithm::HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT) {
923 return GetRecentEffectiveConnectionTypeHttpRTTAndDownstreamThroughput( 948 return GetRecentEffectiveConnectionTypeUsingMetrics(
924 start_time); 949 start_time, NetworkQualityEstimator::MetricUsage::
950 MUST_BE_USED /* http_rtt_metric */,
951 NetworkQualityEstimator::MetricUsage::
952 DO_NOT_USE /* transport_rtt_metric */,
953 NetworkQualityEstimator::MetricUsage::
954 MUST_BE_USED /* downstream_throughput_kbps_metric */);
955 }
956 if (effective_connection_type_algorithm_ ==
957 EffectiveConnectionTypeAlgorithm::
958 TRANSPORT_RTT_OR_DOWNSTREAM_THROUGHOUT) {
959 return GetRecentEffectiveConnectionTypeUsingMetrics(
960 start_time,
961 NetworkQualityEstimator::MetricUsage::DO_NOT_USE /* http_rtt_metric */,
962 NetworkQualityEstimator::MetricUsage::
963 USE_IF_AVAILABLE /* transport_rtt_metric */,
964 NetworkQualityEstimator::MetricUsage::
965 USE_IF_AVAILABLE /* downstream_throughput_kbps_metric */);
925 } 966 }
926 // Add additional algorithms here. 967 // Add additional algorithms here.
927 NOTREACHED(); 968 NOTREACHED();
928 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; 969 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
929 } 970 }
930 971
931 NetworkQualityEstimator::EffectiveConnectionType NetworkQualityEstimator:: 972 NetworkQualityEstimator::EffectiveConnectionType
932 GetRecentEffectiveConnectionTypeHttpRTTAndDownstreamThroughput( 973 NetworkQualityEstimator::GetRecentEffectiveConnectionTypeUsingMetrics(
933 const base::TimeTicks& start_time) const { 974 const base::TimeTicks& start_time,
975 NetworkQualityEstimator::MetricUsage http_rtt_metric,
976 NetworkQualityEstimator::MetricUsage transport_rtt_metric,
977 NetworkQualityEstimator::MetricUsage downstream_throughput_kbps_metric)
978 const {
934 DCHECK(thread_checker_.CalledOnValidThread()); 979 DCHECK(thread_checker_.CalledOnValidThread());
935 980
936 // If the device is currently offline, then return 981 // If the device is currently offline, then return
937 // EFFECTIVE_CONNECTION_TYPE_OFFLINE. 982 // EFFECTIVE_CONNECTION_TYPE_OFFLINE.
938 if (GetCurrentNetworkID().type == NetworkChangeNotifier::CONNECTION_NONE) 983 if (GetCurrentNetworkID().type == NetworkChangeNotifier::CONNECTION_NONE)
939 return EFFECTIVE_CONNECTION_TYPE_OFFLINE; 984 return EFFECTIVE_CONNECTION_TYPE_OFFLINE;
940 985
941 base::TimeDelta http_rtt = nqe::internal::InvalidRTT(); 986 base::TimeDelta http_rtt = nqe::internal::InvalidRTT();
942 if (!GetRecentHttpRTTMedian(start_time, &http_rtt)) 987 if (http_rtt_metric != NetworkQualityEstimator::MetricUsage::DO_NOT_USE &&
988 !GetRecentHttpRTTMedian(start_time, &http_rtt)) {
943 http_rtt = nqe::internal::InvalidRTT(); 989 http_rtt = nqe::internal::InvalidRTT();
990 }
991
992 base::TimeDelta transport_rtt = nqe::internal::InvalidRTT();
993 if (transport_rtt_metric !=
994 NetworkQualityEstimator::MetricUsage::DO_NOT_USE &&
995 !GetRecentTransportRTTMedian(start_time, &transport_rtt)) {
996 transport_rtt = nqe::internal::InvalidRTT();
997 }
944 998
945 int32_t kbps = nqe::internal::kInvalidThroughput; 999 int32_t kbps = nqe::internal::kInvalidThroughput;
946 if (!GetRecentMedianDownlinkThroughputKbps(start_time, &kbps)) 1000 if (downstream_throughput_kbps_metric !=
1001 NetworkQualityEstimator::MetricUsage::DO_NOT_USE &&
1002 !GetRecentMedianDownlinkThroughputKbps(start_time, &kbps)) {
947 kbps = nqe::internal::kInvalidThroughput; 1003 kbps = nqe::internal::kInvalidThroughput;
1004 }
948 1005
949 if (http_rtt == nqe::internal::InvalidRTT() || 1006 if (http_rtt == nqe::internal::InvalidRTT() &&
950 kbps == nqe::internal::kInvalidThroughput) { 1007 http_rtt_metric == NetworkQualityEstimator::MetricUsage::MUST_BE_USED) {
951 // Quality of the current network is unknown.
952 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; 1008 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
953 } 1009 }
954 1010
1011 if (transport_rtt == nqe::internal::InvalidRTT() &&
1012 transport_rtt_metric ==
1013 NetworkQualityEstimator::MetricUsage::MUST_BE_USED) {
1014 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
1015 }
1016
1017 if (kbps == nqe::internal::kInvalidThroughput &&
1018 downstream_throughput_kbps_metric ==
1019 NetworkQualityEstimator::MetricUsage::MUST_BE_USED) {
1020 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
1021 }
1022
1023 if (http_rtt == nqe::internal::InvalidRTT() &&
1024 transport_rtt == nqe::internal::InvalidRTT() &&
1025 kbps == nqe::internal::kInvalidThroughput) {
1026 // None of the metrics are available.
1027 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
1028 }
1029
955 // Search from the slowest connection type to the fastest to find the 1030 // Search from the slowest connection type to the fastest to find the
956 // EffectiveConnectionType that best matches the current connection's 1031 // EffectiveConnectionType that best matches the current connection's
957 // performance. The match is done by comparing RTT and throughput. 1032 // performance. The match is done by comparing RTT and throughput.
958 for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) { 1033 for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) {
959 EffectiveConnectionType type = static_cast<EffectiveConnectionType>(i); 1034 EffectiveConnectionType type = static_cast<EffectiveConnectionType>(i);
960 if (i == EFFECTIVE_CONNECTION_TYPE_UNKNOWN) 1035 if (i == EFFECTIVE_CONNECTION_TYPE_UNKNOWN)
961 continue; 1036 continue;
962 bool estimated_http_rtt_is_higher_than_threshold = 1037
1038 const bool estimated_http_rtt_is_higher_than_threshold =
963 http_rtt != nqe::internal::InvalidRTT() && 1039 http_rtt != nqe::internal::InvalidRTT() &&
964 connection_thresholds_[i].http_rtt() != nqe::internal::InvalidRTT() && 1040 connection_thresholds_[i].http_rtt() != nqe::internal::InvalidRTT() &&
965 http_rtt >= connection_thresholds_[i].http_rtt(); 1041 http_rtt >= connection_thresholds_[i].http_rtt();
966 bool estimated_throughput_is_lower_than_threshold = 1042
1043 const bool estimated_transport_rtt_is_higher_than_threshold =
1044 transport_rtt != nqe::internal::InvalidRTT() &&
1045 connection_thresholds_[i].transport_rtt() !=
1046 nqe::internal::InvalidRTT() &&
1047 transport_rtt >= connection_thresholds_[i].transport_rtt();
1048
1049 const bool estimated_throughput_is_lower_than_threshold =
967 kbps != nqe::internal::kInvalidThroughput && 1050 kbps != nqe::internal::kInvalidThroughput &&
968 connection_thresholds_[i].downstream_throughput_kbps() != 1051 connection_thresholds_[i].downstream_throughput_kbps() !=
969 nqe::internal::kInvalidThroughput && 1052 nqe::internal::kInvalidThroughput &&
970 kbps <= connection_thresholds_[i].downstream_throughput_kbps(); 1053 kbps <= connection_thresholds_[i].downstream_throughput_kbps();
971 1054
972 // Return |type| as the effective connection type if the current network's
973 // RTT is worse than the threshold RTT for |type|, or if the current
974 // network's throughput is lower than the threshold throughput for |type|.
975 if (estimated_http_rtt_is_higher_than_threshold || 1055 if (estimated_http_rtt_is_higher_than_threshold ||
1056 estimated_transport_rtt_is_higher_than_threshold ||
976 estimated_throughput_is_lower_than_threshold) { 1057 estimated_throughput_is_lower_than_threshold) {
977 return type; 1058 return type;
978 } 1059 }
979 } 1060 }
980 // Return the fastest connection type. 1061 // Return the fastest connection type.
981 return static_cast<EffectiveConnectionType>(EFFECTIVE_CONNECTION_TYPE_LAST - 1062 return static_cast<EffectiveConnectionType>(EFFECTIVE_CONNECTION_TYPE_LAST -
982 1); 1063 1);
983 } 1064 }
984 1065
985 void NetworkQualityEstimator::AddEffectiveConnectionTypeObserver( 1066 void NetworkQualityEstimator::AddEffectiveConnectionTypeObserver(
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
1391 NotifyObserversOfEffectiveConnectionTypeChanged() { 1472 NotifyObserversOfEffectiveConnectionTypeChanged() {
1392 DCHECK(thread_checker_.CalledOnValidThread()); 1473 DCHECK(thread_checker_.CalledOnValidThread());
1393 1474
1394 // TODO(tbansal): Add hysteresis in the notification. 1475 // TODO(tbansal): Add hysteresis in the notification.
1395 FOR_EACH_OBSERVER( 1476 FOR_EACH_OBSERVER(
1396 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, 1477 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_,
1397 OnEffectiveConnectionTypeChanged(effective_connection_type_)); 1478 OnEffectiveConnectionTypeChanged(effective_connection_type_));
1398 } 1479 }
1399 1480
1400 } // namespace net 1481 } // namespace net
OLDNEW
« no previous file with comments | « net/nqe/network_quality_estimator.h ('k') | net/nqe/network_quality_estimator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698