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

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

Issue 2146563002: Expose effective connection type to Cronet (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Updated comments Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/nqe/network_quality_estimator.h" 5 #include "net/nqe/network_quality_estimator.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <limits> 9 #include <limits>
10 #include <utility> 10 #include <utility>
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 DCHECK_GT(max_limit, kLowerLimit); 133 DCHECK_GT(max_limit, kLowerLimit);
134 const size_t kBucketCount = 50; 134 const size_t kBucketCount = 50;
135 135
136 // Prefix of network quality estimator histograms. 136 // Prefix of network quality estimator histograms.
137 const char prefix[] = "NQE."; 137 const char prefix[] = "NQE.";
138 return base::Histogram::FactoryGet( 138 return base::Histogram::FactoryGet(
139 prefix + statistic_name + GetNameForConnectionType(type), kLowerLimit, 139 prefix + statistic_name + GetNameForConnectionType(type), kLowerLimit,
140 max_limit, kBucketCount, base::HistogramBase::kUmaTargetedHistogramFlag); 140 max_limit, kBucketCount, base::HistogramBase::kUmaTargetedHistogramFlag);
141 } 141 }
142 142
143 bool GetValueForVariationParam( 143 // Sets |variations_value| to the value of |parameter_name| read from
144 // |variation_params|. If the value is unavailable from |variation_params|, then
145 // |variations_value| is set to |default_value|.
146 void GetValueForVariationParam(
144 const std::map<std::string, std::string>& variation_params, 147 const std::map<std::string, std::string>& variation_params,
145 const std::string& parameter_name, 148 const std::string& parameter_name,
149 int32_t default_value,
146 int32_t* variations_value) { 150 int32_t* variations_value) {
147 const auto it = variation_params.find(parameter_name); 151 const auto it = variation_params.find(parameter_name);
148 return it != variation_params.end() && 152 if (it != variation_params.end() &&
149 base::StringToInt(it->second, variations_value); 153 base::StringToInt(it->second, variations_value)) {
154 return;
155 }
156 *variations_value = default_value;
150 } 157 }
151 158
152 // Returns the algorithm that should be used for computing effective connection 159 // Returns the algorithm that should be used for computing effective connection
153 // type based on field trial params. Returns an empty string if a valid 160 // type based on field trial params. Returns an empty string if a valid
154 // algorithm paramter is not present in the field trial params. 161 // algorithm paramter is not present in the field trial params.
155 std::string GetEffectiveConnectionTypeAlgorithm( 162 std::string GetEffectiveConnectionTypeAlgorithm(
156 const std::map<std::string, std::string>& variation_params) { 163 const std::map<std::string, std::string>& variation_params) {
157 const auto it = variation_params.find("effective_connection_type_algorithm"); 164 const auto it = variation_params.find("effective_connection_type_algorithm");
158 if (it == variation_params.end()) 165 if (it == variation_params.end())
159 return std::string(); 166 return std::string();
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 base::ThreadTaskRunnerHandle::Get(), 316 base::ThreadTaskRunnerHandle::Get(),
310 base::Bind(&NetworkQualityEstimator::OnUpdatedRTTAvailable, 317 base::Bind(&NetworkQualityEstimator::OnUpdatedRTTAvailable,
311 base::Unretained(this)))); 318 base::Unretained(this))));
312 319
313 // Record accuracy at 3 different intervals. The values used here must remain 320 // Record accuracy at 3 different intervals. The values used here must remain
314 // in sync with the suffixes specified in 321 // in sync with the suffixes specified in
315 // tools/metrics/histograms/histograms.xml. 322 // tools/metrics/histograms/histograms.xml.
316 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(15)); 323 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(15));
317 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(30)); 324 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(30));
318 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(60)); 325 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(60));
326
327 // Set to 1870 milliseconds which corresponds to below 33rd percentile of 2G
328 // transport RTT observations.
329 default_connection_thresholds_[EFFECTIVE_CONNECTION_TYPE_SLOW_2G] =
330 nqe::internal::NetworkQuality(nqe::internal::InvalidRTT(),
331 base::TimeDelta::FromMilliseconds(1870),
332 nqe::internal::kInvalidThroughput);
333
334 // Set to 1300 milliseconds which corresponds to 50th percentile of 2G
335 // transport RTT observations.
336 default_connection_thresholds_[EFFECTIVE_CONNECTION_TYPE_2G] =
337 nqe::internal::NetworkQuality(nqe::internal::InvalidRTT(),
338 base::TimeDelta::FromMilliseconds(1300),
339 nqe::internal::kInvalidThroughput);
319 } 340 }
320 341
321 void NetworkQualityEstimator::ObtainOperatingParams( 342 void NetworkQualityEstimator::ObtainOperatingParams(
322 const std::map<std::string, std::string>& variation_params) { 343 const std::map<std::string, std::string>& variation_params) {
323 DCHECK(thread_checker_.CalledOnValidThread()); 344 DCHECK(thread_checker_.CalledOnValidThread());
324 345
325 for (size_t i = 0; i <= NetworkChangeNotifier::CONNECTION_LAST; ++i) { 346 for (size_t i = 0; i <= NetworkChangeNotifier::CONNECTION_LAST; ++i) {
326 NetworkChangeNotifier::ConnectionType type = 347 NetworkChangeNotifier::ConnectionType type =
327 static_cast<NetworkChangeNotifier::ConnectionType>(i); 348 static_cast<NetworkChangeNotifier::ConnectionType>(i);
328 DCHECK_EQ(nqe::internal::InvalidRTT(), default_observations_[i].http_rtt()); 349 DCHECK_EQ(nqe::internal::InvalidRTT(), default_observations_[i].http_rtt());
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 DCHECK_EQ(nqe::internal::InvalidRTT(), 395 DCHECK_EQ(nqe::internal::InvalidRTT(),
375 connection_thresholds_[i].transport_rtt()); 396 connection_thresholds_[i].transport_rtt());
376 DCHECK_EQ(nqe::internal::kInvalidThroughput, 397 DCHECK_EQ(nqe::internal::kInvalidThroughput,
377 connection_thresholds_[i].downstream_throughput_kbps()); 398 connection_thresholds_[i].downstream_throughput_kbps());
378 if (effective_connection_type == EFFECTIVE_CONNECTION_TYPE_UNKNOWN) 399 if (effective_connection_type == EFFECTIVE_CONNECTION_TYPE_UNKNOWN)
379 continue; 400 continue;
380 401
381 std::string connection_type_name = std::string( 402 std::string connection_type_name = std::string(
382 GetNameForEffectiveConnectionType(effective_connection_type)); 403 GetNameForEffectiveConnectionType(effective_connection_type));
383 404
384 int32_t variations_value = kMinimumRTTVariationParameterMsec - 1; 405 int32_t variations_value;
385 if (GetValueForVariationParam( 406 GetValueForVariationParam(
386 variation_params, connection_type_name + kThresholdURLRTTMsecSuffix, 407 variation_params, connection_type_name + kThresholdURLRTTMsecSuffix,
387 &variations_value) && 408 default_connection_thresholds_[i].http_rtt().InMilliseconds(),
388 variations_value >= kMinimumRTTVariationParameterMsec) { 409 &variations_value);
389 connection_thresholds_[i].set_http_rtt( 410 connection_thresholds_[i].set_http_rtt(
390 base::TimeDelta(base::TimeDelta::FromMilliseconds(variations_value))); 411 base::TimeDelta(base::TimeDelta::FromMilliseconds(variations_value)));
412 // Verify that the RTT values are in decreasing order as the network
413 // quality improves.
414 DCHECK(i == 0 ||
415 connection_thresholds_[i].http_rtt() ==
416 nqe::internal::InvalidRTT() ||
417 connection_thresholds_[i - 1].http_rtt() ==
418 nqe::internal::InvalidRTT() ||
419 connection_thresholds_[i].http_rtt() <=
420 connection_thresholds_[i - 1].http_rtt());
391 421
392 // Verify that the RTT values are in decreasing order as the network 422 GetValueForVariationParam(
393 // quality improves. 423 variation_params,
394 DCHECK(i == 0 || 424 connection_type_name + kThresholdTransportRTTMsecSuffix,
395 connection_thresholds_[i - 1].http_rtt() == 425 default_connection_thresholds_[i].transport_rtt().InMilliseconds(),
396 nqe::internal::InvalidRTT() || 426 &variations_value);
397 connection_thresholds_[i].http_rtt() <= 427 connection_thresholds_[i].set_transport_rtt(
398 connection_thresholds_[i - 1].http_rtt()); 428 base::TimeDelta(base::TimeDelta::FromMilliseconds(variations_value)));
399 } 429 // Verify that the transport RTT values are in decreasing order as the
430 // network quality improves.
431 DCHECK(i == 0 ||
432 connection_thresholds_[i].transport_rtt() ==
433 nqe::internal::InvalidRTT() ||
434 connection_thresholds_[i - 1].transport_rtt() ==
435 nqe::internal::InvalidRTT() ||
436 connection_thresholds_[i].transport_rtt() <=
437 connection_thresholds_[i - 1].transport_rtt());
400 438
401 variations_value = kMinimumRTTVariationParameterMsec - 1; 439 GetValueForVariationParam(
402 if (GetValueForVariationParam( 440 variation_params, connection_type_name + kThresholdKbpsSuffix,
403 variation_params, 441 default_connection_thresholds_[i].downstream_throughput_kbps(),
404 connection_type_name + kThresholdTransportRTTMsecSuffix, 442 &variations_value);
405 &variations_value) && 443 connection_thresholds_[i].set_downstream_throughput_kbps(variations_value);
406 variations_value >= kMinimumRTTVariationParameterMsec) { 444 // Verify that the throughput values are in increasing order as the
407 connection_thresholds_[i].set_transport_rtt( 445 // network quality improves.
408 base::TimeDelta(base::TimeDelta::FromMilliseconds(variations_value))); 446 DCHECK(i == 0 ||
409 447 connection_thresholds_[i].downstream_throughput_kbps() ==
410 // Verify that the transport RTT values are in decreasing order as the 448 kMinimumThroughputVariationParameterKbps ||
411 // network quality improves. 449 connection_thresholds_[i - 1].downstream_throughput_kbps() ==
412 DCHECK(i == 0 || 450 kMinimumThroughputVariationParameterKbps ||
413 connection_thresholds_[i - 1].transport_rtt() == 451 connection_thresholds_[i].downstream_throughput_kbps() >=
414 nqe::internal::InvalidRTT() || 452 connection_thresholds_[i - 1].downstream_throughput_kbps());
415 connection_thresholds_[i].transport_rtt() <=
416 connection_thresholds_[i - 1].transport_rtt());
417 }
418
419 variations_value = kMinimumThroughputVariationParameterKbps - 1;
420 if (GetValueForVariationParam(variation_params,
421 connection_type_name + kThresholdKbpsSuffix,
422 &variations_value) &&
423 variations_value >= kMinimumThroughputVariationParameterKbps) {
424 connection_thresholds_[i].set_downstream_throughput_kbps(
425 variations_value);
426
427 // Verify that the throughput values are in increasing order as the
428 // network quality improves.
429 DCHECK(i == 0 ||
430 connection_thresholds_[i - 1].downstream_throughput_kbps() ==
431 kMinimumThroughputVariationParameterKbps ||
432 connection_thresholds_[i].downstream_throughput_kbps() >=
433 connection_thresholds_[i - 1].downstream_throughput_kbps());
434 }
435 } 453 }
436 } 454 }
437 455
438 void NetworkQualityEstimator::AddDefaultEstimates() { 456 void NetworkQualityEstimator::AddDefaultEstimates() {
439 DCHECK(thread_checker_.CalledOnValidThread()); 457 DCHECK(thread_checker_.CalledOnValidThread());
440 458
441 if (default_observations_[current_network_id_.type].http_rtt() != 459 if (default_observations_[current_network_id_.type].http_rtt() !=
442 nqe::internal::InvalidRTT()) { 460 nqe::internal::InvalidRTT()) {
443 RttObservation rtt_observation( 461 RttObservation rtt_observation(
444 default_observations_[current_network_id_.type].http_rtt(), 462 default_observations_[current_network_id_.type].http_rtt(),
(...skipping 1001 matching lines...) Expand 10 before | Expand all | Expand 10 after
1446 1464
1447 void NetworkQualityEstimator::MaybeRecomputeEffectiveConnectionType() { 1465 void NetworkQualityEstimator::MaybeRecomputeEffectiveConnectionType() {
1448 DCHECK(thread_checker_.CalledOnValidThread()); 1466 DCHECK(thread_checker_.CalledOnValidThread());
1449 1467
1450 const base::TimeTicks now = tick_clock_->NowTicks(); 1468 const base::TimeTicks now = tick_clock_->NowTicks();
1451 // Recompute effective connection type only if 1469 // Recompute effective connection type only if
1452 // |effective_connection_type_recomputation_interval_| has passed since it was 1470 // |effective_connection_type_recomputation_interval_| has passed since it was
1453 // last computed or a connection change event was observed since the last 1471 // last computed or a connection change event was observed since the last
1454 // computation. Strict inequalities are used to ensure that effective 1472 // computation. Strict inequalities are used to ensure that effective
1455 // connection type is recomputed on connection change events even if the clock 1473 // connection type is recomputed on connection change events even if the clock
1456 // has not updated. 1474 // has not updated. If the algorithm uses transport RTT, then recompute the
1475 // effective connection type if the effective connection type was previously
1476 // unavailable. This is because the transport RTT observations are voluminous,
1477 // so it may now be possible to compute the effective connection type.
1457 if (now - last_effective_connection_type_computation_ < 1478 if (now - last_effective_connection_type_computation_ <
1458 effective_connection_type_recomputation_interval_ && 1479 effective_connection_type_recomputation_interval_ &&
1459 last_connection_change_ < last_effective_connection_type_computation_) { 1480 last_connection_change_ < last_effective_connection_type_computation_ &&
1481 (effective_connection_type_ !=
1482 NetworkQualityEstimator::EFFECTIVE_CONNECTION_TYPE_UNKNOWN ||
1483 effective_connection_type_algorithm_ !=
1484 EffectiveConnectionTypeAlgorithm::
1485 TRANSPORT_RTT_OR_DOWNSTREAM_THROUGHOUT)) {
1460 return; 1486 return;
1461 } 1487 }
1462 1488
1463 const EffectiveConnectionType past_type = effective_connection_type_; 1489 const EffectiveConnectionType past_type = effective_connection_type_;
1464 last_effective_connection_type_computation_ = now; 1490 last_effective_connection_type_computation_ = now;
1465 effective_connection_type_ = GetEffectiveConnectionType(); 1491 effective_connection_type_ = GetEffectiveConnectionType();
1466 1492
1467 if (past_type != effective_connection_type_) 1493 if (past_type != effective_connection_type_)
1468 NotifyObserversOfEffectiveConnectionTypeChanged(); 1494 NotifyObserversOfEffectiveConnectionTypeChanged();
1469 } 1495 }
1470 1496
1471 void NetworkQualityEstimator:: 1497 void NetworkQualityEstimator::
1472 NotifyObserversOfEffectiveConnectionTypeChanged() { 1498 NotifyObserversOfEffectiveConnectionTypeChanged() {
1473 DCHECK(thread_checker_.CalledOnValidThread()); 1499 DCHECK(thread_checker_.CalledOnValidThread());
1474 1500
1475 // TODO(tbansal): Add hysteresis in the notification. 1501 // TODO(tbansal): Add hysteresis in the notification.
1476 FOR_EACH_OBSERVER( 1502 FOR_EACH_OBSERVER(
1477 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, 1503 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_,
1478 OnEffectiveConnectionTypeChanged(effective_connection_type_)); 1504 OnEffectiveConnectionTypeChanged(effective_connection_type_));
1479 } 1505 }
1480 1506
1481 } // namespace net 1507 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698