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 |