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