• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/nqe/network_quality_estimator_params.h"
6 
7 #include <stdint.h>
8 
9 #include "base/strings/string_number_conversions.h"
10 #include "base/time/time.h"
11 
12 namespace net {
13 
14 const char kForceEffectiveConnectionType[] = "force_effective_connection_type";
15 const char kEffectiveConnectionTypeSlow2GOnCellular[] = "Slow-2G-On-Cellular";
16 const base::TimeDelta
17     kHttpRttEffectiveConnectionTypeThresholds[EFFECTIVE_CONNECTION_TYPE_LAST] =
18         {base::Milliseconds(0),    base::Milliseconds(0),
19          base::Milliseconds(2010), base::Milliseconds(1420),
20          base::Milliseconds(272),  base::Milliseconds(0)};
21 
22 namespace {
23 
24 // Minimum valid value of the variation parameter that holds RTT (in
25 // milliseconds) values.
26 static const int kMinimumRTTVariationParameterMsec = 1;
27 
28 // Minimum valid value of the variation parameter that holds throughput (in
29 // kilobits per second) values.
30 static const int kMinimumThroughputVariationParameterKbps = 1;
31 
32 // Returns the value of |parameter_name| read from |params|. If the
33 // value is unavailable from |params|, then |default_value| is returned.
GetValueForVariationParam(const std::map<std::string,std::string> & params,const std::string & parameter_name,int64_t default_value)34 int64_t GetValueForVariationParam(
35     const std::map<std::string, std::string>& params,
36     const std::string& parameter_name,
37     int64_t default_value) {
38   const auto it = params.find(parameter_name);
39   int64_t variations_value = default_value;
40   if (it != params.end() &&
41       base::StringToInt64(it->second, &variations_value)) {
42     return variations_value;
43   }
44   return default_value;
45 }
46 
47 // Returns the variation value for |parameter_name|. If the value is
48 // unavailable, |default_value| is returned.
GetDoubleValueForVariationParamWithDefaultValue(const std::map<std::string,std::string> & params,const std::string & parameter_name,double default_value)49 double GetDoubleValueForVariationParamWithDefaultValue(
50     const std::map<std::string, std::string>& params,
51     const std::string& parameter_name,
52     double default_value) {
53   const auto it = params.find(parameter_name);
54   if (it == params.end())
55     return default_value;
56 
57   double variations_value = default_value;
58   if (!base::StringToDouble(it->second, &variations_value))
59     return default_value;
60   return variations_value;
61 }
62 
63 // Returns the variation value for |parameter_name|. If the value is
64 // unavailable, |default_value| is returned.
GetStringValueForVariationParamWithDefaultValue(const std::map<std::string,std::string> & params,const std::string & parameter_name,const std::string & default_value)65 std::string GetStringValueForVariationParamWithDefaultValue(
66     const std::map<std::string, std::string>& params,
67     const std::string& parameter_name,
68     const std::string& default_value) {
69   const auto it = params.find(parameter_name);
70   if (it == params.end())
71     return default_value;
72   return it->second;
73 }
74 
GetWeightMultiplierPerSecond(const std::map<std::string,std::string> & params)75 double GetWeightMultiplierPerSecond(
76     const std::map<std::string, std::string>& params) {
77   // Default value of the half life (in seconds) for computing time weighted
78   // percentiles. Every half life, the weight of all observations reduces by
79   // half. Lowering the half life would reduce the weight of older values
80   // faster.
81   int half_life_seconds = 60;
82   int32_t variations_value = 0;
83   auto it = params.find("HalfLifeSeconds");
84   if (it != params.end() && base::StringToInt(it->second, &variations_value) &&
85       variations_value >= 1) {
86     half_life_seconds = variations_value;
87   }
88   DCHECK_GT(half_life_seconds, 0);
89   return pow(0.5, 1.0 / half_life_seconds);
90 }
91 
GetPersistentCacheReadingEnabled(const std::map<std::string,std::string> & params)92 bool GetPersistentCacheReadingEnabled(
93     const std::map<std::string, std::string>& params) {
94   if (GetStringValueForVariationParamWithDefaultValue(
95           params, "persistent_cache_reading_enabled", "true") != "true") {
96     return false;
97   }
98   return true;
99 }
100 
GetMinSocketWatcherNotificationInterval(const std::map<std::string,std::string> & params)101 base::TimeDelta GetMinSocketWatcherNotificationInterval(
102     const std::map<std::string, std::string>& params) {
103   // Use 1000 milliseconds as the default value.
104   return base::Milliseconds(GetValueForVariationParam(
105       params, "min_socket_watcher_notification_interval_msec", 1000));
106 }
107 
108 // static
GetNameForConnectionTypeInternal(NetworkChangeNotifier::ConnectionType connection_type)109 const char* GetNameForConnectionTypeInternal(
110     NetworkChangeNotifier::ConnectionType connection_type) {
111   switch (connection_type) {
112     case NetworkChangeNotifier::CONNECTION_UNKNOWN:
113       return "Unknown";
114     case NetworkChangeNotifier::CONNECTION_ETHERNET:
115       return "Ethernet";
116     case NetworkChangeNotifier::CONNECTION_WIFI:
117       return "WiFi";
118     case NetworkChangeNotifier::CONNECTION_2G:
119       return "2G";
120     case NetworkChangeNotifier::CONNECTION_3G:
121       return "3G";
122     case NetworkChangeNotifier::CONNECTION_4G:
123       return "4G";
124     case NetworkChangeNotifier::CONNECTION_5G:
125       return "5G";
126     case NetworkChangeNotifier::CONNECTION_NONE:
127       return "None";
128     case NetworkChangeNotifier::CONNECTION_BLUETOOTH:
129       return "Bluetooth";
130   }
131   return "";
132 }
133 
134 // Sets the default observation for different connection types in
135 // |default_observations|. The default observations are different for
136 // different connection types (e.g., 2G, 3G, 4G, WiFi). The default
137 // observations may be used to determine the network quality in absence of any
138 // other information.
ObtainDefaultObservations(const std::map<std::string,std::string> & params,nqe::internal::NetworkQuality default_observations[])139 void ObtainDefaultObservations(
140     const std::map<std::string, std::string>& params,
141     nqe::internal::NetworkQuality default_observations[]) {
142   for (size_t i = 0; i < NetworkChangeNotifier::CONNECTION_LAST; ++i) {
143     DCHECK_EQ(nqe::internal::InvalidRTT(), default_observations[i].http_rtt());
144     DCHECK_EQ(nqe::internal::InvalidRTT(),
145               default_observations[i].transport_rtt());
146     DCHECK_EQ(nqe::internal::INVALID_RTT_THROUGHPUT,
147               default_observations[i].downstream_throughput_kbps());
148   }
149 
150   // Default observations for HTTP RTT, transport RTT, and downstream throughput
151   // Kbps for the various connection types. These may be overridden by
152   // variations params. The default observation for a connection type
153   // corresponds to typical network quality for that connection type.
154   default_observations[NetworkChangeNotifier::CONNECTION_UNKNOWN] =
155       nqe::internal::NetworkQuality(base::Milliseconds(115),
156                                     base::Milliseconds(55), 1961);
157 
158   default_observations[NetworkChangeNotifier::CONNECTION_ETHERNET] =
159       nqe::internal::NetworkQuality(base::Milliseconds(90),
160                                     base::Milliseconds(33), 1456);
161 
162   default_observations[NetworkChangeNotifier::CONNECTION_WIFI] =
163       nqe::internal::NetworkQuality(base::Milliseconds(116),
164                                     base::Milliseconds(66), 2658);
165 
166   default_observations[NetworkChangeNotifier::CONNECTION_2G] =
167       nqe::internal::NetworkQuality(base::Milliseconds(1726),
168                                     base::Milliseconds(1531), 74);
169 
170   default_observations[NetworkChangeNotifier::CONNECTION_3G] =
171       nqe::internal::NetworkQuality(base::Milliseconds(273),
172                                     base::Milliseconds(209), 749);
173 
174   default_observations[NetworkChangeNotifier::CONNECTION_4G] =
175       nqe::internal::NetworkQuality(base::Milliseconds(137),
176                                     base::Milliseconds(80), 1708);
177 
178   default_observations[NetworkChangeNotifier::CONNECTION_NONE] =
179       nqe::internal::NetworkQuality(base::Milliseconds(163),
180                                     base::Milliseconds(83), 575);
181 
182   default_observations[NetworkChangeNotifier::CONNECTION_BLUETOOTH] =
183       nqe::internal::NetworkQuality(base::Milliseconds(385),
184                                     base::Milliseconds(318), 476);
185 
186   // Override using the values provided via variation params.
187   for (size_t i = 0; i <= NetworkChangeNotifier::CONNECTION_LAST; ++i) {
188     NetworkChangeNotifier::ConnectionType type =
189         static_cast<NetworkChangeNotifier::ConnectionType>(i);
190 
191     int32_t variations_value = kMinimumRTTVariationParameterMsec - 1;
192     std::string parameter_name =
193         std::string(GetNameForConnectionTypeInternal(type))
194             .append(".DefaultMedianRTTMsec");
195     auto it = params.find(parameter_name);
196     if (it != params.end() &&
197         base::StringToInt(it->second, &variations_value) &&
198         variations_value >= kMinimumRTTVariationParameterMsec) {
199       default_observations[i] = nqe::internal::NetworkQuality(
200           base::Milliseconds(variations_value),
201           default_observations[i].transport_rtt(),
202           default_observations[i].downstream_throughput_kbps());
203     }
204 
205     variations_value = kMinimumRTTVariationParameterMsec - 1;
206     parameter_name = std::string(GetNameForConnectionTypeInternal(type))
207                          .append(".DefaultMedianTransportRTTMsec");
208     it = params.find(parameter_name);
209     if (it != params.end() &&
210         base::StringToInt(it->second, &variations_value) &&
211         variations_value >= kMinimumRTTVariationParameterMsec) {
212       default_observations[i] = nqe::internal::NetworkQuality(
213           default_observations[i].http_rtt(),
214           base::Milliseconds(variations_value),
215           default_observations[i].downstream_throughput_kbps());
216     }
217 
218     variations_value = kMinimumThroughputVariationParameterKbps - 1;
219     parameter_name = std::string(GetNameForConnectionTypeInternal(type))
220                          .append(".DefaultMedianKbps");
221     it = params.find(parameter_name);
222 
223     if (it != params.end() &&
224         base::StringToInt(it->second, &variations_value) &&
225         variations_value >= kMinimumThroughputVariationParameterKbps) {
226       default_observations[i] = nqe::internal::NetworkQuality(
227           default_observations[i].http_rtt(),
228           default_observations[i].transport_rtt(), variations_value);
229     }
230   }
231 }
232 
233 // Typical HTTP RTT value corresponding to a given WebEffectiveConnectionType
234 // value. Taken from
235 // https://cs.chromium.org/chromium/src/net/nqe/network_quality_estimator_params.cc.
236 const base::TimeDelta kTypicalHttpRttEffectiveConnectionType
237     [net::EFFECTIVE_CONNECTION_TYPE_LAST] = {
238         base::Milliseconds(0),    base::Milliseconds(0),
239         base::Milliseconds(3600), base::Milliseconds(1800),
240         base::Milliseconds(450),  base::Milliseconds(175)};
241 
242 // Typical downlink throughput (in Mbps) value corresponding to a given
243 // WebEffectiveConnectionType value. Taken from
244 // https://cs.chromium.org/chromium/src/net/nqe/network_quality_estimator_params.cc.
245 const int32_t kTypicalDownlinkKbpsEffectiveConnectionType
246     [net::EFFECTIVE_CONNECTION_TYPE_LAST] = {0, 0, 40, 75, 400, 1600};
247 
248 // Sets |typical_network_quality| to typical network quality for different
249 // effective connection types.
ObtainTypicalNetworkQualities(const std::map<std::string,std::string> & params,nqe::internal::NetworkQuality typical_network_quality[])250 void ObtainTypicalNetworkQualities(
251     const std::map<std::string, std::string>& params,
252     nqe::internal::NetworkQuality typical_network_quality[]) {
253   for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) {
254     DCHECK_EQ(nqe::internal::InvalidRTT(),
255               typical_network_quality[i].http_rtt());
256     DCHECK_EQ(nqe::internal::InvalidRTT(),
257               typical_network_quality[i].transport_rtt());
258     DCHECK_EQ(nqe::internal::INVALID_RTT_THROUGHPUT,
259               typical_network_quality[i].downstream_throughput_kbps());
260   }
261 
262   typical_network_quality[EFFECTIVE_CONNECTION_TYPE_SLOW_2G] =
263       nqe::internal::NetworkQuality(
264           // Set to the 77.5th percentile of 2G RTT observations on Android.
265           // This corresponds to the median RTT observation when effective
266           // connection type is Slow 2G.
267           kTypicalHttpRttEffectiveConnectionType
268               [EFFECTIVE_CONNECTION_TYPE_SLOW_2G],
269           base::Milliseconds(3000),
270           kTypicalDownlinkKbpsEffectiveConnectionType
271               [EFFECTIVE_CONNECTION_TYPE_SLOW_2G]);
272 
273   typical_network_quality[EFFECTIVE_CONNECTION_TYPE_2G] =
274       nqe::internal::NetworkQuality(
275           // Set to the 58th percentile of 2G RTT observations on Android. This
276           // corresponds to the median RTT observation when effective connection
277           // type is 2G.
278           kTypicalHttpRttEffectiveConnectionType[EFFECTIVE_CONNECTION_TYPE_2G],
279           base::Milliseconds(1500),
280           kTypicalDownlinkKbpsEffectiveConnectionType
281               [EFFECTIVE_CONNECTION_TYPE_2G]);
282 
283   typical_network_quality[EFFECTIVE_CONNECTION_TYPE_3G] =
284       nqe::internal::NetworkQuality(
285           // Set to the 75th percentile of 3G RTT observations on Android. This
286           // corresponds to the median RTT observation when effective connection
287           // type is 3G.
288           kTypicalHttpRttEffectiveConnectionType[EFFECTIVE_CONNECTION_TYPE_3G],
289           base::Milliseconds(400),
290           kTypicalDownlinkKbpsEffectiveConnectionType
291               [EFFECTIVE_CONNECTION_TYPE_3G]);
292 
293   // Set to the 25th percentile of 3G RTT observations on Android.
294   typical_network_quality[EFFECTIVE_CONNECTION_TYPE_4G] =
295       nqe::internal::NetworkQuality(
296           kTypicalHttpRttEffectiveConnectionType[EFFECTIVE_CONNECTION_TYPE_4G],
297           base::Milliseconds(125),
298           kTypicalDownlinkKbpsEffectiveConnectionType
299               [EFFECTIVE_CONNECTION_TYPE_4G]);
300 
301   static_assert(
302       EFFECTIVE_CONNECTION_TYPE_4G + 1 == EFFECTIVE_CONNECTION_TYPE_LAST,
303       "Missing effective connection type");
304 }
305 
306 // Sets the thresholds for different effective connection types in
307 // |connection_thresholds|.
ObtainConnectionThresholds(const std::map<std::string,std::string> & params,nqe::internal::NetworkQuality connection_thresholds[])308 void ObtainConnectionThresholds(
309     const std::map<std::string, std::string>& params,
310     nqe::internal::NetworkQuality connection_thresholds[]) {
311   // First set the default thresholds.
312   nqe::internal::NetworkQuality default_effective_connection_type_thresholds
313       [EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_LAST];
314 
315   DCHECK_LT(base::TimeDelta(), kHttpRttEffectiveConnectionTypeThresholds
316                                    [EFFECTIVE_CONNECTION_TYPE_SLOW_2G]);
317   default_effective_connection_type_thresholds
318       [EFFECTIVE_CONNECTION_TYPE_SLOW_2G] = nqe::internal::NetworkQuality(
319           // Set to the 66th percentile of 2G RTT observations on Android.
320           kHttpRttEffectiveConnectionTypeThresholds
321               [EFFECTIVE_CONNECTION_TYPE_SLOW_2G],
322           nqe::internal::InvalidRTT(), nqe::internal::INVALID_RTT_THROUGHPUT);
323 
324   DCHECK_LT(
325       base::TimeDelta(),
326       kHttpRttEffectiveConnectionTypeThresholds[EFFECTIVE_CONNECTION_TYPE_2G]);
327   default_effective_connection_type_thresholds[EFFECTIVE_CONNECTION_TYPE_2G] =
328       nqe::internal::NetworkQuality(
329           // Set to the 50th percentile of RTT observations on Android.
330           kHttpRttEffectiveConnectionTypeThresholds
331               [EFFECTIVE_CONNECTION_TYPE_2G],
332           nqe::internal::InvalidRTT(), nqe::internal::INVALID_RTT_THROUGHPUT);
333 
334   DCHECK_LT(
335       base::TimeDelta(),
336       kHttpRttEffectiveConnectionTypeThresholds[EFFECTIVE_CONNECTION_TYPE_3G]);
337   default_effective_connection_type_thresholds[EFFECTIVE_CONNECTION_TYPE_3G] =
338       nqe::internal::NetworkQuality(
339           // Set to the 50th percentile of 3G RTT observations on Android.
340           kHttpRttEffectiveConnectionTypeThresholds
341               [EFFECTIVE_CONNECTION_TYPE_3G],
342           nqe::internal::InvalidRTT(), nqe::internal::INVALID_RTT_THROUGHPUT);
343 
344   // Connection threshold should not be set for 4G effective connection type
345   // since it is the fastest.
346   static_assert(
347       EFFECTIVE_CONNECTION_TYPE_3G + 1 == EFFECTIVE_CONNECTION_TYPE_4G,
348       "Missing effective connection type");
349   static_assert(
350       EFFECTIVE_CONNECTION_TYPE_4G + 1 == EFFECTIVE_CONNECTION_TYPE_LAST,
351       "Missing effective connection type");
352   for (size_t i = 0; i <= EFFECTIVE_CONNECTION_TYPE_3G; ++i) {
353     EffectiveConnectionType effective_connection_type =
354         static_cast<EffectiveConnectionType>(i);
355     DCHECK_EQ(nqe::internal::InvalidRTT(), connection_thresholds[i].http_rtt());
356     DCHECK_EQ(nqe::internal::InvalidRTT(),
357               connection_thresholds[i].transport_rtt());
358     DCHECK_EQ(nqe::internal::INVALID_RTT_THROUGHPUT,
359               connection_thresholds[i].downstream_throughput_kbps());
360     if (effective_connection_type == EFFECTIVE_CONNECTION_TYPE_UNKNOWN)
361       continue;
362 
363     std::string connection_type_name = std::string(
364         DeprecatedGetNameForEffectiveConnectionType(effective_connection_type));
365 
366     connection_thresholds[i].set_http_rtt(
367         base::Milliseconds(GetValueForVariationParam(
368             params, connection_type_name + ".ThresholdMedianHttpRTTMsec",
369             default_effective_connection_type_thresholds[i]
370                 .http_rtt()
371                 .InMilliseconds())));
372 
373     DCHECK_EQ(nqe::internal::InvalidRTT(),
374               default_effective_connection_type_thresholds[i].transport_rtt());
375     DCHECK_EQ(nqe::internal::INVALID_RTT_THROUGHPUT,
376               default_effective_connection_type_thresholds[i]
377                   .downstream_throughput_kbps());
378     DCHECK(i == 0 ||
379            connection_thresholds[i].IsFaster(connection_thresholds[i - 1]));
380   }
381 }
382 
GetForcedEffectiveConnectionTypeString(const std::map<std::string,std::string> & params)383 std::string GetForcedEffectiveConnectionTypeString(
384     const std::map<std::string, std::string>& params) {
385   return GetStringValueForVariationParamWithDefaultValue(
386       params, kForceEffectiveConnectionType, "");
387 }
388 
GetForcedEffectiveConnectionTypeOnCellularOnly(const std::map<std::string,std::string> & params)389 bool GetForcedEffectiveConnectionTypeOnCellularOnly(
390     const std::map<std::string, std::string>& params) {
391   return GetForcedEffectiveConnectionTypeString(params) ==
392          kEffectiveConnectionTypeSlow2GOnCellular;
393 }
394 
GetInitForcedEffectiveConnectionType(const std::map<std::string,std::string> & params)395 absl::optional<EffectiveConnectionType> GetInitForcedEffectiveConnectionType(
396     const std::map<std::string, std::string>& params) {
397   if (GetForcedEffectiveConnectionTypeOnCellularOnly(params)) {
398     return absl::nullopt;
399   }
400   std::string forced_value = GetForcedEffectiveConnectionTypeString(params);
401   absl::optional<EffectiveConnectionType> ect =
402       GetEffectiveConnectionTypeForName(forced_value);
403   DCHECK(forced_value.empty() || ect);
404   return ect;
405 }
406 
407 }  // namespace
408 
NetworkQualityEstimatorParams(const std::map<std::string,std::string> & params)409 NetworkQualityEstimatorParams::NetworkQualityEstimatorParams(
410     const std::map<std::string, std::string>& params)
411     : params_(params),
412       throughput_min_requests_in_flight_(
413           GetValueForVariationParam(params_,
414                                     "throughput_min_requests_in_flight",
415                                     5)),
416       throughput_min_transfer_size_kilobytes_(
417           GetValueForVariationParam(params_,
418                                     "throughput_min_transfer_size_kilobytes",
419                                     32)),
420       throughput_hanging_requests_cwnd_size_multiplier_(
421           GetDoubleValueForVariationParamWithDefaultValue(
422               params_,
423               "throughput_hanging_requests_cwnd_size_multiplier",
424               1)),
425       weight_multiplier_per_second_(GetWeightMultiplierPerSecond(params_)),
426       forced_effective_connection_type_(
427           GetInitForcedEffectiveConnectionType(params_)),
428       forced_effective_connection_type_on_cellular_only_(
429           GetForcedEffectiveConnectionTypeOnCellularOnly(params_)),
430       persistent_cache_reading_enabled_(
431           GetPersistentCacheReadingEnabled(params_)),
432       min_socket_watcher_notification_interval_(
433           GetMinSocketWatcherNotificationInterval(params_)),
434       upper_bound_http_rtt_endtoend_rtt_multiplier_(
435           GetDoubleValueForVariationParamWithDefaultValue(
436               params_,
437               "upper_bound_http_rtt_endtoend_rtt_multiplier",
438               3.0)),
439       hanging_request_http_rtt_upper_bound_transport_rtt_multiplier_(
440           GetValueForVariationParam(
441               params_,
442               "hanging_request_http_rtt_upper_bound_transport_rtt_multiplier",
443               8)),
444       hanging_request_http_rtt_upper_bound_http_rtt_multiplier_(
445           GetValueForVariationParam(
446               params_,
447               "hanging_request_http_rtt_upper_bound_http_rtt_multiplier",
448               6)),
449       http_rtt_transport_rtt_min_count_(
450           GetValueForVariationParam(params_,
451                                     "http_rtt_transport_rtt_min_count",
452                                     5)),
453       increase_in_transport_rtt_logging_interval_(
454           base::Milliseconds(GetDoubleValueForVariationParamWithDefaultValue(
455               params_,
456               "increase_in_transport_rtt_logging_interval",
457               10000))),
458       recent_time_threshold_(
459           base::Milliseconds(GetDoubleValueForVariationParamWithDefaultValue(
460               params_,
461               "recent_time_threshold",
462               5000))),
463       historical_time_threshold_(
464           base::Milliseconds(GetDoubleValueForVariationParamWithDefaultValue(
465               params_,
466               "historical_time_threshold",
467               60000))),
468       hanging_request_duration_http_rtt_multiplier_(GetValueForVariationParam(
469           params_,
470           "hanging_request_duration_http_rtt_multiplier",
471           5)),
472       add_default_platform_observations_(
473           GetStringValueForVariationParamWithDefaultValue(
474               params_,
475               "add_default_platform_observations",
476               "true") == "true"),
477       socket_watchers_min_notification_interval_(
478           base::Milliseconds(GetValueForVariationParam(
479               params_,
480               "socket_watchers_min_notification_interval_msec",
481               200))),
482       upper_bound_typical_kbps_multiplier_(
483           GetDoubleValueForVariationParamWithDefaultValue(
484               params_,
485               "upper_bound_typical_kbps_multiplier",
486               3.5)),
487       adjust_rtt_based_on_rtt_counts_(
488           GetStringValueForVariationParamWithDefaultValue(
489               params_,
490               "adjust_rtt_based_on_rtt_counts",
491               "false") == "true") {
492   DCHECK(hanging_request_http_rtt_upper_bound_transport_rtt_multiplier_ == -1 ||
493          hanging_request_http_rtt_upper_bound_transport_rtt_multiplier_ > 0);
494   DCHECK(hanging_request_http_rtt_upper_bound_http_rtt_multiplier_ == -1 ||
495          hanging_request_http_rtt_upper_bound_http_rtt_multiplier_ > 0);
496   DCHECK(hanging_request_http_rtt_upper_bound_transport_rtt_multiplier_ == -1 ||
497          hanging_request_http_rtt_upper_bound_http_rtt_multiplier_ == -1 ||
498          hanging_request_http_rtt_upper_bound_transport_rtt_multiplier_ >=
499              hanging_request_http_rtt_upper_bound_http_rtt_multiplier_);
500 
501   DCHECK_LT(0, hanging_request_duration_http_rtt_multiplier());
502   DCHECK_LT(0, hanging_request_http_rtt_upper_bound_http_rtt_multiplier());
503   DCHECK_LT(0, hanging_request_http_rtt_upper_bound_transport_rtt_multiplier());
504 
505   ObtainDefaultObservations(params_, default_observations_);
506   ObtainTypicalNetworkQualities(params_, typical_network_quality_);
507   ObtainConnectionThresholds(params_, connection_thresholds_);
508 }
509 
510 NetworkQualityEstimatorParams::~NetworkQualityEstimatorParams() = default;
511 
SetUseSmallResponsesForTesting(bool use_small_responses)512 void NetworkQualityEstimatorParams::SetUseSmallResponsesForTesting(
513     bool use_small_responses) {
514   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
515   use_small_responses_ = use_small_responses;
516 }
517 
use_small_responses() const518 bool NetworkQualityEstimatorParams::use_small_responses() const {
519   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
520   return use_small_responses_;
521 }
522 
523 // static
GetDefaultTypicalHttpRtt(EffectiveConnectionType effective_connection_type)524 base::TimeDelta NetworkQualityEstimatorParams::GetDefaultTypicalHttpRtt(
525     EffectiveConnectionType effective_connection_type) {
526   return kTypicalHttpRttEffectiveConnectionType[effective_connection_type];
527 }
528 
529 // static
GetDefaultTypicalDownlinkKbps(EffectiveConnectionType effective_connection_type)530 int32_t NetworkQualityEstimatorParams::GetDefaultTypicalDownlinkKbps(
531     EffectiveConnectionType effective_connection_type) {
532   return kTypicalDownlinkKbpsEffectiveConnectionType[effective_connection_type];
533 }
534 
SetForcedEffectiveConnectionTypeForTesting(EffectiveConnectionType type)535 void NetworkQualityEstimatorParams::SetForcedEffectiveConnectionTypeForTesting(
536     EffectiveConnectionType type) {
537   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
538   DCHECK(!forced_effective_connection_type_on_cellular_only_);
539   forced_effective_connection_type_ = type;
540 }
541 
542 absl::optional<EffectiveConnectionType>
GetForcedEffectiveConnectionType(NetworkChangeNotifier::ConnectionType connection_type)543 NetworkQualityEstimatorParams::GetForcedEffectiveConnectionType(
544     NetworkChangeNotifier::ConnectionType connection_type) {
545   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
546   if (forced_effective_connection_type_) {
547     return forced_effective_connection_type_;
548   }
549 
550   if (forced_effective_connection_type_on_cellular_only_ &&
551       net::NetworkChangeNotifier::IsConnectionCellular(connection_type)) {
552     return EFFECTIVE_CONNECTION_TYPE_SLOW_2G;
553   }
554   return absl::nullopt;
555 }
556 
throughput_min_requests_in_flight() const557 size_t NetworkQualityEstimatorParams::throughput_min_requests_in_flight()
558     const {
559   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
560 
561   // If |use_small_responses_| is set to true for testing, then consider one
562   // request as sufficient for taking throughput sample.
563   return use_small_responses_ ? 1 : throughput_min_requests_in_flight_;
564 }
565 
GetThroughputMinTransferSizeBits() const566 int64_t NetworkQualityEstimatorParams::GetThroughputMinTransferSizeBits()
567     const {
568   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
569   return static_cast<int64_t>(throughput_min_transfer_size_kilobytes_) * 8 *
570          1000;
571 }
572 
573 const nqe::internal::NetworkQuality&
DefaultObservation(NetworkChangeNotifier::ConnectionType type) const574 NetworkQualityEstimatorParams::DefaultObservation(
575     NetworkChangeNotifier::ConnectionType type) const {
576   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
577   return default_observations_[type];
578 }
579 
580 const nqe::internal::NetworkQuality&
TypicalNetworkQuality(EffectiveConnectionType type) const581 NetworkQualityEstimatorParams::TypicalNetworkQuality(
582     EffectiveConnectionType type) const {
583   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
584   return typical_network_quality_[type];
585 }
586 
587 const nqe::internal::NetworkQuality&
ConnectionThreshold(EffectiveConnectionType type) const588 NetworkQualityEstimatorParams::ConnectionThreshold(
589     EffectiveConnectionType type) const {
590   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
591   return connection_thresholds_[type];
592 }
593 
594 }  // namespace net
595