| OLD | NEW |
| 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 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 EffectiveConnectionTypeAlgorithm:: | 246 EffectiveConnectionTypeAlgorithm:: |
| 247 HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT}, | 247 HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT}, |
| 248 {"TransportRTTOrDownstreamThroughput", | 248 {"TransportRTTOrDownstreamThroughput", |
| 249 EffectiveConnectionTypeAlgorithm:: | 249 EffectiveConnectionTypeAlgorithm:: |
| 250 TRANSPORT_RTT_OR_DOWNSTREAM_THROUGHOUT}}), | 250 TRANSPORT_RTT_OR_DOWNSTREAM_THROUGHOUT}}), |
| 251 params_(variation_params), | 251 params_(variation_params), |
| 252 use_localhost_requests_(use_local_host_requests_for_tests), | 252 use_localhost_requests_(use_local_host_requests_for_tests), |
| 253 use_small_responses_(use_smaller_responses_for_tests), | 253 use_small_responses_(use_smaller_responses_for_tests), |
| 254 disable_offline_check_(false), | 254 disable_offline_check_(false), |
| 255 add_default_platform_observations_(add_default_platform_observations), | 255 add_default_platform_observations_(add_default_platform_observations), |
| 256 weight_multiplier_per_second_(params_.GetWeightMultiplierPerSecond()), | |
| 257 weight_multiplier_per_dbm_(params_.GetWeightMultiplierPerDbm()), | |
| 258 effective_connection_type_algorithm_( | 256 effective_connection_type_algorithm_( |
| 259 algorithm_name_to_enum_.find( | 257 algorithm_name_to_enum_.find( |
| 260 params_.GetEffectiveConnectionTypeAlgorithm()) == | 258 params_.GetEffectiveConnectionTypeAlgorithm()) == |
| 261 algorithm_name_to_enum_.end() | 259 algorithm_name_to_enum_.end() |
| 262 ? kDefaultEffectiveConnectionTypeAlgorithm | 260 ? kDefaultEffectiveConnectionTypeAlgorithm |
| 263 : algorithm_name_to_enum_ | 261 : algorithm_name_to_enum_ |
| 264 .find(params_.GetEffectiveConnectionTypeAlgorithm()) | 262 .find(params_.GetEffectiveConnectionTypeAlgorithm()) |
| 265 ->second), | 263 ->second), |
| 266 tick_clock_(new base::DefaultTickClock()), | 264 tick_clock_(new base::DefaultTickClock()), |
| 267 last_connection_change_(tick_clock_->NowTicks()), | 265 last_connection_change_(tick_clock_->NowTicks()), |
| 268 current_network_id_(nqe::internal::NetworkID( | 266 current_network_id_(nqe::internal::NetworkID( |
| 269 NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, | 267 NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, |
| 270 std::string())), | 268 std::string())), |
| 271 downstream_throughput_kbps_observations_(weight_multiplier_per_second_, | 269 downstream_throughput_kbps_observations_( |
| 272 weight_multiplier_per_dbm_), | 270 params_.weight_multiplier_per_second(), |
| 273 rtt_observations_(weight_multiplier_per_second_, | 271 params_.weight_multiplier_per_dbm()), |
| 274 weight_multiplier_per_dbm_), | 272 rtt_observations_(params_.weight_multiplier_per_second(), |
| 273 params_.weight_multiplier_per_dbm()), |
| 275 effective_connection_type_at_last_main_frame_( | 274 effective_connection_type_at_last_main_frame_( |
| 276 EFFECTIVE_CONNECTION_TYPE_UNKNOWN), | 275 EFFECTIVE_CONNECTION_TYPE_UNKNOWN), |
| 277 external_estimate_provider_(std::move(external_estimates_provider)), | 276 external_estimate_provider_(std::move(external_estimates_provider)), |
| 278 effective_connection_type_recomputation_interval_( | 277 effective_connection_type_recomputation_interval_( |
| 279 base::TimeDelta::FromSeconds(10)), | 278 base::TimeDelta::FromSeconds(10)), |
| 280 rtt_observations_size_at_last_ect_computation_(0), | 279 rtt_observations_size_at_last_ect_computation_(0), |
| 281 throughput_observations_size_at_last_ect_computation_(0), | 280 throughput_observations_size_at_last_ect_computation_(0), |
| 282 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), | 281 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), |
| 283 signal_strength_dbm_(INT32_MIN), | 282 signal_strength_dbm_(INT32_MIN), |
| 284 min_signal_strength_since_connection_change_(INT32_MAX), | 283 min_signal_strength_since_connection_change_(INT32_MAX), |
| 285 max_signal_strength_since_connection_change_(INT32_MIN), | 284 max_signal_strength_since_connection_change_(INT32_MIN), |
| 286 correlation_uma_logging_probability_( | |
| 287 params_.correlation_uma_logging_probability()), | |
| 288 forced_effective_connection_type_set_( | |
| 289 params_.forced_effective_connection_type_set()), | |
| 290 forced_effective_connection_type_( | |
| 291 params_.forced_effective_connection_type()), | |
| 292 persistent_cache_reading_enabled_( | |
| 293 params_.persistent_cache_reading_enabled()), | |
| 294 event_creator_(net_log), | 285 event_creator_(net_log), |
| 295 disallowed_observation_sources_for_http_( | 286 disallowed_observation_sources_for_http_( |
| 296 {NETWORK_QUALITY_OBSERVATION_SOURCE_TCP, | 287 {NETWORK_QUALITY_OBSERVATION_SOURCE_TCP, |
| 297 NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC, | 288 NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC, |
| 298 NETWORK_QUALITY_OBSERVATION_SOURCE_TRANSPORT_CACHED_ESTIMATE, | 289 NETWORK_QUALITY_OBSERVATION_SOURCE_TRANSPORT_CACHED_ESTIMATE, |
| 299 NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_TRANSPORT_FROM_PLATFORM}), | 290 NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_TRANSPORT_FROM_PLATFORM}), |
| 300 disallowed_observation_sources_for_transport_( | 291 disallowed_observation_sources_for_transport_( |
| 301 {NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP, | 292 {NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP, |
| 302 NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE, | 293 NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE, |
| 303 NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE, | 294 NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 329 AddDefaultEstimates(); | 320 AddDefaultEstimates(); |
| 330 | 321 |
| 331 throughput_analyzer_.reset(new nqe::internal::ThroughputAnalyzer( | 322 throughput_analyzer_.reset(new nqe::internal::ThroughputAnalyzer( |
| 332 base::ThreadTaskRunnerHandle::Get(), | 323 base::ThreadTaskRunnerHandle::Get(), |
| 333 base::Bind(&NetworkQualityEstimator::OnNewThroughputObservationAvailable, | 324 base::Bind(&NetworkQualityEstimator::OnNewThroughputObservationAvailable, |
| 334 base::Unretained(this)), | 325 base::Unretained(this)), |
| 335 use_localhost_requests_, use_smaller_responses_for_tests)); | 326 use_localhost_requests_, use_smaller_responses_for_tests)); |
| 336 | 327 |
| 337 watcher_factory_.reset(new nqe::internal::SocketWatcherFactory( | 328 watcher_factory_.reset(new nqe::internal::SocketWatcherFactory( |
| 338 base::ThreadTaskRunnerHandle::Get(), | 329 base::ThreadTaskRunnerHandle::Get(), |
| 339 params_.GetMinSocketWatcherNotificationInterval(), | 330 params_.min_socket_watcher_notification_interval(), |
| 340 base::Bind(&NetworkQualityEstimator::OnUpdatedRTTAvailable, | 331 base::Bind(&NetworkQualityEstimator::OnUpdatedRTTAvailable, |
| 341 base::Unretained(this)), | 332 base::Unretained(this)), |
| 342 tick_clock_.get())); | 333 tick_clock_.get())); |
| 343 | 334 |
| 344 // Record accuracy after a 15 second interval. The values used here must | 335 // Record accuracy after a 15 second interval. The values used here must |
| 345 // remain in sync with the suffixes specified in | 336 // remain in sync with the suffixes specified in |
| 346 // tools/metrics/histograms/histograms.xml. | 337 // tools/metrics/histograms/histograms.xml. |
| 347 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(15)); | 338 accuracy_recording_intervals_.push_back(base::TimeDelta::FromSeconds(15)); |
| 348 | 339 |
| 349 for (int i = 0; i < STATISTIC_LAST; ++i) | 340 for (int i = 0; i < STATISTIC_LAST; ++i) |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 return; | 612 return; |
| 622 | 613 |
| 623 throughput_analyzer_->NotifyRequestCompleted(request); | 614 throughput_analyzer_->NotifyRequestCompleted(request); |
| 624 RecordCorrelationMetric(request, net_error); | 615 RecordCorrelationMetric(request, net_error); |
| 625 } | 616 } |
| 626 | 617 |
| 627 void NetworkQualityEstimator::RecordCorrelationMetric(const URLRequest& request, | 618 void NetworkQualityEstimator::RecordCorrelationMetric(const URLRequest& request, |
| 628 int net_error) const { | 619 int net_error) const { |
| 629 DCHECK(thread_checker_.CalledOnValidThread()); | 620 DCHECK(thread_checker_.CalledOnValidThread()); |
| 630 | 621 |
| 631 // The histogram is recorded with probability | 622 // The histogram is recorded randomly to reduce overhead involved with sparse |
| 632 // |correlation_uma_logging_probability_| to reduce overhead involved with | 623 // histograms. Furthermore, recording the correlation on each request is |
| 633 // sparse histograms. Also, recording the correlation on each request is | |
| 634 // unnecessary. | 624 // unnecessary. |
| 635 if (RandDouble() >= correlation_uma_logging_probability_) | 625 if (RandDouble() >= params_.correlation_uma_logging_probability()) |
| 636 return; | 626 return; |
| 637 | 627 |
| 638 if (request.response_info().was_cached || | 628 if (request.response_info().was_cached || |
| 639 !request.response_info().network_accessed) { | 629 !request.response_info().network_accessed) { |
| 640 return; | 630 return; |
| 641 } | 631 } |
| 642 | 632 |
| 643 LoadTimingInfo load_timing_info; | 633 LoadTimingInfo load_timing_info; |
| 644 request.GetLoadTimingInfo(&load_timing_info); | 634 request.GetLoadTimingInfo(&load_timing_info); |
| 645 // If the load timing info is unavailable, it probably means that the request | 635 // If the load timing info is unavailable, it probably means that the request |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 844 last_effective_connection_type_computation_, | 834 last_effective_connection_type_computation_, |
| 845 network_quality_, effective_connection_type_)); | 835 network_quality_, effective_connection_type_)); |
| 846 | 836 |
| 847 // Clear the local state. | 837 // Clear the local state. |
| 848 last_connection_change_ = tick_clock_->NowTicks(); | 838 last_connection_change_ = tick_clock_->NowTicks(); |
| 849 peak_network_quality_ = nqe::internal::NetworkQuality(); | 839 peak_network_quality_ = nqe::internal::NetworkQuality(); |
| 850 downstream_throughput_kbps_observations_.Clear(); | 840 downstream_throughput_kbps_observations_.Clear(); |
| 851 rtt_observations_.Clear(); | 841 rtt_observations_.Clear(); |
| 852 | 842 |
| 853 #if defined(OS_ANDROID) | 843 #if defined(OS_ANDROID) |
| 854 if (weight_multiplier_per_dbm_ < 1.0 && | 844 if (params_.weight_multiplier_per_dbm() < 1.0 && |
| 855 NetworkChangeNotifier::IsConnectionCellular(current_network_id_.type)) { | 845 NetworkChangeNotifier::IsConnectionCellular(current_network_id_.type)) { |
| 856 UMA_HISTOGRAM_BOOLEAN( | 846 UMA_HISTOGRAM_BOOLEAN( |
| 857 "NQE.CellularSignalStrengthAvailable", | 847 "NQE.CellularSignalStrengthAvailable", |
| 858 min_signal_strength_since_connection_change_ != INT32_MAX && | 848 min_signal_strength_since_connection_change_ != INT32_MAX && |
| 859 max_signal_strength_since_connection_change_ != INT32_MIN); | 849 max_signal_strength_since_connection_change_ != INT32_MIN); |
| 860 | 850 |
| 861 if (min_signal_strength_since_connection_change_ != INT32_MAX && | 851 if (min_signal_strength_since_connection_change_ != INT32_MAX && |
| 862 max_signal_strength_since_connection_change_ != INT32_MIN) { | 852 max_signal_strength_since_connection_change_ != INT32_MIN) { |
| 863 UMA_HISTOGRAM_COUNTS_100( | 853 UMA_HISTOGRAM_COUNTS_100( |
| 864 "NQE.CellularSignalStrengthDifference", | 854 "NQE.CellularSignalStrengthDifference", |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 current_network_id_.type != NetworkChangeNotifier::CONNECTION_ETHERNET && | 896 current_network_id_.type != NetworkChangeNotifier::CONNECTION_ETHERNET && |
| 907 current_network_id_.type != NetworkChangeNotifier::CONNECTION_BLUETOOTH) { | 897 current_network_id_.type != NetworkChangeNotifier::CONNECTION_BLUETOOTH) { |
| 908 RecordExternalEstimateProviderMetrics( | 898 RecordExternalEstimateProviderMetrics( |
| 909 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERIED); | 899 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERIED); |
| 910 external_estimate_provider_->Update(); | 900 external_estimate_provider_->Update(); |
| 911 } | 901 } |
| 912 } | 902 } |
| 913 | 903 |
| 914 void NetworkQualityEstimator::UpdateSignalStrength() { | 904 void NetworkQualityEstimator::UpdateSignalStrength() { |
| 915 #if defined(OS_ANDROID) | 905 #if defined(OS_ANDROID) |
| 916 if (weight_multiplier_per_dbm_ >= 1.0 || | 906 if (params_.weight_multiplier_per_dbm() >= 1.0 || |
| 917 !NetworkChangeNotifier::IsConnectionCellular(current_network_id_.type) || | 907 !NetworkChangeNotifier::IsConnectionCellular(current_network_id_.type) || |
| 918 !android::cellular_signal_strength::GetSignalStrengthDbm( | 908 !android::cellular_signal_strength::GetSignalStrengthDbm( |
| 919 &signal_strength_dbm_)) { | 909 &signal_strength_dbm_)) { |
| 920 signal_strength_dbm_ = INT32_MIN; | 910 signal_strength_dbm_ = INT32_MIN; |
| 921 } | 911 } |
| 922 min_signal_strength_since_connection_change_ = std::min( | 912 min_signal_strength_since_connection_change_ = std::min( |
| 923 min_signal_strength_since_connection_change_, signal_strength_dbm_); | 913 min_signal_strength_since_connection_change_, signal_strength_dbm_); |
| 924 max_signal_strength_since_connection_change_ = std::max( | 914 max_signal_strength_since_connection_change_ = std::max( |
| 925 max_signal_strength_since_connection_change_, signal_strength_dbm_); | 915 max_signal_strength_since_connection_change_, signal_strength_dbm_); |
| 926 #endif // OS_ANDROID | 916 #endif // OS_ANDROID |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1202 NetworkQualityEstimator::MetricUsage downstream_throughput_kbps_metric, | 1192 NetworkQualityEstimator::MetricUsage downstream_throughput_kbps_metric, |
| 1203 base::TimeDelta* http_rtt, | 1193 base::TimeDelta* http_rtt, |
| 1204 base::TimeDelta* transport_rtt, | 1194 base::TimeDelta* transport_rtt, |
| 1205 int32_t* downstream_throughput_kbps) const { | 1195 int32_t* downstream_throughput_kbps) const { |
| 1206 DCHECK(thread_checker_.CalledOnValidThread()); | 1196 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1207 | 1197 |
| 1208 *http_rtt = nqe::internal::InvalidRTT(); | 1198 *http_rtt = nqe::internal::InvalidRTT(); |
| 1209 *transport_rtt = nqe::internal::InvalidRTT(); | 1199 *transport_rtt = nqe::internal::InvalidRTT(); |
| 1210 *downstream_throughput_kbps = nqe::internal::kInvalidThroughput; | 1200 *downstream_throughput_kbps = nqe::internal::kInvalidThroughput; |
| 1211 | 1201 |
| 1212 if (forced_effective_connection_type_set_) | 1202 if (params_.forced_effective_connection_type()) |
| 1213 return forced_effective_connection_type_; | 1203 return params_.forced_effective_connection_type().value(); |
| 1214 | 1204 |
| 1215 // If the device is currently offline, then return | 1205 // If the device is currently offline, then return |
| 1216 // EFFECTIVE_CONNECTION_TYPE_OFFLINE. | 1206 // EFFECTIVE_CONNECTION_TYPE_OFFLINE. |
| 1217 | 1207 |
| 1218 if (current_network_id_.type == NetworkChangeNotifier::CONNECTION_NONE && | 1208 if (current_network_id_.type == NetworkChangeNotifier::CONNECTION_NONE && |
| 1219 !disable_offline_check_) { | 1209 !disable_offline_check_) { |
| 1220 return EFFECTIVE_CONNECTION_TYPE_OFFLINE; | 1210 return EFFECTIVE_CONNECTION_TYPE_OFFLINE; |
| 1221 } | 1211 } |
| 1222 | 1212 |
| 1223 if (!GetRecentHttpRTT(start_time, http_rtt)) | 1213 if (!GetRecentHttpRTT(start_time, http_rtt)) |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1465 | 1455 |
| 1466 if (network_id.type == NetworkChangeNotifier::GetConnectionType()) | 1456 if (network_id.type == NetworkChangeNotifier::GetConnectionType()) |
| 1467 return network_id; | 1457 return network_id; |
| 1468 } | 1458 } |
| 1469 NOTREACHED(); | 1459 NOTREACHED(); |
| 1470 } | 1460 } |
| 1471 | 1461 |
| 1472 bool NetworkQualityEstimator::ReadCachedNetworkQualityEstimate() { | 1462 bool NetworkQualityEstimator::ReadCachedNetworkQualityEstimate() { |
| 1473 DCHECK(thread_checker_.CalledOnValidThread()); | 1463 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1474 | 1464 |
| 1475 if (!persistent_cache_reading_enabled_) | 1465 if (!params_.persistent_cache_reading_enabled()) |
| 1476 return false; | 1466 return false; |
| 1477 | 1467 |
| 1478 nqe::internal::CachedNetworkQuality cached_network_quality; | 1468 nqe::internal::CachedNetworkQuality cached_network_quality; |
| 1479 | 1469 |
| 1480 const bool cached_estimate_available = network_quality_store_->GetById( | 1470 const bool cached_estimate_available = network_quality_store_->GetById( |
| 1481 current_network_id_, &cached_network_quality); | 1471 current_network_id_, &cached_network_quality); |
| 1482 if (network_quality_store_->EligibleForCaching(current_network_id_)) { | 1472 if (network_quality_store_->EligibleForCaching(current_network_id_)) { |
| 1483 UMA_HISTOGRAM_BOOLEAN("NQE.CachedNetworkQualityAvailable", | 1473 UMA_HISTOGRAM_BOOLEAN("NQE.CachedNetworkQualityAvailable", |
| 1484 cached_estimate_available); | 1474 cached_estimate_available); |
| 1485 } | 1475 } |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1772 network_quality_store_->Add(it.first, cached_network_quality); | 1762 network_quality_store_->Add(it.first, cached_network_quality); |
| 1773 MaybeUpdateNetworkQualityFromCache(it.first, cached_network_quality); | 1763 MaybeUpdateNetworkQualityFromCache(it.first, cached_network_quality); |
| 1774 } | 1764 } |
| 1775 } | 1765 } |
| 1776 | 1766 |
| 1777 void NetworkQualityEstimator::MaybeUpdateNetworkQualityFromCache( | 1767 void NetworkQualityEstimator::MaybeUpdateNetworkQualityFromCache( |
| 1778 const nqe::internal::NetworkID& network_id, | 1768 const nqe::internal::NetworkID& network_id, |
| 1779 const nqe::internal::CachedNetworkQuality& cached_network_quality) { | 1769 const nqe::internal::CachedNetworkQuality& cached_network_quality) { |
| 1780 DCHECK(thread_checker_.CalledOnValidThread()); | 1770 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1781 | 1771 |
| 1782 if (!persistent_cache_reading_enabled_) | 1772 if (!params_.persistent_cache_reading_enabled()) |
| 1783 return; | 1773 return; |
| 1784 if (network_id != current_network_id_) | 1774 if (network_id != current_network_id_) |
| 1785 return; | 1775 return; |
| 1786 | 1776 |
| 1787 // Since the cached network quality is for the current network, add it to | 1777 // Since the cached network quality is for the current network, add it to |
| 1788 // the current observations. | 1778 // the current observations. |
| 1789 RttObservation http_rtt_observation( | 1779 RttObservation http_rtt_observation( |
| 1790 cached_network_quality.network_quality().http_rtt(), | 1780 cached_network_quality.network_quality().http_rtt(), |
| 1791 base::TimeTicks::Now(), INT32_MIN, | 1781 base::TimeTicks::Now(), INT32_MIN, |
| 1792 NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE); | 1782 NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1840 return base::Optional<base::TimeDelta>(); | 1830 return base::Optional<base::TimeDelta>(); |
| 1841 } | 1831 } |
| 1842 | 1832 |
| 1843 base::Optional<int32_t> | 1833 base::Optional<int32_t> |
| 1844 NetworkQualityEstimator::NetworkQualityProvider::GetDownstreamThroughputKbps() | 1834 NetworkQualityEstimator::NetworkQualityProvider::GetDownstreamThroughputKbps() |
| 1845 const { | 1835 const { |
| 1846 return base::Optional<int32_t>(); | 1836 return base::Optional<int32_t>(); |
| 1847 } | 1837 } |
| 1848 | 1838 |
| 1849 } // namespace net | 1839 } // namespace net |
| OLD | NEW |