Revert of Re-enabling webrtc Telemetry tests. (patchset #1 id:1 of https://codereview...
[chromium-blink-merge.git] / net / base / network_quality_estimator.h
blob02a178296d172e1ac60b9e52673f6448a879c222
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.
5 #ifndef NET_BASE_NETWORK_QUALITY_ESTIMATOR_H_
6 #define NET_BASE_NETWORK_QUALITY_ESTIMATOR_H_
8 #include <stdint.h>
10 #include <deque>
11 #include <map>
13 #include "base/gtest_prod_util.h"
14 #include "base/macros.h"
15 #include "base/threading/thread_checker.h"
16 #include "base/time/time.h"
17 #include "net/base/net_export.h"
18 #include "net/base/network_change_notifier.h"
19 #include "net/base/network_quality.h"
21 namespace net {
23 // NetworkQualityEstimator provides network quality estimates (quality of the
24 // full paths to all origins that have been connected to).
25 // The estimates are based on the observed organic traffic.
26 // A NetworkQualityEstimator instance is attached to URLRequestContexts and
27 // observes the traffic of URLRequests spawned from the URLRequestContexts.
28 // A single instance of NQE can be attached to multiple URLRequestContexts,
29 // thereby increasing the single NQE instance's accuracy by providing more
30 // observed traffic characteristics.
31 class NET_EXPORT_PRIVATE NetworkQualityEstimator
32 : public NetworkChangeNotifier::ConnectionTypeObserver {
33 public:
34 // Creates a new NetworkQualityEstimator.
35 // |variation_params| is the map containing all field trial parameters
36 // related to NetworkQualityEstimator field trial.
37 explicit NetworkQualityEstimator(
38 const std::map<std::string, std::string>& variation_params);
40 ~NetworkQualityEstimator() override;
42 // Returns the peak estimates (fastest RTT and peak throughput) of the
43 // current network.
44 // Virtualized for testing.
45 virtual NetworkQuality GetPeakEstimate() const;
47 // Sets |median| to the estimate of median network quality. The estimated
48 // quality is computed using a weighted median algorithm that assigns higher
49 // weight to the recent observations. |median| must not be nullptr. Returns
50 // true only if an estimate of the network quality is available (enough
51 // observations must be available to make an estimate). Virtualized for
52 // testing.
53 virtual bool GetEstimate(NetworkQuality* median) const;
55 // Notifies NetworkQualityEstimator that a response has been received.
56 // |cumulative_prefilter_bytes_read| is the count of the bytes received prior
57 // to applying filters (e.g. decompression, SDCH) from request creation time
58 // until now.
59 // |prefiltered_bytes_read| is the count of the bytes received prior
60 // to applying filters in the most recent read.
61 void NotifyDataReceived(const URLRequest& request,
62 int64_t cumulative_prefilter_bytes_read,
63 int64_t prefiltered_bytes_read);
65 private:
66 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, StoreObservations);
67 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest,
68 TestPeakKbpsFastestRTTUpdates);
69 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestAddObservation);
70 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, ObtainOperatingParams);
71 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, HalfLifeParam);
72 FRIEND_TEST_ALL_PREFIXES(URLRequestTestHTTP, NetworkQualityEstimator);
73 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest,
74 PercentileSameTimestamps);
75 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest,
76 PercentileDifferentTimestamps);
77 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, ComputedPercentiles);
79 // Records the round trip time or throughput observation, along with the time
80 // the observation was made.
81 struct NET_EXPORT_PRIVATE Observation {
82 Observation(int32_t value, base::TimeTicks timestamp);
84 ~Observation();
86 // Value of the observation.
87 const int32_t value;
89 // Time when the observation was taken.
90 const base::TimeTicks timestamp;
93 // Holds an observation and its weight.
94 struct WeightedObservation {
95 WeightedObservation(int32_t value, double weight)
96 : value(value), weight(weight) {}
97 WeightedObservation(const WeightedObservation& other)
98 : WeightedObservation(other.value, other.weight) {}
100 WeightedObservation& operator=(const WeightedObservation& other) {
101 value = other.value;
102 weight = other.weight;
103 return *this;
106 // Required for sorting the samples in the ascending order of values.
107 bool operator<(const WeightedObservation& other) const {
108 return (value < other.value);
111 // Value of the sample.
112 int32_t value;
114 // Weight of the sample. This is computed based on how much time has passed
115 // since the sample was taken.
116 double weight;
119 // Stores observations sorted by time.
120 class NET_EXPORT_PRIVATE ObservationBuffer {
121 public:
122 explicit ObservationBuffer(double weight_multiplier_per_second);
124 ~ObservationBuffer();
126 // Adds |observation| to the buffer. The oldest observation in the buffer
127 // will be evicted to make room if the buffer is already full.
128 void AddObservation(const Observation& observation);
130 // Returns the number of observations in this buffer.
131 size_t Size() const;
133 // Clears the observations stored in this buffer.
134 void Clear();
136 // Returns the |percentile| value of the observations in this buffer.
137 int32_t GetPercentile(int percentile) const;
139 private:
140 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, StoreObservations);
141 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest,
142 ObtainOperatingParams);
143 FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, HalfLifeParam);
145 // Computes the weighted observations and stores them in
146 // |weighted_observations| sorted by ascending |WeightedObservation.value|.
147 // Sets |total_weight| to the total weight of all observations. Should be
148 // called only when there is at least one observation in the buffer.
149 void ComputeWeightedObservations(
150 std::vector<WeightedObservation>& weighted_observations,
151 double* total_weight) const;
153 // Holds observations sorted by time, with the oldest observation at the
154 // front of the queue.
155 std::deque<Observation> observations_;
157 // The factor by which the weight of an observation reduces every second.
158 // For example, if an observation is 6 seconds old, its weight would be:
159 // weight_multiplier_per_second_ ^ 6
160 // Calculated from |kHalfLifeSeconds| by solving the following equation:
161 // weight_multiplier_per_second_ ^ kHalfLifeSeconds = 0.5
162 const double weight_multiplier_per_second_;
164 DISALLOW_COPY_AND_ASSIGN(ObservationBuffer);
167 // Tiny transfer sizes may give inaccurate throughput results.
168 // Minimum size of the transfer over which the throughput is computed.
169 static const int kMinTransferSizeInBytes = 10000;
171 // Minimum duration (in microseconds) of the transfer over which the
172 // throughput is computed.
173 static const int kMinRequestDurationMicroseconds = 1000;
175 // Minimum valid value of the variation parameter that holds RTT (in
176 // milliseconds) values.
177 static const int kMinimumRTTVariationParameterMsec = 1;
179 // Minimum valid value of the variation parameter that holds throughput (in
180 // kbps) values.
181 static const int kMinimumThroughputVariationParameterKbps = 1;
183 // Construct a NetworkQualityEstimator instance allowing for test
184 // configuration. Registers for network type change notifications so estimates
185 // can be kept network specific.
186 // |variation_params| is the map containing all field trial parameters for the
187 // network quality estimator field trial.
188 // |allow_local_host_requests_for_tests| should only be true when testing
189 // against local HTTP server and allows the requests to local host to be
190 // used for network quality estimation.
191 // |allow_smaller_responses_for_tests| should only be true when testing
192 // against local HTTP server and allows the responses smaller than
193 // |kMinTransferSizeInBytes| or shorter than |kMinRequestDurationMicroseconds|
194 // to be used for network quality estimation.
195 NetworkQualityEstimator(
196 const std::map<std::string, std::string>& variation_params,
197 bool allow_local_host_requests_for_tests,
198 bool allow_smaller_responses_for_tests);
200 // Obtains operating parameters from the field trial parameters.
201 void ObtainOperatingParams(
202 const std::map<std::string, std::string>& variation_params);
204 // Adds the default median RTT and downstream throughput estimate for the
205 // current connection type to the observation buffer.
206 void AddDefaultEstimates();
208 // Returns the maximum size of the observation buffer.
209 // Used for testing.
210 size_t GetMaximumObservationBufferSizeForTests() const;
212 // Returns true if the size of all observation buffers is equal to the
213 // |expected_size|. Used for testing.
214 bool VerifyBufferSizeForTests(size_t expected_size) const;
216 // NetworkChangeNotifier::ConnectionTypeObserver implementation.
217 void OnConnectionTypeChanged(
218 NetworkChangeNotifier::ConnectionType type) override;
220 // Returns an estimate of network quality at the specified |percentile|.
221 // |percentile| must be between 0 and 100 (both inclusive) with higher
222 // percentiles indicating less performant networks. For example, if
223 // |percentile| is 90, then the network is expected to be faster than the
224 // returned estimate with 0.9 probability. Similarly, network is expected to
225 // be slower than the returned estimate with 0.1 probability.
226 NetworkQuality GetEstimate(int percentile) const;
228 // Determines if the requests to local host can be used in estimating the
229 // network quality. Set to true only for tests.
230 const bool allow_localhost_requests_;
232 // Determines if the responses smaller than |kMinTransferSizeInBytes|
233 // or shorter than |kMinTransferSizeInBytes| can be used in estimating the
234 // network quality. Set to true only for tests.
235 const bool allow_small_responses_;
237 // Time when last connection change was observed.
238 base::TimeTicks last_connection_change_;
240 // Last value passed to |OnConnectionTypeChanged|. This indicates the
241 // current connection type.
242 NetworkChangeNotifier::ConnectionType current_connection_type_;
244 // Fastest round-trip-time (RTT) since last connectivity change. RTT measured
245 // from URLRequest creation until first byte received.
246 base::TimeDelta fastest_rtt_since_last_connection_change_;
248 // Rough measurement of downstream peak Kbps witnessed since last connectivity
249 // change. The accuracy is decreased by ignoring these factors:
250 // 1) Multiple URLRequests can occur concurrently.
251 // 2) The transfer time includes at least one RTT while no bytes are read.
252 int32_t peak_kbps_since_last_connection_change_;
254 // Buffer that holds Kbps observations sorted by timestamp.
255 ObservationBuffer kbps_observations_;
257 // Buffer that holds RTT (in milliseconds) observations sorted by timestamp.
258 ObservationBuffer rtt_msec_observations_;
260 // Default network quality observations obtained from the network quality
261 // estimator field trial parameters. The observations are indexed by
262 // ConnectionType.
263 NetworkQuality
264 default_observations_[NetworkChangeNotifier::CONNECTION_LAST + 1];
266 base::ThreadChecker thread_checker_;
268 DISALLOW_COPY_AND_ASSIGN(NetworkQualityEstimator);
271 } // namespace net
273 #endif // NET_BASE_NETWORK_QUALITY_ESTIMATOR_H_