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