OLD | NEW |
| (Empty) |
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 | |
5 #ifndef NET_BASE_NETWORK_QUALITY_ESTIMATOR_H_ | |
6 #define NET_BASE_NETWORK_QUALITY_ESTIMATOR_H_ | |
7 | |
8 #include <stddef.h> | |
9 #include <stdint.h> | |
10 | |
11 #include <deque> | |
12 #include <map> | |
13 #include <memory> | |
14 #include <string> | |
15 #include <tuple> | |
16 | |
17 #include "base/compiler_specific.h" | |
18 #include "base/gtest_prod_util.h" | |
19 #include "base/macros.h" | |
20 #include "base/memory/ref_counted.h" | |
21 #include "base/memory/weak_ptr.h" | |
22 #include "base/observer_list.h" | |
23 #include "base/threading/thread_checker.h" | |
24 #include "base/time/time.h" | |
25 #include "net/base/external_estimate_provider.h" | |
26 #include "net/base/net_export.h" | |
27 #include "net/base/network_change_notifier.h" | |
28 #include "net/base/socket_performance_watcher_factory.h" | |
29 | |
30 namespace base { | |
31 class SingleThreadTaskRunner; | |
32 } // namespace base | |
33 | |
34 namespace net { | |
35 | |
36 class URLRequest; | |
37 | |
38 // NetworkQualityEstimator provides network quality estimates (quality of the | |
39 // full paths to all origins that have been connected to). | |
40 // The estimates are based on the observed organic traffic. | |
41 // A NetworkQualityEstimator instance is attached to URLRequestContexts and | |
42 // observes the traffic of URLRequests spawned from the URLRequestContexts. | |
43 // A single instance of NQE can be attached to multiple URLRequestContexts, | |
44 // thereby increasing the single NQE instance's accuracy by providing more | |
45 // observed traffic characteristics. | |
46 class NET_EXPORT_PRIVATE NetworkQualityEstimator | |
47 : public NetworkChangeNotifier::ConnectionTypeObserver, | |
48 public ExternalEstimateProvider::UpdatedEstimateDelegate { | |
49 public: | |
50 // EffectiveConnectionType is the connection type whose typical performance is | |
51 // most similar to the measured performance of the network in use. In many | |
52 // cases, the "effective" connection type and the actual type of connection in | |
53 // use are the same, but often a network connection performs significantly | |
54 // different, usually worse, from its expected capabilities. | |
55 // EffectiveConnectionType of a network is independent of if the current | |
56 // connection is metered or not. For example, an unmetered slow connection may | |
57 // have EFFECTIVE_CONNECTION_TYPE_SLOW_2G as its effective connection type. | |
58 enum EffectiveConnectionType { | |
59 // The connection types should be in increasing order of quality. | |
60 EFFECTIVE_CONNECTION_TYPE_UNKNOWN = 0, | |
61 EFFECTIVE_CONNECTION_TYPE_OFFLINE, | |
62 EFFECTIVE_CONNECTION_TYPE_SLOW_2G, | |
63 EFFECTIVE_CONNECTION_TYPE_2G, | |
64 EFFECTIVE_CONNECTION_TYPE_3G, | |
65 EFFECTIVE_CONNECTION_TYPE_4G, | |
66 EFFECTIVE_CONNECTION_TYPE_BROADBAND, | |
67 EFFECTIVE_CONNECTION_TYPE_LAST, | |
68 }; | |
69 | |
70 // On Android, a Java counterpart will be generated for this enum. | |
71 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net | |
72 // GENERATED_JAVA_CLASS_NAME_OVERRIDE: NetworkQualityObservationSource | |
73 // GENERATED_JAVA_PREFIX_TO_STRIP: | |
74 enum ObservationSource { | |
75 // The observation was taken at the request layer, e.g., a round trip time | |
76 // is recorded as the time between the request being sent and the first byte | |
77 // being received. | |
78 URL_REQUEST, | |
79 // The observation is taken from TCP statistics maintained by the kernel. | |
80 TCP, | |
81 // The observation is taken at the QUIC layer. | |
82 QUIC, | |
83 // The observation is a previously cached estimate of the metric. | |
84 CACHED_ESTIMATE, | |
85 // The observation is derived from network connection information provided | |
86 // by the platform. For example, typical RTT and throughput values are used | |
87 // for a given type of network connection. | |
88 DEFAULT_FROM_PLATFORM, | |
89 // The observation came from a Chromium-external source. | |
90 EXTERNAL_ESTIMATE | |
91 }; | |
92 | |
93 // Observes measurements of round trip time. | |
94 class NET_EXPORT_PRIVATE RTTObserver { | |
95 public: | |
96 // Will be called when a new RTT observation is available. The round trip | |
97 // time is specified in milliseconds. The time when the observation was | |
98 // taken and the source of the observation are provided. | |
99 virtual void OnRTTObservation(int32_t rtt_ms, | |
100 const base::TimeTicks& timestamp, | |
101 ObservationSource source) = 0; | |
102 | |
103 protected: | |
104 RTTObserver() {} | |
105 virtual ~RTTObserver() {} | |
106 | |
107 private: | |
108 DISALLOW_COPY_AND_ASSIGN(RTTObserver); | |
109 }; | |
110 | |
111 // Observes measurements of throughput. | |
112 class NET_EXPORT_PRIVATE ThroughputObserver { | |
113 public: | |
114 // Will be called when a new throughput observation is available. | |
115 // Throughput is specified in kilobits per second. | |
116 virtual void OnThroughputObservation(int32_t throughput_kbps, | |
117 const base::TimeTicks& timestamp, | |
118 ObservationSource source) = 0; | |
119 | |
120 protected: | |
121 ThroughputObserver() {} | |
122 virtual ~ThroughputObserver() {} | |
123 | |
124 private: | |
125 DISALLOW_COPY_AND_ASSIGN(ThroughputObserver); | |
126 }; | |
127 | |
128 // Creates a new NetworkQualityEstimator. | |
129 // |variation_params| is the map containing all field trial parameters | |
130 // related to NetworkQualityEstimator field trial. | |
131 // |external_estimates_provider| may be NULL. | |
132 NetworkQualityEstimator( | |
133 std::unique_ptr<ExternalEstimateProvider> external_estimates_provider, | |
134 const std::map<std::string, std::string>& variation_params); | |
135 | |
136 // Construct a NetworkQualityEstimator instance allowing for test | |
137 // configuration. Registers for network type change notifications so estimates | |
138 // can be kept network specific. | |
139 // |external_estimates_provider| may be NULL. | |
140 // |variation_params| is the map containing all field trial parameters for the | |
141 // network quality estimator field trial. | |
142 // |allow_local_host_requests_for_tests| should only be true when testing | |
143 // against local HTTP server and allows the requests to local host to be | |
144 // used for network quality estimation. | |
145 // |allow_smaller_responses_for_tests| should only be true when testing. | |
146 // Allows the responses smaller than |kMinTransferSizeInBytes| or shorter than | |
147 // |kMinRequestDurationMicroseconds| to be used for network quality | |
148 // estimation. | |
149 NetworkQualityEstimator( | |
150 std::unique_ptr<ExternalEstimateProvider> external_estimates_provider, | |
151 const std::map<std::string, std::string>& variation_params, | |
152 bool allow_local_host_requests_for_tests, | |
153 bool allow_smaller_responses_for_tests); | |
154 | |
155 ~NetworkQualityEstimator() override; | |
156 | |
157 // Returns the effective type of the current connection. | |
158 EffectiveConnectionType GetEffectiveConnectionType() const; | |
159 | |
160 // Returns true if RTT is available and sets |rtt| to estimated RTT at the | |
161 // HTTP layer. Virtualized for testing. |rtt| should not be null. The RTT at | |
162 // the HTTP layer measures the time from when the request was sent (this | |
163 // happens after the connection is established) to the time when the response | |
164 // headers were received. | |
165 virtual bool GetURLRequestRTTEstimate(base::TimeDelta* rtt) const | |
166 WARN_UNUSED_RESULT; | |
167 | |
168 // Returns true if downlink throughput is available and sets |kbps| to | |
169 // estimated downlink throughput (in kilobits per second). | |
170 // Virtualized for testing. |kbps| should not be null. | |
171 virtual bool GetDownlinkThroughputKbpsEstimate(int32_t* kbps) const; | |
172 | |
173 // Notifies NetworkQualityEstimator that the response header of |request| has | |
174 // been received. | |
175 void NotifyHeadersReceived(const URLRequest& request); | |
176 | |
177 // Notifies NetworkQualityEstimator that the response body of |request| has | |
178 // been received. | |
179 void NotifyRequestCompleted(const URLRequest& request); | |
180 | |
181 // Returns true if median RTT at the HTTP layer is available and sets |rtt| | |
182 // to the median of RTT observations since |begin_timestamp|. | |
183 // Virtualized for testing. |rtt| should not be null. The RTT at the HTTP | |
184 // layer measures the time from when the request was sent (this happens after | |
185 // the connection is established) to the time when the response headers were | |
186 // received. | |
187 virtual bool GetRecentURLRequestRTTMedian( | |
188 const base::TimeTicks& begin_timestamp, | |
189 base::TimeDelta* rtt) const WARN_UNUSED_RESULT; | |
190 | |
191 // Returns true if median downstream throughput is available and sets |kbps| | |
192 // to the median of downstream throughput (in kilobits per second) | |
193 // observations since |begin_timestamp|. Virtualized for testing. |kbps| | |
194 // should not be null. | |
195 virtual bool GetRecentMedianDownlinkThroughputKbps( | |
196 const base::TimeTicks& begin_timestamp, | |
197 int32_t* kbps) const WARN_UNUSED_RESULT; | |
198 | |
199 // Adds |rtt_observer| to the list of round trip time observers. Must be | |
200 // called on the IO thread. | |
201 void AddRTTObserver(RTTObserver* rtt_observer); | |
202 | |
203 // Removes |rtt_observer| from the list of round trip time observers if it | |
204 // is on the list of observers. Must be called on the IO thread. | |
205 void RemoveRTTObserver(RTTObserver* rtt_observer); | |
206 | |
207 // Adds |throughput_observer| to the list of throughput observers. Must be | |
208 // called on the IO thread. | |
209 void AddThroughputObserver(ThroughputObserver* throughput_observer); | |
210 | |
211 // Removes |throughput_observer| from the list of throughput observers if it | |
212 // is on the list of observers. Must be called on the IO thread. | |
213 void RemoveThroughputObserver(ThroughputObserver* throughput_observer); | |
214 | |
215 SocketPerformanceWatcherFactory* GetSocketPerformanceWatcherFactory(); | |
216 | |
217 protected: | |
218 // NetworkID is used to uniquely identify a network. | |
219 // For the purpose of network quality estimation and caching, a network is | |
220 // uniquely identified by a combination of |type| and | |
221 // |id|. This approach is unable to distinguish networks with | |
222 // same name (e.g., different Wi-Fi networks with same SSID). | |
223 // This is a protected member to expose it to tests. | |
224 struct NET_EXPORT_PRIVATE NetworkID { | |
225 NetworkID(NetworkChangeNotifier::ConnectionType type, const std::string& id) | |
226 : type(type), id(id) {} | |
227 NetworkID(const NetworkID& other) : type(other.type), id(other.id) {} | |
228 ~NetworkID() {} | |
229 | |
230 NetworkID& operator=(const NetworkID& other) { | |
231 type = other.type; | |
232 id = other.id; | |
233 return *this; | |
234 } | |
235 | |
236 // Overloaded because NetworkID is used as key in a map. | |
237 bool operator<(const NetworkID& other) const { | |
238 return std::tie(type, id) < std::tie(other.type, other.id); | |
239 } | |
240 | |
241 // Connection type of the network. | |
242 NetworkChangeNotifier::ConnectionType type; | |
243 | |
244 // Name of this network. This is set to: | |
245 // - Wi-Fi SSID if the device is connected to a Wi-Fi access point and the | |
246 // SSID name is available, or | |
247 // - MCC/MNC code of the cellular carrier if the device is connected to a | |
248 // cellular network, or | |
249 // - "Ethernet" in case the device is connected to ethernet. | |
250 // - An empty string in all other cases or if the network name is not | |
251 // exposed by platform APIs. | |
252 std::string id; | |
253 }; | |
254 | |
255 // Returns true if the cached network quality estimate was successfully read. | |
256 bool ReadCachedNetworkQualityEstimate(); | |
257 | |
258 // NetworkChangeNotifier::ConnectionTypeObserver implementation: | |
259 void OnConnectionTypeChanged( | |
260 NetworkChangeNotifier::ConnectionType type) override; | |
261 | |
262 // ExternalEstimateProvider::UpdatedEstimateObserver implementation. | |
263 void OnUpdatedEstimateAvailable() override; | |
264 | |
265 // Return a string equivalent to |type|. | |
266 const char* GetNameForEffectiveConnectionType( | |
267 EffectiveConnectionType type) const; | |
268 | |
269 private: | |
270 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, StoreObservations); | |
271 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestAddObservation); | |
272 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, ObtainOperatingParams); | |
273 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, HalfLifeParam); | |
274 FRIEND_TEST_ALL_PREFIXES(URLRequestTestHTTP, NetworkQualityEstimator); | |
275 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, | |
276 PercentileSameTimestamps); | |
277 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, | |
278 PercentileDifferentTimestamps); | |
279 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, ComputedPercentiles); | |
280 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestCaching); | |
281 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, | |
282 TestLRUCacheMaximumSize); | |
283 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestGetMedianRTTSince); | |
284 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, | |
285 TestExternalEstimateProviderMergeEstimates); | |
286 | |
287 class SocketWatcher; | |
288 class SocketWatcherFactory; | |
289 | |
290 // NetworkQuality is used to cache the quality of a network connection. | |
291 class NET_EXPORT_PRIVATE NetworkQuality { | |
292 public: | |
293 NetworkQuality(); | |
294 // |rtt| is the estimate of the round trip time. | |
295 // |downstream_throughput_kbps| is the estimate of the downstream | |
296 // throughput in kilobits per second. | |
297 NetworkQuality(const base::TimeDelta& rtt, | |
298 int32_t downstream_throughput_kbps); | |
299 NetworkQuality(const NetworkQuality& other); | |
300 ~NetworkQuality(); | |
301 | |
302 NetworkQuality& operator=(const NetworkQuality& other); | |
303 | |
304 // Returns the estimate of the round trip time. | |
305 const base::TimeDelta& rtt() const { return rtt_; } | |
306 | |
307 // Returns the estimate of the downstream throughput in Kbps (Kilobits per | |
308 // second). | |
309 int32_t downstream_throughput_kbps() const { | |
310 return downstream_throughput_kbps_; | |
311 } | |
312 | |
313 private: | |
314 // Estimated round trip time. | |
315 base::TimeDelta rtt_; | |
316 | |
317 // Estimated downstream throughput in kilobits per second. | |
318 int32_t downstream_throughput_kbps_; | |
319 }; | |
320 | |
321 // CachedNetworkQuality stores the quality of a previously seen network. | |
322 class NET_EXPORT_PRIVATE CachedNetworkQuality { | |
323 public: | |
324 explicit CachedNetworkQuality(const NetworkQuality& network_quality); | |
325 CachedNetworkQuality(const CachedNetworkQuality& other); | |
326 ~CachedNetworkQuality(); | |
327 | |
328 // Returns the network quality associated with this cached entry. | |
329 const NetworkQuality& network_quality() const { return network_quality_; } | |
330 | |
331 // Returns true if this cache entry was updated before | |
332 // |cached_network_quality|. | |
333 bool OlderThan(const CachedNetworkQuality& cached_network_quality) const; | |
334 | |
335 // Time when this cache entry was last updated. | |
336 const base::TimeTicks last_update_time_; | |
337 | |
338 // Quality of this cached network. | |
339 const NetworkQuality network_quality_; | |
340 | |
341 private: | |
342 DISALLOW_ASSIGN(CachedNetworkQuality); | |
343 }; | |
344 | |
345 // Records observations of network quality metrics (such as round trip time | |
346 // or throughput), along with the time the observation was made. Observations | |
347 // can be made at several places in the network stack, thus the observation | |
348 // source is provided as well. ValueType must be numerical so that statistics | |
349 // such as median, average can be computed. | |
350 template <typename ValueType> | |
351 struct NET_EXPORT_PRIVATE Observation { | |
352 Observation(const ValueType& value, | |
353 base::TimeTicks timestamp, | |
354 ObservationSource source) | |
355 : value(value), timestamp(timestamp), source(source) { | |
356 DCHECK(!timestamp.is_null()); | |
357 } | |
358 ~Observation() {} | |
359 | |
360 // Value of the observation. | |
361 const ValueType value; | |
362 | |
363 // Time when the observation was taken. | |
364 const base::TimeTicks timestamp; | |
365 | |
366 // The source of the observation. | |
367 const ObservationSource source; | |
368 }; | |
369 | |
370 // Holds an observation and its weight. | |
371 template <typename ValueType> | |
372 struct NET_EXPORT_PRIVATE WeightedObservation { | |
373 WeightedObservation(ValueType value, double weight) | |
374 : value(value), weight(weight) {} | |
375 WeightedObservation(const WeightedObservation& other) | |
376 : WeightedObservation(other.value, other.weight) {} | |
377 | |
378 WeightedObservation& operator=(const WeightedObservation& other) { | |
379 value = other.value; | |
380 weight = other.weight; | |
381 return *this; | |
382 } | |
383 | |
384 // Required for sorting the samples in the ascending order of values. | |
385 bool operator<(const WeightedObservation& other) const { | |
386 return (value < other.value); | |
387 } | |
388 | |
389 // Value of the sample. | |
390 ValueType value; | |
391 | |
392 // Weight of the sample. This is computed based on how much time has passed | |
393 // since the sample was taken. | |
394 double weight; | |
395 }; | |
396 | |
397 // Stores observations sorted by time. | |
398 template <typename ValueType> | |
399 class NET_EXPORT_PRIVATE ObservationBuffer { | |
400 public: | |
401 explicit ObservationBuffer(double weight_multiplier_per_second); | |
402 ~ObservationBuffer(); | |
403 | |
404 // Adds |observation| to the buffer. The oldest observation in the buffer | |
405 // will be evicted to make room if the buffer is already full. | |
406 void AddObservation(const Observation<ValueType>& observation) { | |
407 DCHECK_LE(observations_.size(), | |
408 static_cast<size_t>(kMaximumObservationsBufferSize)); | |
409 // Evict the oldest element if the buffer is already full. | |
410 if (observations_.size() == kMaximumObservationsBufferSize) | |
411 observations_.pop_front(); | |
412 | |
413 observations_.push_back(observation); | |
414 DCHECK_LE(observations_.size(), | |
415 static_cast<size_t>(kMaximumObservationsBufferSize)); | |
416 } | |
417 | |
418 // Clears the observations stored in this buffer. | |
419 void Clear() { observations_.clear(); } | |
420 | |
421 // Returns true iff the |percentile| value of the observations in this | |
422 // buffer is available. Sets |result| to the computed |percentile| | |
423 // value among all observations since |begin_timestamp|. If the value is | |
424 // unavailable, false is returned and |result| is not modified. Percentile | |
425 // value is unavailable if all the values in observation buffer are older | |
426 // than |begin_timestamp|. |result| must not be null. | |
427 // |disallowed_observation_sources| is the list of observation sources that | |
428 // should be excluded when computing the percentile. | |
429 bool GetPercentile( | |
430 const base::TimeTicks& begin_timestamp, | |
431 ValueType* result, | |
432 int percentile, | |
433 const std::vector<ObservationSource>& disallowed_observation_sources) | |
434 const WARN_UNUSED_RESULT; | |
435 | |
436 private: | |
437 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, HalfLifeParam); | |
438 | |
439 // Computes the weighted observations and stores them in | |
440 // |weighted_observations| sorted by ascending |WeightedObservation.value|. | |
441 // Only the observations with timestamp later than |begin_timestamp| are | |
442 // considered. Also, sets |total_weight| to the total weight of all | |
443 // observations. Should be called only when there is at least one | |
444 // observation in the buffer. |disallowed_observation_sources| is the list | |
445 // of observation sources that should be excluded when computing the | |
446 // weighted observations. | |
447 void ComputeWeightedObservations( | |
448 const base::TimeTicks& begin_timestamp, | |
449 std::vector<WeightedObservation<ValueType>>& weighted_observations, | |
450 double* total_weight, | |
451 const std::vector<ObservationSource>& disallowed_observation_sources) | |
452 const; | |
453 | |
454 // Holds observations sorted by time, with the oldest observation at the | |
455 // front of the queue. | |
456 std::deque<Observation<ValueType>> observations_; | |
457 | |
458 // The factor by which the weight of an observation reduces every second. | |
459 // For example, if an observation is 6 seconds old, its weight would be: | |
460 // weight_multiplier_per_second_ ^ 6 | |
461 // Calculated from |kHalfLifeSeconds| by solving the following equation: | |
462 // weight_multiplier_per_second_ ^ kHalfLifeSeconds = 0.5 | |
463 const double weight_multiplier_per_second_; | |
464 | |
465 DISALLOW_COPY_AND_ASSIGN(ObservationBuffer); | |
466 }; | |
467 | |
468 // Value of round trip time observations is in base::TimeDelta. | |
469 typedef net::NetworkQualityEstimator::Observation<base::TimeDelta> | |
470 RttObservation; | |
471 typedef net::NetworkQualityEstimator::ObservationBuffer<base::TimeDelta> | |
472 RttObservationBuffer; | |
473 | |
474 // Value of throughput observations is in kilobits per second. | |
475 typedef net::NetworkQualityEstimator::Observation<int32_t> | |
476 ThroughputObservation; | |
477 typedef net::NetworkQualityEstimator::ObservationBuffer<int32_t> | |
478 ThroughputObservationBuffer; | |
479 | |
480 // This does not use a unordered_map or hash_map for code simplicity (key just | |
481 // implements operator<, rather than hash and equality) and because the map is | |
482 // tiny. | |
483 typedef std::map<NetworkID, CachedNetworkQuality> CachedNetworkQualities; | |
484 | |
485 // Throughput is set to |kInvalidThroughput| if a valid value is | |
486 // unavailable. Readers should discard throughput value if it is set to | |
487 // |kInvalidThroughput|. | |
488 static const int32_t kInvalidThroughput; | |
489 | |
490 // Tiny transfer sizes may give inaccurate throughput results. | |
491 // Minimum size of the transfer over which the throughput is computed. | |
492 static const int kMinTransferSizeInBytes = 10000; | |
493 | |
494 // Minimum duration (in microseconds) of the transfer over which the | |
495 // throughput is computed. | |
496 static const int kMinRequestDurationMicroseconds = 1000; | |
497 | |
498 // Minimum valid value of the variation parameter that holds RTT (in | |
499 // milliseconds) values. | |
500 static const int kMinimumRTTVariationParameterMsec = 1; | |
501 | |
502 // Minimum valid value of the variation parameter that holds throughput (in | |
503 // kilobits per second) values. | |
504 static const int kMinimumThroughputVariationParameterKbps = 1; | |
505 | |
506 // Maximum size of the cache that holds network quality estimates. | |
507 // Smaller size may reduce the cache hit rate due to frequent evictions. | |
508 // Larger size may affect performance. | |
509 static const size_t kMaximumNetworkQualityCacheSize = 10; | |
510 | |
511 // Maximum number of observations that can be held in the ObservationBuffer. | |
512 static const size_t kMaximumObservationsBufferSize = 300; | |
513 | |
514 // Time duration (in milliseconds) after which the estimate provided by | |
515 // external estimate provider is considered stale. | |
516 static const int kExternalEstimateProviderFreshnessDurationMsec = | |
517 5 * 60 * 1000; | |
518 | |
519 // Returns the RTT value to be used when the valid RTT is unavailable. Readers | |
520 // should discard RTT if it is set to the value returned by |InvalidRTT()|. | |
521 static const base::TimeDelta InvalidRTT(); | |
522 | |
523 // Notifies |this| of a new transport layer RTT. | |
524 void OnUpdatedRTTAvailable(SocketPerformanceWatcherFactory::Protocol protocol, | |
525 const base::TimeDelta& rtt); | |
526 | |
527 // Queries the external estimate provider for the latest network quality | |
528 // estimates, and adds those estimates to the current observation buffer. | |
529 void QueryExternalEstimateProvider(); | |
530 | |
531 // Obtains operating parameters from the field trial parameters. | |
532 void ObtainOperatingParams( | |
533 const std::map<std::string, std::string>& variation_params); | |
534 | |
535 // Obtains the model parameters for different effective connection types from | |
536 // the field trial parameters. For each effective connection type, a model | |
537 // (currently composed of a RTT threshold and a downlink throughput threshold) | |
538 // is provided by the field trial. | |
539 void ObtainEffectiveConnectionTypeModelParams( | |
540 const std::map<std::string, std::string>& variation_params); | |
541 | |
542 // Adds the default median RTT and downstream throughput estimate for the | |
543 // current connection type to the observation buffer. | |
544 void AddDefaultEstimates(); | |
545 | |
546 // Returns an estimate of network quality at the specified |percentile|. | |
547 // |disallowed_observation_sources| is the list of observation sources that | |
548 // should be excluded when computing the percentile. | |
549 // Only the observations later than |begin_timestamp| are taken into account. | |
550 // |percentile| must be between 0 and 100 (both inclusive) with higher | |
551 // percentiles indicating less performant networks. For example, if | |
552 // |percentile| is 90, then the network is expected to be faster than the | |
553 // returned estimate with 0.9 probability. Similarly, network is expected to | |
554 // be slower than the returned estimate with 0.1 probability. | |
555 base::TimeDelta GetRTTEstimateInternal( | |
556 const std::vector<ObservationSource>& disallowed_observation_sources, | |
557 const base::TimeTicks& begin_timestamp, | |
558 int percentile) const; | |
559 int32_t GetDownlinkThroughputKbpsEstimateInternal( | |
560 const base::TimeTicks& begin_timestamp, | |
561 int percentile) const; | |
562 | |
563 // Returns the current network ID checking by calling the platform APIs. | |
564 // Virtualized for testing. | |
565 virtual NetworkID GetCurrentNetworkID() const; | |
566 | |
567 // Writes the estimated quality of the current network to the cache. | |
568 void CacheNetworkQualityEstimate(); | |
569 | |
570 void NotifyObserversOfRTT(const RttObservation& observation); | |
571 | |
572 void NotifyObserversOfThroughput(const ThroughputObservation& observation); | |
573 | |
574 // Records the UMA related to RTT. | |
575 void RecordRTTUMA(int32_t estimated_value_msec, | |
576 int32_t actual_value_msec) const; | |
577 | |
578 // Returns true only if |request| can be used for network quality estimation. | |
579 // Only the requests that go over network are considered to provide useful | |
580 // observations. | |
581 bool RequestProvidesUsefulObservations(const URLRequest& request) const; | |
582 | |
583 // Values of external estimate provider status. This enum must remain | |
584 // synchronized with the enum of the same name in | |
585 // metrics/histograms/histograms.xml. | |
586 enum NQEExternalEstimateProviderStatus { | |
587 EXTERNAL_ESTIMATE_PROVIDER_STATUS_NOT_AVAILABLE, | |
588 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE, | |
589 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERIED, | |
590 EXTERNAL_ESTIMATE_PROVIDER_STATUS_QUERY_SUCCESSFUL, | |
591 EXTERNAL_ESTIMATE_PROVIDER_STATUS_CALLBACK, | |
592 EXTERNAL_ESTIMATE_PROVIDER_STATUS_RTT_AVAILABLE, | |
593 EXTERNAL_ESTIMATE_PROVIDER_STATUS_DOWNLINK_BANDWIDTH_AVAILABLE, | |
594 EXTERNAL_ESTIMATE_PROVIDER_STATUS_BOUNDARY | |
595 }; | |
596 | |
597 // Records the metrics related to external estimate provider. | |
598 void RecordExternalEstimateProviderMetrics( | |
599 NQEExternalEstimateProviderStatus status) const; | |
600 | |
601 // Determines if the requests to local host can be used in estimating the | |
602 // network quality. Set to true only for tests. | |
603 const bool allow_localhost_requests_; | |
604 | |
605 // Determines if the responses smaller than |kMinTransferSizeInBytes| | |
606 // or shorter than |kMinTransferSizeInBytes| can be used in estimating the | |
607 // network quality. Set to true only for tests. | |
608 const bool allow_small_responses_; | |
609 | |
610 // The factor by which the weight of an observation reduces every second. | |
611 const double weight_multiplier_per_second_; | |
612 | |
613 // Time when last connection change was observed. | |
614 base::TimeTicks last_connection_change_; | |
615 | |
616 // ID of the current network. | |
617 NetworkID current_network_id_; | |
618 | |
619 // Peak network quality (fastest round-trip-time (RTT) and highest | |
620 // downstream throughput) measured since last connectivity change. RTT is | |
621 // measured from time the request is sent until the first byte received. | |
622 // The accuracy is decreased by ignoring these factors: | |
623 // 1) Multiple URLRequests can occur concurrently. | |
624 // 2) Includes server processing time. | |
625 NetworkQuality peak_network_quality_; | |
626 | |
627 // Cache that stores quality of previously seen networks. | |
628 CachedNetworkQualities cached_network_qualities_; | |
629 | |
630 // Buffer that holds throughput observations (in kilobits per second) sorted | |
631 // by timestamp. | |
632 ThroughputObservationBuffer downstream_throughput_kbps_observations_; | |
633 | |
634 // Buffer that holds RTT observations sorted by timestamp. | |
635 RttObservationBuffer rtt_observations_; | |
636 | |
637 // Default network quality observations obtained from the network quality | |
638 // estimator field trial parameters. The observations are indexed by | |
639 // ConnectionType. | |
640 NetworkQuality | |
641 default_observations_[NetworkChangeNotifier::CONNECTION_LAST + 1]; | |
642 | |
643 // Thresholds for different effective connection types obtained from field | |
644 // trial variation params. These thresholds encode how different connection | |
645 // types behave in general. In future, complex encodings (e.g., curve | |
646 // fitting) may be used. | |
647 NetworkQuality connection_thresholds_[EFFECTIVE_CONNECTION_TYPE_LAST]; | |
648 | |
649 // Estimated network quality. Updated on mainframe requests. | |
650 NetworkQuality estimated_median_network_quality_; | |
651 | |
652 // ExternalEstimateProvider that provides network quality using operating | |
653 // system APIs. May be NULL. | |
654 const std::unique_ptr<ExternalEstimateProvider> external_estimate_provider_; | |
655 | |
656 // Observer lists for round trip times and throughput measurements. | |
657 base::ObserverList<RTTObserver> rtt_observer_list_; | |
658 base::ObserverList<ThroughputObserver> throughput_observer_list_; | |
659 | |
660 std::unique_ptr<SocketPerformanceWatcherFactory> watcher_factory_; | |
661 | |
662 base::ThreadChecker thread_checker_; | |
663 | |
664 base::WeakPtrFactory<NetworkQualityEstimator> weak_ptr_factory_; | |
665 | |
666 DISALLOW_COPY_AND_ASSIGN(NetworkQualityEstimator); | |
667 }; | |
668 | |
669 } // namespace net | |
670 | |
671 #endif // NET_BASE_NETWORK_QUALITY_ESTIMATOR_H_ | |
OLD | NEW |