| 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 11 matching lines...) Expand all Loading... |
| 22 #include "net/base/load_flags.h" | 22 #include "net/base/load_flags.h" |
| 23 #include "net/base/load_timing_info.h" | 23 #include "net/base/load_timing_info.h" |
| 24 #include "net/base/network_interfaces.h" | 24 #include "net/base/network_interfaces.h" |
| 25 #include "net/base/url_util.h" | 25 #include "net/base/url_util.h" |
| 26 #include "net/nqe/socket_watcher_factory.h" | 26 #include "net/nqe/socket_watcher_factory.h" |
| 27 #include "net/nqe/throughput_analyzer.h" | 27 #include "net/nqe/throughput_analyzer.h" |
| 28 #include "net/url_request/url_request.h" | 28 #include "net/url_request/url_request.h" |
| 29 #include "url/gurl.h" | 29 #include "url/gurl.h" |
| 30 | 30 |
| 31 #if defined(OS_ANDROID) | 31 #if defined(OS_ANDROID) |
| 32 #include "net/android/cellular_signal_strength.h" |
| 32 #include "net/android/network_library.h" | 33 #include "net/android/network_library.h" |
| 33 #endif // OS_ANDROID | 34 #endif // OS_ANDROID |
| 34 | 35 |
| 35 namespace { | 36 namespace { |
| 36 | 37 |
| 37 // Default value of the half life (in seconds) for computing time weighted | 38 // Default value of the half life (in seconds) for computing time weighted |
| 38 // percentiles. Every half life, the weight of all observations reduces by | 39 // percentiles. Every half life, the weight of all observations reduces by |
| 39 // half. Lowering the half life would reduce the weight of older values faster. | 40 // half. Lowering the half life would reduce the weight of older values faster. |
| 40 const int kDefaultHalfLifeSeconds = 60; | 41 const int kDefaultHalfLifeSeconds = 60; |
| 41 | 42 |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 effective_connection_type_recomputation_interval_( | 201 effective_connection_type_recomputation_interval_( |
| 201 base::TimeDelta::FromSeconds(15)), | 202 base::TimeDelta::FromSeconds(15)), |
| 202 last_connection_change_(tick_clock_->NowTicks()), | 203 last_connection_change_(tick_clock_->NowTicks()), |
| 203 current_network_id_( | 204 current_network_id_( |
| 204 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, | 205 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, |
| 205 std::string())), | 206 std::string())), |
| 206 downstream_throughput_kbps_observations_(weight_multiplier_per_second_), | 207 downstream_throughput_kbps_observations_(weight_multiplier_per_second_), |
| 207 rtt_observations_(weight_multiplier_per_second_), | 208 rtt_observations_(weight_multiplier_per_second_), |
| 208 external_estimate_provider_(std::move(external_estimates_provider)), | 209 external_estimate_provider_(std::move(external_estimates_provider)), |
| 209 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), | 210 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), |
| 211 min_rssi_since_connection_change_(INT32_MAX), |
| 212 max_rssi_since_connection_change_(INT32_MIN), |
| 210 weak_ptr_factory_(this) { | 213 weak_ptr_factory_(this) { |
| 211 static_assert(kDefaultHalfLifeSeconds > 0, | 214 static_assert(kDefaultHalfLifeSeconds > 0, |
| 212 "Default half life duration must be > 0"); | 215 "Default half life duration must be > 0"); |
| 213 static_assert(kMaximumNetworkQualityCacheSize > 0, | 216 static_assert(kMaximumNetworkQualityCacheSize > 0, |
| 214 "Size of the network quality cache must be > 0"); | 217 "Size of the network quality cache must be > 0"); |
| 215 // This limit should not be increased unless the logic for removing the | 218 // This limit should not be increased unless the logic for removing the |
| 216 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. | 219 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. |
| 217 static_assert(kMaximumNetworkQualityCacheSize <= 10, | 220 static_assert(kMaximumNetworkQualityCacheSize <= 10, |
| 218 "Size of the network quality cache must <= 10"); | 221 "Size of the network quality cache must <= 10"); |
| 219 | 222 |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 // possible to measure the accuracy by comparing the estimate with the | 442 // possible to measure the accuracy by comparing the estimate with the |
| 440 // observations received over intervals of varying durations. | 443 // observations received over intervals of varying durations. |
| 441 for (const base::TimeDelta& measuring_delay : | 444 for (const base::TimeDelta& measuring_delay : |
| 442 GetAccuracyRecordingIntervals()) { | 445 GetAccuracyRecordingIntervals()) { |
| 443 base::MessageLoop::current()->task_runner()->PostDelayedTask( | 446 base::MessageLoop::current()->task_runner()->PostDelayedTask( |
| 444 FROM_HERE, | 447 FROM_HERE, |
| 445 base::Bind(&NetworkQualityEstimator::RecordAccuracyAfterMainFrame, | 448 base::Bind(&NetworkQualityEstimator::RecordAccuracyAfterMainFrame, |
| 446 weak_ptr_factory_.GetWeakPtr(), measuring_delay), | 449 weak_ptr_factory_.GetWeakPtr(), measuring_delay), |
| 447 measuring_delay); | 450 measuring_delay); |
| 448 } | 451 } |
| 452 UpdateSignalStrength(); |
| 449 } | 453 } |
| 450 | 454 |
| 451 LoadTimingInfo load_timing_info; | 455 LoadTimingInfo load_timing_info; |
| 452 request.GetLoadTimingInfo(&load_timing_info); | 456 request.GetLoadTimingInfo(&load_timing_info); |
| 453 | 457 |
| 454 // If the load timing info is unavailable, it probably means that the request | 458 // If the load timing info is unavailable, it probably means that the request |
| 455 // did not go over the network. | 459 // did not go over the network. |
| 456 if (load_timing_info.send_start.is_null() || | 460 if (load_timing_info.send_start.is_null() || |
| 457 load_timing_info.receive_headers_end.is_null()) { | 461 load_timing_info.receive_headers_end.is_null()) { |
| 458 return; | 462 return; |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 RecordMetricsOnConnectionTypeChanged(); | 618 RecordMetricsOnConnectionTypeChanged(); |
| 615 | 619 |
| 616 // Write the estimates of the previous network to the cache. | 620 // Write the estimates of the previous network to the cache. |
| 617 CacheNetworkQualityEstimate(); | 621 CacheNetworkQualityEstimate(); |
| 618 | 622 |
| 619 // Clear the local state. | 623 // Clear the local state. |
| 620 last_connection_change_ = tick_clock_->NowTicks(); | 624 last_connection_change_ = tick_clock_->NowTicks(); |
| 621 peak_network_quality_ = nqe::internal::NetworkQuality(); | 625 peak_network_quality_ = nqe::internal::NetworkQuality(); |
| 622 downstream_throughput_kbps_observations_.Clear(); | 626 downstream_throughput_kbps_observations_.Clear(); |
| 623 rtt_observations_.Clear(); | 627 rtt_observations_.Clear(); |
| 628 |
| 629 #if defined(OS_ANDROID) |
| 630 if (NetworkChangeNotifier::IsConnectionCellular(current_network_id_.type)) { |
| 631 UMA_HISTOGRAM_BOOLEAN("NQE.CellularRSSIAvailable", |
| 632 min_rssi_since_connection_change_ != INT32_MAX && |
| 633 max_rssi_since_connection_change_ != INT32_MIN); |
| 634 } |
| 635 #endif // OS_ANDROID |
| 636 min_rssi_since_connection_change_ = INT32_MAX; |
| 637 max_rssi_since_connection_change_ = INT32_MIN; |
| 638 |
| 624 current_network_id_ = GetCurrentNetworkID(); | 639 current_network_id_ = GetCurrentNetworkID(); |
| 625 | 640 |
| 626 // Query the external estimate provider on certain connection types. Once the | 641 // Query the external estimate provider on certain connection types. Once the |
| 627 // updated estimates are available, OnUpdatedEstimateAvailable will be called | 642 // updated estimates are available, OnUpdatedEstimateAvailable will be called |
| 628 // by |external_estimate_provider_| with updated estimates. | 643 // by |external_estimate_provider_| with updated estimates. |
| 629 if (external_estimate_provider_ && | 644 if (external_estimate_provider_ && |
| 630 current_network_id_.type != NetworkChangeNotifier::CONNECTION_NONE && | 645 current_network_id_.type != NetworkChangeNotifier::CONNECTION_NONE && |
| 631 current_network_id_.type != NetworkChangeNotifier::CONNECTION_UNKNOWN && | 646 current_network_id_.type != NetworkChangeNotifier::CONNECTION_UNKNOWN && |
| 632 current_network_id_.type != NetworkChangeNotifier::CONNECTION_ETHERNET && | 647 current_network_id_.type != NetworkChangeNotifier::CONNECTION_ETHERNET && |
| 633 current_network_id_.type != NetworkChangeNotifier::CONNECTION_BLUETOOTH) { | 648 current_network_id_.type != NetworkChangeNotifier::CONNECTION_BLUETOOTH) { |
| 634 RecordExternalEstimateProviderMetrics( | 649 RecordExternalEstimateProviderMetrics( |
| 635 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERIED); | 650 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERIED); |
| 636 external_estimate_provider_->Update(); | 651 external_estimate_provider_->Update(); |
| 637 } | 652 } |
| 638 | 653 |
| 639 // Read any cached estimates for the new network. If cached estimates are | 654 // Read any cached estimates for the new network. If cached estimates are |
| 640 // unavailable, add the default estimates. | 655 // unavailable, add the default estimates. |
| 641 if (!ReadCachedNetworkQualityEstimate()) | 656 if (!ReadCachedNetworkQualityEstimate()) |
| 642 AddDefaultEstimates(); | 657 AddDefaultEstimates(); |
| 643 estimated_quality_at_last_main_frame_ = nqe::internal::NetworkQuality(); | 658 estimated_quality_at_last_main_frame_ = nqe::internal::NetworkQuality(); |
| 644 throughput_analyzer_->OnConnectionTypeChanged(); | 659 throughput_analyzer_->OnConnectionTypeChanged(); |
| 645 MaybeRecomputeEffectiveConnectionType(); | 660 MaybeRecomputeEffectiveConnectionType(); |
| 661 UpdateSignalStrength(); |
| 662 } |
| 663 |
| 664 void NetworkQualityEstimator::UpdateSignalStrength() { |
| 665 #if defined(OS_ANDROID) |
| 666 int32_t rssi; |
| 667 if (!android::cellular_signal_strength::GetRssiDbm(&rssi)) |
| 668 return; |
| 669 min_rssi_since_connection_change_ = |
| 670 std::min(min_rssi_since_connection_change_, rssi); |
| 671 max_rssi_since_connection_change_ = |
| 672 std::max(max_rssi_since_connection_change_, rssi); |
| 673 #endif // OS_ANDROID |
| 646 } | 674 } |
| 647 | 675 |
| 648 void NetworkQualityEstimator::RecordMetricsOnConnectionTypeChanged() const { | 676 void NetworkQualityEstimator::RecordMetricsOnConnectionTypeChanged() const { |
| 649 DCHECK(thread_checker_.CalledOnValidThread()); | 677 DCHECK(thread_checker_.CalledOnValidThread()); |
| 650 if (peak_network_quality_.http_rtt() != nqe::internal::InvalidRTT()) { | 678 if (peak_network_quality_.http_rtt() != nqe::internal::InvalidRTT()) { |
| 651 base::HistogramBase* rtt_histogram = | 679 base::HistogramBase* rtt_histogram = |
| 652 GetHistogram("FastestRTT.", current_network_id_.type, 10 * 1000); | 680 GetHistogram("FastestRTT.", current_network_id_.type, 10 * 1000); |
| 653 rtt_histogram->Add(peak_network_quality_.http_rtt().InMilliseconds()); | 681 rtt_histogram->Add(peak_network_quality_.http_rtt().InMilliseconds()); |
| 654 } | 682 } |
| 655 | 683 |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1191 NotifyObserversOfEffectiveConnectionTypeChanged() { | 1219 NotifyObserversOfEffectiveConnectionTypeChanged() { |
| 1192 DCHECK(thread_checker_.CalledOnValidThread()); | 1220 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1193 | 1221 |
| 1194 // TODO(tbansal): Add hysteresis in the notification. | 1222 // TODO(tbansal): Add hysteresis in the notification. |
| 1195 FOR_EACH_OBSERVER( | 1223 FOR_EACH_OBSERVER( |
| 1196 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, | 1224 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, |
| 1197 OnEffectiveConnectionTypeChanged(effective_connection_type_)); | 1225 OnEffectiveConnectionTypeChanged(effective_connection_type_)); |
| 1198 } | 1226 } |
| 1199 | 1227 |
| 1200 } // namespace net | 1228 } // namespace net |
| OLD | NEW |