| 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 #ifndef NET_NQE_NETWORK_QUALITY_ESTIMATOR_H_ | 5 #ifndef NET_NQE_NETWORK_QUALITY_ESTIMATOR_H_ |
| 6 #define NET_NQE_NETWORK_QUALITY_ESTIMATOR_H_ | 6 #define NET_NQE_NETWORK_QUALITY_ESTIMATOR_H_ |
| 7 | 7 |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <map> | 10 #include <map> |
| 11 #include <memory> | 11 #include <memory> |
| 12 #include <string> | 12 #include <string> |
| 13 #include <tuple> | |
| 14 | 13 |
| 15 #include "base/compiler_specific.h" | 14 #include "base/compiler_specific.h" |
| 16 #include "base/gtest_prod_util.h" | 15 #include "base/gtest_prod_util.h" |
| 17 #include "base/macros.h" | 16 #include "base/macros.h" |
| 18 #include "base/memory/ref_counted.h" | 17 #include "base/memory/ref_counted.h" |
| 19 #include "base/memory/weak_ptr.h" | 18 #include "base/memory/weak_ptr.h" |
| 20 #include "base/observer_list.h" | 19 #include "base/observer_list.h" |
| 21 #include "base/threading/thread_checker.h" | 20 #include "base/threading/thread_checker.h" |
| 22 #include "base/time/time.h" | 21 #include "base/time/time.h" |
| 23 #include "net/base/net_export.h" | 22 #include "net/base/net_export.h" |
| 24 #include "net/base/network_change_notifier.h" | 23 #include "net/base/network_change_notifier.h" |
| 25 #include "net/nqe/cached_network_quality.h" | 24 #include "net/nqe/cached_network_quality.h" |
| 26 #include "net/nqe/external_estimate_provider.h" | 25 #include "net/nqe/external_estimate_provider.h" |
| 26 #include "net/nqe/network_id.h" |
| 27 #include "net/nqe/network_qualities_manager.h" |
| 27 #include "net/nqe/network_quality.h" | 28 #include "net/nqe/network_quality.h" |
| 28 #include "net/nqe/network_quality_observation.h" | 29 #include "net/nqe/network_quality_observation.h" |
| 29 #include "net/nqe/network_quality_observation_source.h" | 30 #include "net/nqe/network_quality_observation_source.h" |
| 30 #include "net/nqe/observation_buffer.h" | 31 #include "net/nqe/observation_buffer.h" |
| 31 #include "net/socket/socket_performance_watcher_factory.h" | 32 #include "net/socket/socket_performance_watcher_factory.h" |
| 32 | 33 |
| 33 namespace base { | 34 namespace base { |
| 34 class TickClock; | 35 class TickClock; |
| 35 } // namespace base | 36 } // namespace base |
| 36 | 37 |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 // HTTP server and allows the requests to local host to be used for network | 232 // HTTP server and allows the requests to local host to be used for network |
| 232 // quality estimation. | 233 // quality estimation. |
| 233 void SetUseLocalHostRequestsForTesting(bool use_localhost_requests); | 234 void SetUseLocalHostRequestsForTesting(bool use_localhost_requests); |
| 234 | 235 |
| 235 // |use_smaller_responses_for_tests| should only be true when testing. | 236 // |use_smaller_responses_for_tests| should only be true when testing. |
| 236 // Allows the responses smaller than |kMinTransferSizeInBits| to be used for | 237 // Allows the responses smaller than |kMinTransferSizeInBits| to be used for |
| 237 // network quality estimation. | 238 // network quality estimation. |
| 238 void SetUseSmallResponsesForTesting(bool use_small_responses); | 239 void SetUseSmallResponsesForTesting(bool use_small_responses); |
| 239 | 240 |
| 240 protected: | 241 protected: |
| 241 // NetworkID is used to uniquely identify a network. | |
| 242 // For the purpose of network quality estimation and caching, a network is | |
| 243 // uniquely identified by a combination of |type| and | |
| 244 // |id|. This approach is unable to distinguish networks with | |
| 245 // same name (e.g., different Wi-Fi networks with same SSID). | |
| 246 // This is a protected member to expose it to tests. | |
| 247 struct NET_EXPORT_PRIVATE NetworkID { | |
| 248 NetworkID(NetworkChangeNotifier::ConnectionType type, const std::string& id) | |
| 249 : type(type), id(id) {} | |
| 250 NetworkID(const NetworkID& other) : type(other.type), id(other.id) {} | |
| 251 ~NetworkID() {} | |
| 252 | |
| 253 NetworkID& operator=(const NetworkID& other) { | |
| 254 type = other.type; | |
| 255 id = other.id; | |
| 256 return *this; | |
| 257 } | |
| 258 | |
| 259 // Overloaded because NetworkID is used as key in a map. | |
| 260 bool operator<(const NetworkID& other) const { | |
| 261 return std::tie(type, id) < std::tie(other.type, other.id); | |
| 262 } | |
| 263 | |
| 264 // Connection type of the network. | |
| 265 NetworkChangeNotifier::ConnectionType type; | |
| 266 | |
| 267 // Name of this network. This is set to: | |
| 268 // - Wi-Fi SSID if the device is connected to a Wi-Fi access point and the | |
| 269 // SSID name is available, or | |
| 270 // - MCC/MNC code of the cellular carrier if the device is connected to a | |
| 271 // cellular network, or | |
| 272 // - "Ethernet" in case the device is connected to ethernet. | |
| 273 // - An empty string in all other cases or if the network name is not | |
| 274 // exposed by platform APIs. | |
| 275 std::string id; | |
| 276 }; | |
| 277 | |
| 278 // Returns true if the cached network quality estimate was successfully read. | |
| 279 bool ReadCachedNetworkQualityEstimate(); | |
| 280 | |
| 281 // NetworkChangeNotifier::ConnectionTypeObserver implementation: | 242 // NetworkChangeNotifier::ConnectionTypeObserver implementation: |
| 282 void OnConnectionTypeChanged( | 243 void OnConnectionTypeChanged( |
| 283 NetworkChangeNotifier::ConnectionType type) override; | 244 NetworkChangeNotifier::ConnectionType type) override; |
| 284 | 245 |
| 285 // ExternalEstimateProvider::UpdatedEstimateObserver implementation. | 246 // ExternalEstimateProvider::UpdatedEstimateObserver implementation. |
| 286 void OnUpdatedEstimateAvailable(const base::TimeDelta& rtt, | 247 void OnUpdatedEstimateAvailable(const base::TimeDelta& rtt, |
| 287 int32_t downstream_throughput_kbps, | 248 int32_t downstream_throughput_kbps, |
| 288 int32_t upstream_throughput_kbps) override; | 249 int32_t upstream_throughput_kbps) override; |
| 289 | 250 |
| 290 // Returns true if the RTT is available and sets |rtt| to the RTT estimated at | 251 // Returns true if the RTT is available and sets |rtt| to the RTT estimated at |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 void SetTickClockForTesting(std::unique_ptr<base::TickClock> tick_clock); | 306 void SetTickClockForTesting(std::unique_ptr<base::TickClock> tick_clock); |
| 346 | 307 |
| 347 private: | 308 private: |
| 348 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, StoreObservations); | 309 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, StoreObservations); |
| 349 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestAddObservation); | 310 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestAddObservation); |
| 350 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, ObtainOperatingParams); | 311 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, ObtainOperatingParams); |
| 351 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, | 312 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, |
| 352 ObtainAlgorithmToUseFromParams); | 313 ObtainAlgorithmToUseFromParams); |
| 353 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, HalfLifeParam); | 314 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, HalfLifeParam); |
| 354 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, ComputedPercentiles); | 315 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, ComputedPercentiles); |
| 355 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestCaching); | |
| 356 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, | |
| 357 TestLRUCacheMaximumSize); | |
| 358 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestGetMetricsSince); | 316 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestGetMetricsSince); |
| 359 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, | 317 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, |
| 360 TestExternalEstimateProviderMergeEstimates); | 318 TestExternalEstimateProviderMergeEstimates); |
| 361 | 319 |
| 362 // Value of round trip time observations is in base::TimeDelta. | 320 // Value of round trip time observations is in base::TimeDelta. |
| 363 typedef nqe::internal::Observation<base::TimeDelta> RttObservation; | 321 typedef nqe::internal::Observation<base::TimeDelta> RttObservation; |
| 364 typedef nqe::internal::ObservationBuffer<base::TimeDelta> | 322 typedef nqe::internal::ObservationBuffer<base::TimeDelta> |
| 365 RttObservationBuffer; | 323 RttObservationBuffer; |
| 366 | 324 |
| 367 // Value of throughput observations is in kilobits per second. | 325 // Value of throughput observations is in kilobits per second. |
| 368 typedef nqe::internal::Observation<int32_t> ThroughputObservation; | 326 typedef nqe::internal::Observation<int32_t> ThroughputObservation; |
| 369 typedef nqe::internal::ObservationBuffer<int32_t> ThroughputObservationBuffer; | 327 typedef nqe::internal::ObservationBuffer<int32_t> ThroughputObservationBuffer; |
| 370 | 328 |
| 371 // This does not use a unordered_map or hash_map for code simplicity (key just | |
| 372 // implements operator<, rather than hash and equality) and because the map is | |
| 373 // tiny. | |
| 374 typedef std::map<NetworkID, nqe::internal::CachedNetworkQuality> | |
| 375 CachedNetworkQualities; | |
| 376 | |
| 377 // Algorithms supported by network quality estimator for computing effective | 329 // Algorithms supported by network quality estimator for computing effective |
| 378 // connection type. | 330 // connection type. |
| 379 enum class EffectiveConnectionTypeAlgorithm { | 331 enum class EffectiveConnectionTypeAlgorithm { |
| 380 HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT = 0, | 332 HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT = 0, |
| 381 TRANSPORT_RTT_OR_DOWNSTREAM_THROUGHOUT, | 333 TRANSPORT_RTT_OR_DOWNSTREAM_THROUGHOUT, |
| 382 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST | 334 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST |
| 383 }; | 335 }; |
| 384 | 336 |
| 385 // Defines how a metric (e.g, transport RTT) should be used when computing | 337 // Defines how a metric (e.g, transport RTT) should be used when computing |
| 386 // the effective connection type. | 338 // the effective connection type. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 409 EffectiveConnectionTypeAlgorithm::HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT; | 361 EffectiveConnectionTypeAlgorithm::HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT; |
| 410 | 362 |
| 411 // Minimum valid value of the variation parameter that holds RTT (in | 363 // Minimum valid value of the variation parameter that holds RTT (in |
| 412 // milliseconds) values. | 364 // milliseconds) values. |
| 413 static const int kMinimumRTTVariationParameterMsec = 1; | 365 static const int kMinimumRTTVariationParameterMsec = 1; |
| 414 | 366 |
| 415 // Minimum valid value of the variation parameter that holds throughput (in | 367 // Minimum valid value of the variation parameter that holds throughput (in |
| 416 // kilobits per second) values. | 368 // kilobits per second) values. |
| 417 static const int kMinimumThroughputVariationParameterKbps = 1; | 369 static const int kMinimumThroughputVariationParameterKbps = 1; |
| 418 | 370 |
| 419 // Maximum size of the cache that holds network quality estimates. | |
| 420 // Smaller size may reduce the cache hit rate due to frequent evictions. | |
| 421 // Larger size may affect performance. | |
| 422 static const size_t kMaximumNetworkQualityCacheSize = 10; | |
| 423 | |
| 424 // Returns the RTT value to be used when the valid RTT is unavailable. Readers | 371 // Returns the RTT value to be used when the valid RTT is unavailable. Readers |
| 425 // should discard RTT if it is set to the value returned by |InvalidRTT()|. | 372 // should discard RTT if it is set to the value returned by |InvalidRTT()|. |
| 426 static const base::TimeDelta InvalidRTT(); | 373 static const base::TimeDelta InvalidRTT(); |
| 427 | 374 |
| 428 // Records UMA when there is a change in connection type. | 375 // Records UMA when there is a change in connection type. |
| 429 void RecordMetricsOnConnectionTypeChanged() const; | 376 void RecordMetricsOnConnectionTypeChanged() const; |
| 430 | 377 |
| 431 // Records UMA on main frame requests. | 378 // Records UMA on main frame requests. |
| 432 void RecordMetricsOnMainFrameRequest() const; | 379 void RecordMetricsOnMainFrameRequest() const; |
| 433 | 380 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 const std::vector<NetworkQualityObservationSource>& | 415 const std::vector<NetworkQualityObservationSource>& |
| 469 disallowed_observation_sources, | 416 disallowed_observation_sources, |
| 470 const base::TimeTicks& start_time, | 417 const base::TimeTicks& start_time, |
| 471 int percentile) const; | 418 int percentile) const; |
| 472 int32_t GetDownlinkThroughputKbpsEstimateInternal( | 419 int32_t GetDownlinkThroughputKbpsEstimateInternal( |
| 473 const base::TimeTicks& start_time, | 420 const base::TimeTicks& start_time, |
| 474 int percentile) const; | 421 int percentile) const; |
| 475 | 422 |
| 476 // Returns the current network ID checking by calling the platform APIs. | 423 // Returns the current network ID checking by calling the platform APIs. |
| 477 // Virtualized for testing. | 424 // Virtualized for testing. |
| 478 virtual NetworkID GetCurrentNetworkID() const; | 425 virtual nqe::internal::NetworkID GetCurrentNetworkID() const; |
| 479 | |
| 480 // Writes the estimated quality of the current network to the cache. | |
| 481 void CacheNetworkQualityEstimate(); | |
| 482 | 426 |
| 483 void NotifyObserversOfRTT(const RttObservation& observation); | 427 void NotifyObserversOfRTT(const RttObservation& observation); |
| 484 | 428 |
| 485 void NotifyObserversOfThroughput(const ThroughputObservation& observation); | 429 void NotifyObserversOfThroughput(const ThroughputObservation& observation); |
| 486 | 430 |
| 487 // Returns true only if the |request| can be used for RTT estimation. | 431 // Returns true only if the |request| can be used for RTT estimation. |
| 488 bool RequestProvidesRTTObservation(const URLRequest& request) const; | 432 bool RequestProvidesRTTObservation(const URLRequest& request) const; |
| 489 | 433 |
| 490 // Recomputes effective connection type, if it was computed more than the | 434 // Recomputes effective connection type, if it was computed more than the |
| 491 // specified duration ago, or if there has been a connection change recently. | 435 // specified duration ago, or if there has been a connection change recently. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 EXTERNAL_ESTIMATE_PROVIDER_STATUS_CALLBACK, | 471 EXTERNAL_ESTIMATE_PROVIDER_STATUS_CALLBACK, |
| 528 EXTERNAL_ESTIMATE_PROVIDER_STATUS_RTT_AVAILABLE, | 472 EXTERNAL_ESTIMATE_PROVIDER_STATUS_RTT_AVAILABLE, |
| 529 EXTERNAL_ESTIMATE_PROVIDER_STATUS_DOWNLINK_BANDWIDTH_AVAILABLE, | 473 EXTERNAL_ESTIMATE_PROVIDER_STATUS_DOWNLINK_BANDWIDTH_AVAILABLE, |
| 530 EXTERNAL_ESTIMATE_PROVIDER_STATUS_BOUNDARY | 474 EXTERNAL_ESTIMATE_PROVIDER_STATUS_BOUNDARY |
| 531 }; | 475 }; |
| 532 | 476 |
| 533 // Records the metrics related to external estimate provider. | 477 // Records the metrics related to external estimate provider. |
| 534 void RecordExternalEstimateProviderMetrics( | 478 void RecordExternalEstimateProviderMetrics( |
| 535 NQEExternalEstimateProviderStatus status) const; | 479 NQEExternalEstimateProviderStatus status) const; |
| 536 | 480 |
| 481 // Returns true if the cached network quality estimate was successfully read. |
| 482 bool ReadCachedNetworkQualityEstimate(); |
| 483 |
| 537 // Determines if the requests to local host can be used in estimating the | 484 // Determines if the requests to local host can be used in estimating the |
| 538 // network quality. Set to true only for tests. | 485 // network quality. Set to true only for tests. |
| 539 bool use_localhost_requests_; | 486 bool use_localhost_requests_; |
| 540 | 487 |
| 541 // Determines if the responses smaller than |kMinTransferSizeInBytes| | 488 // Determines if the responses smaller than |kMinTransferSizeInBytes| |
| 542 // or shorter than |kMinTransferSizeInBytes| can be used in estimating the | 489 // or shorter than |kMinTransferSizeInBytes| can be used in estimating the |
| 543 // network quality. Set to true only for tests. | 490 // network quality. Set to true only for tests. |
| 544 bool use_small_responses_; | 491 bool use_small_responses_; |
| 545 | 492 |
| 546 // The factor by which the weight of an observation reduces every second. | 493 // The factor by which the weight of an observation reduces every second. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 563 base::TimeTicks last_effective_connection_type_computation_; | 510 base::TimeTicks last_effective_connection_type_computation_; |
| 564 | 511 |
| 565 // Intervals after the main frame request arrives at which accuracy of network | 512 // Intervals after the main frame request arrives at which accuracy of network |
| 566 // quality prediction is recorded. | 513 // quality prediction is recorded. |
| 567 std::vector<base::TimeDelta> accuracy_recording_intervals_; | 514 std::vector<base::TimeDelta> accuracy_recording_intervals_; |
| 568 | 515 |
| 569 // Time when last connection change was observed. | 516 // Time when last connection change was observed. |
| 570 base::TimeTicks last_connection_change_; | 517 base::TimeTicks last_connection_change_; |
| 571 | 518 |
| 572 // ID of the current network. | 519 // ID of the current network. |
| 573 NetworkID current_network_id_; | 520 nqe::internal::NetworkID current_network_id_; |
| 574 | 521 |
| 575 // Peak network quality (fastest round-trip-time (RTT) and highest | 522 // Peak network quality (fastest round-trip-time (RTT) and highest |
| 576 // downstream throughput) measured since last connectivity change. RTT is | 523 // downstream throughput) measured since last connectivity change. RTT is |
| 577 // measured from time the request is sent until the first byte received. | 524 // measured from time the request is sent until the first byte received. |
| 578 // The accuracy is decreased by ignoring these factors: | 525 // The accuracy is decreased by ignoring these factors: |
| 579 // 1) Multiple URLRequests can occur concurrently. | 526 // 1) Multiple URLRequests can occur concurrently. |
| 580 // 2) Includes server processing time. | 527 // 2) Includes server processing time. |
| 581 nqe::internal::NetworkQuality peak_network_quality_; | 528 nqe::internal::NetworkQuality peak_network_quality_; |
| 582 | 529 |
| 583 // Cache that stores quality of previously seen networks. | |
| 584 CachedNetworkQualities cached_network_qualities_; | |
| 585 | |
| 586 // Buffer that holds throughput observations (in kilobits per second) sorted | 530 // Buffer that holds throughput observations (in kilobits per second) sorted |
| 587 // by timestamp. | 531 // by timestamp. |
| 588 ThroughputObservationBuffer downstream_throughput_kbps_observations_; | 532 ThroughputObservationBuffer downstream_throughput_kbps_observations_; |
| 589 | 533 |
| 590 // Buffer that holds RTT observations sorted by timestamp. | 534 // Buffer that holds RTT observations sorted by timestamp. |
| 591 RttObservationBuffer rtt_observations_; | 535 RttObservationBuffer rtt_observations_; |
| 592 | 536 |
| 593 // Default network quality observations obtained from the network quality | 537 // Default network quality observations obtained from the network quality |
| 594 // estimator field trial parameters. The observations are indexed by | 538 // estimator field trial parameters. The observations are indexed by |
| 595 // ConnectionType. | 539 // ConnectionType. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 635 // events. It is also updated every time there is network traffic (provided | 579 // events. It is also updated every time there is network traffic (provided |
| 636 // the last computation was more than | 580 // the last computation was more than |
| 637 // |effective_connection_type_recomputation_interval_| ago). | 581 // |effective_connection_type_recomputation_interval_| ago). |
| 638 EffectiveConnectionType effective_connection_type_; | 582 EffectiveConnectionType effective_connection_type_; |
| 639 | 583 |
| 640 // Minimum and Maximum signal strength (in dbM) observed since last connection | 584 // Minimum and Maximum signal strength (in dbM) observed since last connection |
| 641 // change. Updated on connection change and main frame requests. | 585 // change. Updated on connection change and main frame requests. |
| 642 int32_t min_signal_strength_since_connection_change_; | 586 int32_t min_signal_strength_since_connection_change_; |
| 643 int32_t max_signal_strength_since_connection_change_; | 587 int32_t max_signal_strength_since_connection_change_; |
| 644 | 588 |
| 589 // Manages the cache that holds the qualities of different networks. |
| 590 nqe::internal::NetworkQualitiesManager network_qualities_manager_; |
| 591 |
| 645 base::ThreadChecker thread_checker_; | 592 base::ThreadChecker thread_checker_; |
| 646 | 593 |
| 647 base::WeakPtrFactory<NetworkQualityEstimator> weak_ptr_factory_; | 594 base::WeakPtrFactory<NetworkQualityEstimator> weak_ptr_factory_; |
| 648 | 595 |
| 649 DISALLOW_COPY_AND_ASSIGN(NetworkQualityEstimator); | 596 DISALLOW_COPY_AND_ASSIGN(NetworkQualityEstimator); |
| 650 }; | 597 }; |
| 651 | 598 |
| 652 } // namespace net | 599 } // namespace net |
| 653 | 600 |
| 654 #endif // NET_NQE_NETWORK_QUALITY_ESTIMATOR_H_ | 601 #endif // NET_NQE_NETWORK_QUALITY_ESTIMATOR_H_ |
| OLD | NEW |