1 // Copyright 2015 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_NQE_NETWORK_QUALITY_ESTIMATOR_H_ 6 #define NET_NQE_NETWORK_QUALITY_ESTIMATOR_H_ 7 8 #include <stdint.h> 9 10 #include <map> 11 #include <memory> 12 #include <vector> 13 14 #include "base/gtest_prod_util.h" 15 #include "base/memory/raw_ptr.h" 16 #include "base/memory/weak_ptr.h" 17 #include "base/observer_list.h" 18 #include "base/sequence_checker.h" 19 #include "base/time/time.h" 20 #include "build/build_config.h" 21 #include "build/chromeos_buildflags.h" 22 #include "net/base/net_export.h" 23 #include "net/base/network_change_notifier.h" 24 #include "net/log/net_log_with_source.h" 25 #include "net/nqe/cached_network_quality.h" 26 #include "net/nqe/effective_connection_type.h" 27 #include "net/nqe/effective_connection_type_observer.h" 28 #include "net/nqe/event_creator.h" 29 #include "net/nqe/network_id.h" 30 #include "net/nqe/network_quality.h" 31 #include "net/nqe/network_quality_estimator_params.h" 32 #include "net/nqe/network_quality_observation.h" 33 #include "net/nqe/network_quality_observation_source.h" 34 #include "net/nqe/network_quality_store.h" 35 #include "net/nqe/observation_buffer.h" 36 #include "net/nqe/peer_to_peer_connections_count_observer.h" 37 #include "net/nqe/rtt_throughput_estimates_observer.h" 38 #include "net/nqe/socket_watcher_factory.h" 39 #include "third_party/abseil-cpp/absl/types/optional.h" 40 41 namespace base { 42 class TickClock; 43 } // namespace base 44 45 namespace net { 46 47 class NetLog; 48 49 namespace nqe::internal { 50 class ThroughputAnalyzer; 51 } // namespace nqe::internal 52 53 class URLRequest; 54 55 // NetworkQualityEstimator provides network quality estimates (quality of the 56 // full paths to all origins that have been connected to). 57 // The estimates are based on the observed organic traffic. 58 // A NetworkQualityEstimator instance is attached to URLRequestContexts and 59 // observes the traffic of URLRequests spawned from the URLRequestContexts. 60 // A single instance of NQE can be attached to multiple URLRequestContexts, 61 // thereby increasing the single NQE instance's accuracy by providing more 62 // observed traffic characteristics. 63 class NET_EXPORT_PRIVATE NetworkQualityEstimator 64 : public NetworkChangeNotifier::ConnectionTypeObserver { 65 public: 66 // Observes measurements of round trip time. 67 class NET_EXPORT_PRIVATE RTTObserver { 68 public: 69 RTTObserver(const RTTObserver&) = delete; 70 RTTObserver& operator=(const RTTObserver&) = delete; 71 72 // Will be called when a new RTT observation is available. The round trip 73 // time is specified in milliseconds. The time when the observation was 74 // taken and the source of the observation are provided. 75 virtual void OnRTTObservation(int32_t rtt_ms, 76 const base::TimeTicks& timestamp, 77 NetworkQualityObservationSource source) = 0; 78 79 protected: 80 RTTObserver() = default; 81 virtual ~RTTObserver() = default; 82 }; 83 84 // Observes measurements of throughput. 85 class NET_EXPORT_PRIVATE ThroughputObserver { 86 public: 87 ThroughputObserver(const ThroughputObserver&) = delete; 88 ThroughputObserver& operator=(const ThroughputObserver&) = delete; 89 90 // Will be called when a new throughput observation is available. 91 // Throughput is specified in kilobits per second. 92 virtual void OnThroughputObservation( 93 int32_t throughput_kbps, 94 const base::TimeTicks& timestamp, 95 NetworkQualityObservationSource source) = 0; 96 97 protected: 98 ThroughputObserver() = default; 99 virtual ~ThroughputObserver() = default; 100 }; 101 102 // Creates a new NetworkQualityEstimator. 103 // |params| contains the 104 // configuration parameters relevant to network quality estimator. The caller 105 // must guarantee that |net_log| outlives |this|. 106 NetworkQualityEstimator( 107 std::unique_ptr<NetworkQualityEstimatorParams> params, 108 NetLog* net_log); 109 110 NetworkQualityEstimator(const NetworkQualityEstimator&) = delete; 111 NetworkQualityEstimator& operator=(const NetworkQualityEstimator&) = delete; 112 113 ~NetworkQualityEstimator() override; 114 115 // Returns the current effective connection type. The effective connection 116 // type is computed by the network quality estimator at regular intervals and 117 // at certain events (e.g., connection change). Virtualized for testing. 118 virtual EffectiveConnectionType GetEffectiveConnectionType() const; 119 120 // Adds |observer| to a list of effective connection type observers. 121 // The observer must register and unregister itself on the same thread. 122 // |observer| would be notified on the thread on which it registered. 123 // |observer| would be notified of the current effective connection 124 // type in the next message pump. 125 void AddEffectiveConnectionTypeObserver( 126 EffectiveConnectionTypeObserver* observer); 127 128 // Removes |observer| from a list of effective connection type observers. 129 void RemoveEffectiveConnectionTypeObserver( 130 EffectiveConnectionTypeObserver* observer); 131 132 // Adds/Removes |observer| from the list of peer to peer connections count 133 // observers. The observer must register and unregister itself on the same 134 // thread. |observer| would be notified on the thread on which it registered. 135 // |observer| would be notified of the current count of peer to peer 136 // connections in the next message pump. 137 void AddPeerToPeerConnectionsCountObserver( 138 PeerToPeerConnectionsCountObserver* observer); 139 void RemovePeerToPeerConnectionsCountObserver( 140 PeerToPeerConnectionsCountObserver* observer); 141 142 // Returns the current HTTP RTT estimate. If the estimate is unavailable, 143 // the returned optional value is null. The RTT at the HTTP layer measures the 144 // time from when the request was sent (this happens after the connection is 145 // established) to the time when the response headers were received. 146 // Virtualized for testing. 147 virtual absl::optional<base::TimeDelta> GetHttpRTT() const; 148 149 // Returns the current transport RTT estimate. If the estimate is 150 // unavailable, the returned optional value is null. The RTT at the transport 151 // layer provides an aggregate estimate of the transport RTT as computed by 152 // various underlying TCP and QUIC connections. Virtualized for testing. 153 virtual absl::optional<base::TimeDelta> GetTransportRTT() const; 154 155 // Returns the current downstream throughput estimate (in kilobits per 156 // second). If the estimate is unavailable, the returned optional value is 157 // null. 158 absl::optional<int32_t> GetDownstreamThroughputKbps() const; 159 160 // Adds |observer| to the list of RTT and throughput estimate observers. 161 // The observer must register and unregister itself on the same thread. 162 // |observer| would be notified on the thread on which it registered. 163 // |observer| would be notified of the current values in the next message 164 // pump. 165 void AddRTTAndThroughputEstimatesObserver( 166 RTTAndThroughputEstimatesObserver* observer); 167 168 // Removes |observer| from the list of RTT and throughput estimate 169 // observers. 170 void RemoveRTTAndThroughputEstimatesObserver( 171 RTTAndThroughputEstimatesObserver* observer); 172 173 // Notifies NetworkQualityEstimator that the response header of |request| has 174 // been received. Reports the total prefilter network bytes that have been 175 // read for the response of |request|. 176 void NotifyHeadersReceived(const URLRequest& request, 177 int64_t prefilter_total_bytes_read); 178 179 // Notifies NetworkQualityEstimator that unfiltered bytes have been read for 180 // |request|. Reports the total prefilter network bytes that have been read 181 // for the response of |request|. 182 void NotifyBytesRead(const URLRequest& request, 183 int64_t prefilter_total_bytes_read); 184 185 // Notifies NetworkQualityEstimator that the headers of |request| are about to 186 // be sent. 187 void NotifyStartTransaction(const URLRequest& request); 188 189 // Notifies NetworkQualityEstimator that the response body of |request| has 190 // been received. 191 void NotifyRequestCompleted(const URLRequest& request); 192 193 // Notifies NetworkQualityEstimator that |request| will be destroyed. 194 void NotifyURLRequestDestroyed(const URLRequest& request); 195 196 // Adds |rtt_observer| to the list of round trip time observers. Must be 197 // called on the IO thread. 198 void AddRTTObserver(RTTObserver* rtt_observer); 199 200 // Removes |rtt_observer| from the list of round trip time observers if it 201 // is on the list of observers. Must be called on the IO thread. 202 void RemoveRTTObserver(RTTObserver* rtt_observer); 203 204 // Adds |throughput_observer| to the list of throughput observers. Must be 205 // called on the IO thread. 206 void AddThroughputObserver(ThroughputObserver* throughput_observer); 207 208 // Removes |throughput_observer| from the list of throughput observers if it 209 // is on the list of observers. Must be called on the IO thread. 210 void RemoveThroughputObserver(ThroughputObserver* throughput_observer); 211 212 SocketPerformanceWatcherFactory* GetSocketPerformanceWatcherFactory(); 213 214 // |use_localhost_requests| should only be true when testing against local 215 // HTTP server and allows the requests to local host to be used for network 216 // quality estimation. 217 void SetUseLocalHostRequestsForTesting(bool use_localhost_requests); 218 219 // |use_small_responses| should only be true when testing. 220 // Allows the responses smaller than |kMinTransferSizeInBits| to be used for 221 // network quality estimation. 222 void SetUseSmallResponsesForTesting(bool use_small_responses); 223 224 // If |disable_offline_check| is set to true, then the device offline check is 225 // disabled when computing the effective connection type or when writing the 226 // prefs. 227 void DisableOfflineCheckForTesting(bool disable_offline_check); 228 229 // Reports |effective_connection_type| to all 230 // EffectiveConnectionTypeObservers. 231 void ReportEffectiveConnectionTypeForTesting( 232 EffectiveConnectionType effective_connection_type); 233 234 // Reports the RTTs and throughput to all RTTAndThroughputEstimatesObservers. 235 void ReportRTTsAndThroughputForTesting(base::TimeDelta http_rtt, 236 base::TimeDelta transport_rtt, 237 int32_t downstream_throughput_kbps); 238 239 // Adds and removes |observer| from the list of cache observers. 240 void AddNetworkQualitiesCacheObserver( 241 nqe::internal::NetworkQualityStore::NetworkQualitiesCacheObserver* 242 observer); 243 void RemoveNetworkQualitiesCacheObserver( 244 nqe::internal::NetworkQualityStore::NetworkQualitiesCacheObserver* 245 observer); 246 247 // Called when the persistent prefs have been read. |read_prefs| contains the 248 // parsed prefs as a map between NetworkIDs and CachedNetworkQualities. 249 void OnPrefsRead( 250 const std::map<nqe::internal::NetworkID, 251 nqe::internal::CachedNetworkQuality> read_prefs); 252 params()253 const NetworkQualityEstimatorParams* params() { return params_.get(); } 254 255 #if BUILDFLAG(IS_CHROMEOS_ASH) 256 // Enables getting the network id asynchronously when 257 // GatherEstimatesForNextConnectionType(). This should always be called in 258 // production, because getting the network id involves a blocking call to 259 // recv() in AddressTrackerLinux, and the IO thread should never be blocked. 260 // TODO(https://crbug.com/821607): Remove after the bug is resolved. 261 void EnableGetNetworkIdAsynchronously(); 262 #endif // BUILDFLAG(IS_CHROMEOS_ASH) 263 264 // Forces the effective connection type to be recomputed as |type|. Once 265 // called, effective connection type would always be computed as |type|. 266 // Calling this also notifies all the observers of the effective connection 267 // type as |type|. 268 void SimulateNetworkQualityChangeForTesting( 269 net::EffectiveConnectionType type); 270 271 // Notifies |this| of round trip ping latency reported by H2 connections. 272 virtual void RecordSpdyPingLatency(const HostPortPair& host_port_pair, 273 base::TimeDelta rtt); 274 275 // Sets the current count of media connections that require low latency. 276 void OnPeerToPeerConnectionsCountChange(uint32_t count); 277 278 // Returns the current count of peer to peer connections that may require low 279 // latency. 280 uint32_t GetPeerToPeerConnectionsCountChange() const; 281 282 // Forces NetworkQualityEstimator reports 283 // NetworkChangeNotifier::CONNECTION_WIFI(2) as 284 // EFFECTIVE_CONNECTION_TYPE_SLOW_2G(2) since EffectiveConnectionType and the 285 // production receivers doesn't notice Wifi. 286 void ForceReportWifiAsSlow2GForTesting(); 287 288 typedef nqe::internal::Observation Observation; 289 typedef nqe::internal::ObservationBuffer ObservationBuffer; 290 291 protected: 292 // NetworkChangeNotifier::ConnectionTypeObserver implementation: 293 void OnConnectionTypeChanged( 294 NetworkChangeNotifier::ConnectionType type) override; 295 296 // Returns true if median RTT across all samples that belong to 297 // |observation_category| is available and sets |rtt| to the median of RTT 298 // observations since |start_time|. Virtualized for testing. |rtt| should not 299 // be null. If |observations_count| is not null, then it is set to the number 300 // of RTT observations that were used for computing the RTT estimate. 301 [[nodiscard]] virtual bool GetRecentRTT( 302 nqe::internal::ObservationCategory observation_category, 303 const base::TimeTicks& start_time, 304 base::TimeDelta* rtt, 305 size_t* observations_count) const; 306 307 // Returns true if median downstream throughput is available and sets |kbps| 308 // to the median of downstream throughput (in kilobits per second) 309 // observations since |start_time|. Virtualized for testing. |kbps| 310 // should not be null. Virtualized for testing. 311 // TODO(tbansal): Change it to return throughput as int32. 312 [[nodiscard]] virtual bool GetRecentDownlinkThroughputKbps( 313 const base::TimeTicks& start_time, 314 int32_t* kbps) const; 315 316 // Overrides the tick clock used by |this| for testing. 317 void SetTickClockForTesting(const base::TickClock* tick_clock); 318 319 // Returns the effective type of the current connection based on the 320 // samples observed. May use HTTP RTT, transport RTT and 321 // downstream throughput to compute the effective connection type based on 322 // |http_rtt_metric|, |transport_rtt_metric| and 323 // |downstream_throughput_kbps_metric|, respectively. |http_rtt|, 324 // |transport_rtt| and |downstream_throughput_kbps| must be non-null. 325 // |http_rtt|, |transport_rtt| and |downstream_throughput_kbps| are 326 // set to the expected HTTP RTT, transport RTT and downstream throughput (in 327 // kilobits per second) based on observations taken since |start_time|. 328 // If |transport_rtt_observation_count| is not null, then it is set to the 329 // number of transport RTT observations that were available when computing the 330 // effective connection type. 331 virtual EffectiveConnectionType GetRecentEffectiveConnectionTypeUsingMetrics( 332 base::TimeDelta* http_rtt, 333 base::TimeDelta* transport_rtt, 334 base::TimeDelta* end_to_end_rtt, 335 int32_t* downstream_throughput_kbps, 336 size_t* transport_rtt_observation_count, 337 size_t* end_to_end_rtt_observation_count) const; 338 339 // Notifies |this| of a new transport layer RTT. Called by socket watchers. 340 // Protected for testing. 341 void OnUpdatedTransportRTTAvailable( 342 SocketPerformanceWatcherFactory::Protocol protocol, 343 const base::TimeDelta& rtt, 344 const absl::optional<nqe::internal::IPHash>& host); 345 346 // Returns an estimate of network quality at the specified |percentile|. 347 // Only the observations later than |start_time| are taken into account. 348 // |percentile| must be between 0 and 100 (both inclusive) with higher 349 // percentiles indicating less performant networks. For example, if 350 // |percentile| is 90, then the network is expected to be faster than the 351 // returned estimate with 0.9 probability. Similarly, network is expected to 352 // be slower than the returned estimate with 0.1 probability. 353 // Virtualized for testing. 354 // |observation_category| is the category of observations which should be used 355 // for computing the RTT estimate. 356 // If |observations_count| is not null, then it is set to the number of RTT 357 // observations that were available when computing the RTT estimate. 358 virtual base::TimeDelta GetRTTEstimateInternal( 359 base::TimeTicks start_time, 360 nqe::internal::ObservationCategory observation_category, 361 int percentile, 362 size_t* observations_count) const; 363 int32_t GetDownlinkThroughputKbpsEstimateInternal( 364 const base::TimeTicks& start_time, 365 int percentile) const; 366 367 // Notifies the observers of RTT or throughput estimates computation. 368 virtual void NotifyObserversOfRTTOrThroughputComputed() const; 369 370 // Notifies |observer| of the current RTT and throughput if |observer| is 371 // still registered as an observer. 372 virtual void NotifyRTTAndThroughputEstimatesObserverIfPresent( 373 RTTAndThroughputEstimatesObserver* observer) const; 374 375 // Adds |observation| to the buffer of RTT observations, and notifies RTT 376 // observers of |observation|. May also trigger recomputation of effective 377 // connection type. 378 void AddAndNotifyObserversOfRTT(const Observation& observation); 379 380 // Adds |observation| to the buffer of throughput observations, and notifies 381 // throughput observers of |observation|. May also trigger recomputation of 382 // effective connection type. 383 void AddAndNotifyObserversOfThroughput(const Observation& observation); 384 385 // Returns true if the request with observed HTTP of |observed_http_rtt| is 386 // expected to be a hanging request. The decision is made by comparing 387 // |observed_http_rtt| with the expected HTTP and transport RTT. 388 bool IsHangingRequest(base::TimeDelta observed_http_rtt) const; 389 390 // Forces computation of effective connection type, and notifies observers 391 // if there is a change in its value. 392 void ComputeEffectiveConnectionType(); 393 394 // Returns a non-null value if the value of the effective connection type has 395 // been overridden for testing. 396 virtual absl::optional<net::EffectiveConnectionType> GetOverrideECT() const; 397 398 // Observer list for RTT or throughput estimates. Protected for testing. 399 base::ObserverList<RTTAndThroughputEstimatesObserver>::Unchecked 400 rtt_and_throughput_estimates_observer_list_; 401 402 // Observer list for changes in effective connection type. 403 base::ObserverList<EffectiveConnectionTypeObserver>::Unchecked 404 effective_connection_type_observer_list_; 405 406 // Observer list for changes in peer to peer connections count. 407 base::ObserverList<PeerToPeerConnectionsCountObserver>::Unchecked 408 peer_to_peer_type_observer_list_; 409 410 // Params to configure the network quality estimator. 411 const std::unique_ptr<NetworkQualityEstimatorParams> params_; 412 413 // Number of end to end RTT samples available when the ECT was last computed. 414 size_t end_to_end_rtt_observation_count_at_last_ect_computation_ = 0; 415 416 // Current count of active peer to peer connections. 417 uint32_t p2p_connections_count_ = 0u; 418 419 private: 420 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, 421 AdaptiveRecomputationEffectiveConnectionType); 422 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, StoreObservations); 423 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestAddObservation); 424 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, 425 DefaultObservationsOverridden); 426 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, ComputedPercentiles); 427 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestGetMetricsSince); 428 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, 429 UnknownEffectiveConnectionType); 430 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, 431 TypicalNetworkQualities); 432 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, 433 OnPrefsReadWithReadingDisabled); 434 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, 435 ForceEffectiveConnectionTypeThroughFieldTrial); 436 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, 437 ObservationDiscardedIfCachedEstimateAvailable); 438 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, 439 TestRttThroughputObservers); 440 441 // Returns the RTT value to be used when the valid RTT is unavailable. Readers 442 // should discard RTT if it is set to the value returned by |InvalidRTT()|. 443 static const base::TimeDelta InvalidRTT(); 444 445 // Records a downstream throughput observation to the observation buffer if 446 // a valid observation is available. |downstream_kbps| is the downstream 447 // throughput in kilobits per second. 448 void OnNewThroughputObservationAvailable(int32_t downstream_kbps); 449 450 // Adds the default median RTT and downstream throughput estimate for the 451 // current connection type to the observation buffer. 452 void AddDefaultEstimates(); 453 454 // Returns the current network ID checking by calling the platform APIs. 455 // Virtualized for testing. 456 virtual nqe::internal::NetworkID GetCurrentNetworkID() const; 457 458 // Returns true only if the |request| can be used for RTT estimation. 459 bool RequestProvidesRTTObservation(const URLRequest& request) const; 460 461 // Returns true if ECT should be recomputed. 462 bool ShouldComputeEffectiveConnectionType() const; 463 464 // Calls ShouldComputeEffectiveConnectionType() to determine if ECT needs to 465 // be computed. If so, it recomputes effective connection type. 466 void MaybeComputeEffectiveConnectionType(); 467 468 // Notifies observers of a change in effective connection type. 469 void NotifyObserversOfEffectiveConnectionTypeChanged(); 470 471 // Notifies |observer| of the current effective connection type if |observer| 472 // is still registered as an observer. 473 void NotifyEffectiveConnectionTypeObserverIfPresent( 474 MayBeDangling<EffectiveConnectionTypeObserver> observer) const; 475 476 // Notifies |observer| of the current count of peer to peer connections. 477 void NotifyPeerToPeerConnectionsCountObserverIfPresent( 478 MayBeDangling<PeerToPeerConnectionsCountObserver> observer) const; 479 480 // Records NQE accuracy metrics. |measuring_duration| should belong to the 481 // vector returned by AccuracyRecordingIntervals(). 482 // RecordAccuracyAfterMainFrame should be called |measuring_duration| after a 483 // main frame request is observed. 484 void RecordAccuracyAfterMainFrame(base::TimeDelta measuring_duration) const; 485 486 // Updates the provided |http_rtt| based on all provided RTT values. 487 void UpdateHttpRttUsingAllRttValues( 488 base::TimeDelta* http_rtt, 489 const base::TimeDelta transport_rtt, 490 const base::TimeDelta end_to_end_rtt) const; 491 492 // Returns true if the cached network quality estimate was successfully read. 493 bool ReadCachedNetworkQualityEstimate(); 494 495 // Gathers metrics for the next connection type. Called when there is a change 496 // in the connection type. 497 void GatherEstimatesForNextConnectionType(); 498 499 // Invoked to continue GatherEstimatesForNextConnectionType work after getting 500 // network id. If |get_network_id_asynchronously_| is set, the network id is 501 // fetched on a worker thread. Otherwise, GatherEstimatesForNextConnectionType 502 // calls this directly. This is a workaround for https://crbug.com/821607 503 // where net::GetWifiSSID() call gets stuck. 504 void ContinueGatherEstimatesForNextConnectionType( 505 const nqe::internal::NetworkID& network_id); 506 507 // Updates the value of |cached_estimate_applied_| if |observation| is 508 // computed from a cached estimate. |buffer| is the observation buffer to 509 // which the cached estimate is being added to. 510 void MaybeUpdateCachedEstimateApplied(const Observation& observation, 511 ObservationBuffer* buffer); 512 513 // Returns true if |observation| should be added to the observation buffer. 514 bool ShouldAddObservation(const Observation& observation) const; 515 516 // Returns true if the socket watcher can run the callback to notify the RTT 517 // observations. 518 bool ShouldSocketWatcherNotifyRTT(base::TimeTicks now); 519 520 // When RTT counts are low, it may be impossible to predict accurate ECT. In 521 // that case, we just give the highest value. 522 void AdjustHttpRttBasedOnRTTCounts(base::TimeDelta* http_rtt) const; 523 524 // Clamps the throughput estimate based on the current effective connection 525 // type. 526 void ClampKbpsBasedOnEct(); 527 528 // Determines if the requests to local host can be used in estimating the 529 // network quality. Set to true only for tests. 530 bool use_localhost_requests_ = false; 531 532 // When set to true, the device offline check is disabled when computing the 533 // effective connection type or when writing the prefs. Set to true only for 534 // testing. 535 bool disable_offline_check_ = false; 536 537 // Tick clock used by the network quality estimator. 538 raw_ptr<const base::TickClock> tick_clock_; 539 540 // Time when last connection change was observed. 541 base::TimeTicks last_connection_change_; 542 543 // ID of the current network. 544 nqe::internal::NetworkID current_network_id_; 545 546 // Buffer that holds throughput observations from the HTTP layer (in kilobits 547 // per second) sorted by timestamp. 548 ObservationBuffer http_downstream_throughput_kbps_observations_; 549 550 // Buffer that holds RTT observations with different observation categories. 551 // The entries in |rtt_ms_observations_| are in the same order as the 552 // entries in the nqe::internal:ObservationCategory enum. 553 // Each observation buffer in |rtt_ms_observations_| stores RTT observations 554 // in milliseconds. Within a buffer, the observations are sorted by timestamp. 555 ObservationBuffer 556 rtt_ms_observations_[nqe::internal::OBSERVATION_CATEGORY_COUNT]; 557 558 // Observer lists for round trip times and throughput measurements. 559 base::ObserverList<RTTObserver>::Unchecked rtt_observer_list_; 560 base::ObserverList<ThroughputObserver>::Unchecked throughput_observer_list_; 561 562 std::unique_ptr<nqe::internal::SocketWatcherFactory> watcher_factory_; 563 564 // Takes throughput measurements, and passes them back to |this| through the 565 // provided callback. |this| stores the throughput observations in 566 // |downstream_throughput_kbps_observations_|, which are later used for 567 // estimating the throughput. 568 std::unique_ptr<nqe::internal::ThroughputAnalyzer> throughput_analyzer_; 569 570 // Minimum duration between two consecutive computations of effective 571 // connection type. Set to non-zero value as a performance optimization. 572 const base::TimeDelta effective_connection_type_recomputation_interval_ = 573 base::Seconds(10); 574 575 // Time when the effective connection type was last computed. 576 base::TimeTicks last_effective_connection_type_computation_; 577 578 // Number of RTT and bandwidth samples available when effective connection 579 // type was last recomputed. 580 size_t rtt_observations_size_at_last_ect_computation_ = 0; 581 size_t throughput_observations_size_at_last_ect_computation_ = 0; 582 583 // Number of transport RTT samples available when the ECT was last computed. 584 size_t transport_rtt_observation_count_last_ect_computation_ = 0; 585 586 // Number of RTT observations received since the effective connection type was 587 // last computed. 588 size_t new_rtt_observations_since_last_ect_computation_ = 0; 589 590 // Number of throughput observations received since the effective connection 591 // type was last computed. 592 size_t new_throughput_observations_since_last_ect_computation_ = 0; 593 594 // Current estimate of the network quality. 595 nqe::internal::NetworkQuality network_quality_; 596 absl::optional<base::TimeDelta> end_to_end_rtt_; 597 598 // Current effective connection type. It is updated on connection change 599 // events. It is also updated every time there is network traffic (provided 600 // the last computation was more than 601 // |effective_connection_type_recomputation_interval_| ago). 602 EffectiveConnectionType effective_connection_type_ = 603 EFFECTIVE_CONNECTION_TYPE_UNKNOWN; 604 605 // Stores the qualities of different networks. 606 std::unique_ptr<nqe::internal::NetworkQualityStore> network_quality_store_; 607 608 // True if a cached RTT or throughput estimate was available and the 609 // corresponding observation has been added on the current network. 610 bool cached_estimate_applied_ = false; 611 612 SEQUENCE_CHECKER(sequence_checker_); 613 614 NetLogWithSource net_log_; 615 616 // Manages the writing of events to the net log. 617 nqe::internal::EventCreator event_creator_; 618 619 // Time when the last RTT observation from a socket watcher was received. 620 base::TimeTicks last_socket_watcher_rtt_notification_; 621 622 absl::optional<base::TimeTicks> last_signal_strength_check_timestamp_; 623 624 #if BUILDFLAG(IS_CHROMEOS_ASH) 625 // Whether the network id should be obtained on a worker thread. 626 bool get_network_id_asynchronously_ = false; 627 #endif 628 629 bool force_report_wifi_as_slow_2g_for_testing_ = false; 630 631 base::WeakPtrFactory<NetworkQualityEstimator> weak_ptr_factory_{this}; 632 }; 633 634 } // namespace net 635 636 #endif // NET_NQE_NETWORK_QUALITY_ESTIMATOR_H_ 637