forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
throughput_analyzer.h
194 lines (152 loc) · 7.46 KB
/
throughput_analyzer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_NQE_THROUGHPUT_ANALYZER_H_
#define NET_NQE_THROUGHPUT_ANALYZER_H_
#include <stdint.h>
#include "base/callback.h"
#include "base/containers/hash_tables.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
#include "net/log/net_log_with_source.h"
namespace {
typedef base::Callback<void(int32_t)> ThroughputObservationCallback;
}
namespace base {
class SingleThreadTaskRunner;
}
namespace net {
class NetworkQualityEstimatorParams;
class URLRequest;
namespace nqe {
namespace internal {
// Makes throughput observations. Polls NetworkActivityMonitor
// (TrafficStats on Android) to count number of bits received over throughput
// observation windows in accordance with the following rules:
// (1) A new window of observation begins any time a URL request header is
// about to be sent, or a request completes or is destroyed.
// (2) A request is "active" if its headers are sent, but it hasn't completed,
// and "local" if destined to local host. If at any time during a
// throughput observation window there is an active, local request, the
// window is discarded.
// (3) If less than 32KB is received over the network during a window of
// observation, that window is discarded.
class NET_EXPORT_PRIVATE ThroughputAnalyzer {
public:
// |throughput_observation_callback| is called on the |task_runner| when
// |this| has a new throughput observation.
// |use_local_host_requests_for_tests| should only be true when testing
// against local HTTP server and allows the requests to local host to be
// used for network quality estimation. |use_smaller_responses_for_tests|
// should only be true when testing, and allows the responses smaller than
// |kMinTransferSizeInBits| or shorter than
// |kMinRequestDurationMicroseconds| to be used for network quality
// estimation.
// Virtualized for testing.
ThroughputAnalyzer(
const NetworkQualityEstimatorParams* params,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
ThroughputObservationCallback throughput_observation_callback,
bool use_local_host_requests_for_tests,
bool use_smaller_responses_for_tests,
const NetLogWithSource& net_log);
virtual ~ThroughputAnalyzer();
// Notifies |this| that the headers of |request| are about to be sent.
void NotifyStartTransaction(const URLRequest& request);
// Notifies |this| that |request| has completed.
void NotifyRequestCompleted(const URLRequest& request);
// Notifies |this| of a change in connection type.
void OnConnectionTypeChanged();
// |use_localhost_requests| should only be true when testing against local
// HTTP server and allows the requests to local host to be used for network
// quality estimation.
void SetUseLocalHostRequestsForTesting(bool use_localhost_requests);
// |use_smaller_responses_for_tests| should only be true when testing, and
// allows the responses smaller than |kMinTransferSizeInBits| or shorter than
// |kMinRequestDurationMicroseconds| to be used for network quality
// estimation.
void SetUseSmallResponsesForTesting(bool use_small_responses);
// Returns true if throughput is currently tracked by a throughput
// observation window.
bool IsCurrentlyTrackingThroughput() const;
protected:
// Exposed for testing.
bool disable_throughput_measurements() const {
return disable_throughput_measurements_;
}
// Returns the number of bits received by Chromium so far. The count may not
// start from zero, so the caller should only look at difference from a prior
// call. The count is obtained by polling TrafficStats on Android, and
// net::NetworkActivityMonitor on all other platforms. Virtualized for
// testing.
virtual int64_t GetBitsReceived() const;
private:
friend class TestThroughputAnalyzer;
typedef base::hash_set<const URLRequest*> Requests;
// Returns true if downstream throughput can be recorded. In that case,
// |downstream_kbps| is set to the computed downstream throughput (in
// kilobits per second). If a downstream throughput observation is taken,
// then the throughput observation window is reset so as to continue
// tracking throughput. A throughput observation can be taken only if the
// time-window is currently active, and enough bytes have accumulated in
// that window. |downstream_kbps| should not be null.
bool MaybeGetThroughputObservation(int32_t* downstream_kbps);
// Starts the throughput observation window that keeps track of network
// bytes if the following conditions are true:
// (i) All active requests are non-local;
// (ii) There is at least one active, non-local request; and,
// (iii) The throughput observation window is not already tracking
// throughput. The window is started by setting the |start_| and
// |bits_received_|.
void MaybeStartThroughputObservationWindow();
// EndThroughputObservationWindow ends the throughput observation window.
void EndThroughputObservationWindow();
// Returns true if the |request| degrades the accuracy of the throughput
// observation window. A local request or a request that spans a connection
// change degrades the accuracy of the throughput computation.
bool DegradesAccuracy(const URLRequest& request) const;
// Bounds |accuracy_degrading_requests_| and |requests_| to ensure their sizes
// do not exceed their capacities.
void BoundRequestsSize();
const NetworkQualityEstimatorParams* params_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
// Called every time a new throughput observation is available.
ThroughputObservationCallback throughput_observation_callback_;
// Time when last connection change was observed.
base::TimeTicks last_connection_change_;
// Start time of the current throughput observation window. Set to null if
// the window is not currently active.
base::TimeTicks window_start_time_;
// Number of bits received prior to |start_| as reported by
// NetworkActivityMonitor.
int64_t bits_received_at_window_start_;
// Container that holds active requests that reduce the accuracy of
// throughput computation. These requests are not used in throughput
// computation.
Requests accuracy_degrading_requests_;
// Container that holds active requests that do not reduce the accuracy of
// throughput computation. These requests are used in throughput computation.
Requests requests_;
// If true, then |this| throughput analyzer stops tracking the throughput
// observations until Chromium is restarted. This may happen if the throughput
// analyzer has lost track of the requests that degrade throughput computation
// accuracy.
bool disable_throughput_measurements_;
// Determines if the requests to local host can be used in estimating the
// network quality. Set to true only for tests.
bool use_localhost_requests_for_tests_;
// Determines if the responses smaller than |kMinTransferSizeInBits|
// or shorter than |kMinTransferSizeInBits| can be used in estimating the
// network quality. Set to true only for tests.
bool use_small_responses_for_tests_;
base::ThreadChecker thread_checker_;
NetLogWithSource net_log_;
DISALLOW_COPY_AND_ASSIGN(ThroughputAnalyzer);
};
} // namespace internal
} // namespace nqe
} // namespace net
#endif // NET_NQE_THROUGHPUT_ANALYZER_H_