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