• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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