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