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

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: Patch 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
« no previous file with comments | « net/nqe/network_quality_estimator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // Below 33rd percentile of 2G transport RTT observations.
328 default_connection_thresholds_[EFFECTIVE_CONNECTION_TYPE_SLOW_2G] =
329 nqe::internal::NetworkQuality(nqe::internal::InvalidRTT(),
330 base::TimeDelta::FromMilliseconds(1870),
RyanSturm 2016/07/12 19:57:55 nit: Can you move the 1870 and 1300 to a static co
tbansal1 2016/07/12 20:32:25 I would prefer to keep them here instead of using
RyanSturm 2016/07/12 20:44:47 I think it would be more clear like: // 1.87 seco
tbansal1 2016/07/13 05:52:03 I updated the comments.
331 nqe::internal::kInvalidThroughput);
332
333 // 50th percentile of 2G transport RTT observations.
334 default_connection_thresholds_[EFFECTIVE_CONNECTION_TYPE_2G] =
335 nqe::internal::NetworkQuality(nqe::internal::InvalidRTT(),
336 base::TimeDelta::FromMilliseconds(1300),
337 nqe::internal::kInvalidThroughput);
319 } 338 }
320 339
321 void NetworkQualityEstimator::ObtainOperatingParams( 340 void NetworkQualityEstimator::ObtainOperatingParams(
322 const std::map<std::string, std::string>& variation_params) { 341 const std::map<std::string, std::string>& variation_params) {
323 DCHECK(thread_checker_.CalledOnValidThread()); 342 DCHECK(thread_checker_.CalledOnValidThread());
324 343
325 for (size_t i = 0; i <= NetworkChangeNotifier::CONNECTION_LAST; ++i) { 344 for (size_t i = 0; i <= NetworkChangeNotifier::CONNECTION_LAST; ++i) {
326 NetworkChangeNotifier::ConnectionType type = 345 NetworkChangeNotifier::ConnectionType type =
327 static_cast<NetworkChangeNotifier::ConnectionType>(i); 346 static_cast<NetworkChangeNotifier::ConnectionType>(i);
328 DCHECK_EQ(nqe::internal::InvalidRTT(), default_observations_[i].http_rtt()); 347 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(), 393 DCHECK_EQ(nqe::internal::InvalidRTT(),
375 connection_thresholds_[i].transport_rtt()); 394 connection_thresholds_[i].transport_rtt());
376 DCHECK_EQ(nqe::internal::kInvalidThroughput, 395 DCHECK_EQ(nqe::internal::kInvalidThroughput,
377 connection_thresholds_[i].downstream_throughput_kbps()); 396 connection_thresholds_[i].downstream_throughput_kbps());
378 if (effective_connection_type == EFFECTIVE_CONNECTION_TYPE_UNKNOWN) 397 if (effective_connection_type == EFFECTIVE_CONNECTION_TYPE_UNKNOWN)
379 continue; 398 continue;
380 399
381 std::string connection_type_name = std::string( 400 std::string connection_type_name = std::string(
382 GetNameForEffectiveConnectionType(effective_connection_type)); 401 GetNameForEffectiveConnectionType(effective_connection_type));
383 402
384 int32_t variations_value = kMinimumRTTVariationParameterMsec - 1; 403 int32_t variations_value;
385 if (GetValueForVariationParam( 404 GetValueForVariationParam(
386 variation_params, connection_type_name + kThresholdURLRTTMsecSuffix, 405 variation_params, connection_type_name + kThresholdURLRTTMsecSuffix,
387 &variations_value) && 406 default_connection_thresholds_[i].http_rtt().InMilliseconds(),
388 variations_value >= kMinimumRTTVariationParameterMsec) { 407 &variations_value);
389 connection_thresholds_[i].set_http_rtt( 408 connection_thresholds_[i].set_http_rtt(
390 base::TimeDelta(base::TimeDelta::FromMilliseconds(variations_value))); 409 base::TimeDelta(base::TimeDelta::FromMilliseconds(variations_value)));
410 // Verify that the RTT values are in decreasing order as the network
411 // quality improves.
412 DCHECK(i == 0 ||
413 connection_thresholds_[i].http_rtt() ==
414 nqe::internal::InvalidRTT() ||
415 connection_thresholds_[i - 1].http_rtt() ==
416 nqe::internal::InvalidRTT() ||
417 connection_thresholds_[i].http_rtt() <=
418 connection_thresholds_[i - 1].http_rtt());
391 419
392 // Verify that the RTT values are in decreasing order as the network 420 GetValueForVariationParam(
393 // quality improves. 421 variation_params,
394 DCHECK(i == 0 || 422 connection_type_name + kThresholdTransportRTTMsecSuffix,
395 connection_thresholds_[i - 1].http_rtt() == 423 default_connection_thresholds_[i].transport_rtt().InMilliseconds(),
396 nqe::internal::InvalidRTT() || 424 &variations_value);
397 connection_thresholds_[i].http_rtt() <= 425 connection_thresholds_[i].set_transport_rtt(
398 connection_thresholds_[i - 1].http_rtt()); 426 base::TimeDelta(base::TimeDelta::FromMilliseconds(variations_value)));
399 } 427 // Verify that the transport RTT values are in decreasing order as the
428 // network quality improves.
429 DCHECK(i == 0 ||
430 connection_thresholds_[i].transport_rtt() ==
431 nqe::internal::InvalidRTT() ||
432 connection_thresholds_[i - 1].transport_rtt() ==
433 nqe::internal::InvalidRTT() ||
434 connection_thresholds_[i].transport_rtt() <=
435 connection_thresholds_[i - 1].transport_rtt());
400 436
401 variations_value = kMinimumRTTVariationParameterMsec - 1; 437 GetValueForVariationParam(
402 if (GetValueForVariationParam( 438 variation_params, connection_type_name + kThresholdKbpsSuffix,
403 variation_params, 439 default_connection_thresholds_[i].downstream_throughput_kbps(),
404 connection_type_name + kThresholdTransportRTTMsecSuffix, 440 &variations_value);
405 &variations_value) && 441 connection_thresholds_[i].set_downstream_throughput_kbps(variations_value);
406 variations_value >= kMinimumRTTVariationParameterMsec) { 442 // Verify that the throughput values are in increasing order as the
407 connection_thresholds_[i].set_transport_rtt( 443 // network quality improves.
408 base::TimeDelta(base::TimeDelta::FromMilliseconds(variations_value))); 444 DCHECK(i == 0 ||
409 445 connection_thresholds_[i].downstream_throughput_kbps() ==
410 // Verify that the transport RTT values are in decreasing order as the 446 kMinimumThroughputVariationParameterKbps ||
411 // network quality improves. 447 connection_thresholds_[i - 1].downstream_throughput_kbps() ==
412 DCHECK(i == 0 || 448 kMinimumThroughputVariationParameterKbps ||
413 connection_thresholds_[i - 1].transport_rtt() == 449 connection_thresholds_[i].downstream_throughput_kbps() >=
414 nqe::internal::InvalidRTT() || 450 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 } 451 }
436 } 452 }
437 453
438 void NetworkQualityEstimator::AddDefaultEstimates() { 454 void NetworkQualityEstimator::AddDefaultEstimates() {
439 DCHECK(thread_checker_.CalledOnValidThread()); 455 DCHECK(thread_checker_.CalledOnValidThread());
440 456
441 if (default_observations_[current_network_id_.type].http_rtt() != 457 if (default_observations_[current_network_id_.type].http_rtt() !=
442 nqe::internal::InvalidRTT()) { 458 nqe::internal::InvalidRTT()) {
443 RttObservation rtt_observation( 459 RttObservation rtt_observation(
444 default_observations_[current_network_id_.type].http_rtt(), 460 default_observations_[current_network_id_.type].http_rtt(),
(...skipping 1001 matching lines...) Expand 10 before | Expand all | Expand 10 after
1446 1462
1447 void NetworkQualityEstimator::MaybeRecomputeEffectiveConnectionType() { 1463 void NetworkQualityEstimator::MaybeRecomputeEffectiveConnectionType() {
1448 DCHECK(thread_checker_.CalledOnValidThread()); 1464 DCHECK(thread_checker_.CalledOnValidThread());
1449 1465
1450 const base::TimeTicks now = tick_clock_->NowTicks(); 1466 const base::TimeTicks now = tick_clock_->NowTicks();
1451 // Recompute effective connection type only if 1467 // Recompute effective connection type only if
1452 // |effective_connection_type_recomputation_interval_| has passed since it was 1468 // |effective_connection_type_recomputation_interval_| has passed since it was
1453 // last computed or a connection change event was observed since the last 1469 // last computed or a connection change event was observed since the last
1454 // computation. Strict inequalities are used to ensure that effective 1470 // computation. Strict inequalities are used to ensure that effective
1455 // connection type is recomputed on connection change events even if the clock 1471 // connection type is recomputed on connection change events even if the clock
1456 // has not updated. 1472 // has not updated. If the algorithm uses transport RTT, then recompute the
1473 // effective connection type if the effective connection type was previously
1474 // unavailable. This is because the transport RTT observations are voluminous,
1475 // so it may now be possible to compute the effective connection type.
1457 if (now - last_effective_connection_type_computation_ < 1476 if (now - last_effective_connection_type_computation_ <
1458 effective_connection_type_recomputation_interval_ && 1477 effective_connection_type_recomputation_interval_ &&
1459 last_connection_change_ < last_effective_connection_type_computation_) { 1478 last_connection_change_ < last_effective_connection_type_computation_ &&
1479 (effective_connection_type_ !=
1480 NetworkQualityEstimator::EFFECTIVE_CONNECTION_TYPE_UNKNOWN ||
1481 effective_connection_type_algorithm_ !=
1482 EffectiveConnectionTypeAlgorithm::
1483 TRANSPORT_RTT_OR_DOWNSTREAM_THROUGHOUT)) {
1460 return; 1484 return;
1461 } 1485 }
1462 1486
1463 const EffectiveConnectionType past_type = effective_connection_type_; 1487 const EffectiveConnectionType past_type = effective_connection_type_;
1464 last_effective_connection_type_computation_ = now; 1488 last_effective_connection_type_computation_ = now;
1465 effective_connection_type_ = GetEffectiveConnectionType(); 1489 effective_connection_type_ = GetEffectiveConnectionType();
1466 1490
1467 if (past_type != effective_connection_type_) 1491 if (past_type != effective_connection_type_)
1468 NotifyObserversOfEffectiveConnectionTypeChanged(); 1492 NotifyObserversOfEffectiveConnectionTypeChanged();
1469 } 1493 }
1470 1494
1471 void NetworkQualityEstimator:: 1495 void NetworkQualityEstimator::
1472 NotifyObserversOfEffectiveConnectionTypeChanged() { 1496 NotifyObserversOfEffectiveConnectionTypeChanged() {
1473 DCHECK(thread_checker_.CalledOnValidThread()); 1497 DCHECK(thread_checker_.CalledOnValidThread());
1474 1498
1475 // TODO(tbansal): Add hysteresis in the notification. 1499 // TODO(tbansal): Add hysteresis in the notification.
1476 FOR_EACH_OBSERVER( 1500 FOR_EACH_OBSERVER(
1477 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, 1501 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_,
1478 OnEffectiveConnectionTypeChanged(effective_connection_type_)); 1502 OnEffectiveConnectionTypeChanged(effective_connection_type_));
1479 } 1503 }
1480 1504
1481 } // namespace net 1505 } // namespace net
OLDNEW
« no previous file with comments | « net/nqe/network_quality_estimator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698