network_quality_estimator.h 29 KB

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