1 // Copyright 2018 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 SERVICES_NETWORK_PUBLIC_CPP_NETWORK_QUALITY_TRACKER_H_
6 #define SERVICES_NETWORK_PUBLIC_CPP_NETWORK_QUALITY_TRACKER_H_
7
8 #include <memory>
9
10 #include "base/callback.h"
11 #include "base/component_export.h"
12 #include "base/macros.h"
13 #include "base/observer_list.h"
14 #include "base/sequence_checker.h"
15 #include "mojo/public/cpp/bindings/receiver.h"
16 #include "net/nqe/effective_connection_type.h"
17 #include "services/network/public/mojom/network_quality_estimator_manager.mojom.h"
18 #include "services/network/public/mojom/network_service.mojom-forward.h"
19
20 namespace network {
21
22 // This class subscribes to network quality change events from
23 // network::mojom::NetworkQualityEstimatorManagerClient and propagates these
24 // notifications to its list of EffectiveConnectionTypeObserver registered
25 // through AddObserver() and RemoveObserver().
COMPONENT_EXPORT(NETWORK_CPP)26 class COMPONENT_EXPORT(NETWORK_CPP) NetworkQualityTracker
27 : public network::mojom::NetworkQualityEstimatorManagerClient {
28 public:
29 class COMPONENT_EXPORT(NETWORK_CPP) EffectiveConnectionTypeObserver {
30 public:
31 // Called when there is a change in the effective connection type. The
32 // |observer| is notified of the current effective connection type on the
33 // same thread on which it was added.
34 virtual void OnEffectiveConnectionTypeChanged(
35 net::EffectiveConnectionType type) = 0;
36
37 protected:
38 EffectiveConnectionTypeObserver() {}
39 virtual ~EffectiveConnectionTypeObserver() {}
40
41 private:
42 DISALLOW_COPY_AND_ASSIGN(EffectiveConnectionTypeObserver);
43 };
44
45 // Observes changes in the HTTP RTT, transport RTT or downstream throughput
46 // estimates.
47 class COMPONENT_EXPORT(NETWORK_CPP) RTTAndThroughputEstimatesObserver {
48 public:
49 // Called when there is a substantial change in either HTTP RTT, transport
50 // RTT or downstream estimate. If either of the RTT estimates are
51 // unavailable, then the value of that estimate is set to base::TimeDelta().
52 // If downstream estimate is unavailable, its value is set to INT32_MAX.
53 // The |observer| is notified of the current effective connection type on
54 // the same thread on which it was added.
55 virtual void OnRTTOrThroughputEstimatesComputed(
56 base::TimeDelta http_rtt,
57 base::TimeDelta transport_rtt,
58 int32_t downstream_throughput_kbps) = 0;
59
60 virtual ~RTTAndThroughputEstimatesObserver() {}
61
62 protected:
63 RTTAndThroughputEstimatesObserver() {}
64
65 private:
66 DISALLOW_COPY_AND_ASSIGN(RTTAndThroughputEstimatesObserver);
67 };
68
69 // Running the |callback| returns the network service in use.
70 // NetworkQualityTracker does not need to be destroyed before the network
71 // service.
72 explicit NetworkQualityTracker(
73 base::RepeatingCallback<network::mojom::NetworkService*()> callback);
74
75 ~NetworkQualityTracker() override;
76
77 // Returns the current estimate of the effective connection type.
78 virtual net::EffectiveConnectionType GetEffectiveConnectionType() const;
79
80 // Returns the current HTTP RTT estimate. The RTT at the HTTP layer measures
81 // the time from when the request was sent (this happens after the connection
82 // is established) to the time when the response headers were received.
83 virtual base::TimeDelta GetHttpRTT() const;
84
85 // Returns the current transport-layer RTT estimate. The RTT at the transport
86 // layer provides an aggregate estimate of the transport RTT as computed by
87 // various underlying TCP and QUIC connections.
88 virtual base::TimeDelta GetTransportRTT() const;
89
90 // Returns the current downstream throughput estimate (in kilobits per
91 // second).
92 virtual int32_t GetDownstreamThroughputKbps() const;
93
94 // Registers |observer| to receive notifications of network changes. The
95 // thread on which this is called is the thread on which |observer| will be
96 // called back with notifications. The |observer| is notified of the current
97 // effective connection type on the same thread. At the time |observer| is
98 // added, if the estimated effective connection type is unknown, then the
99 // |observer| is not notified until there is a change in the network quality
100 // estimate.
101 void AddEffectiveConnectionTypeObserver(
102 EffectiveConnectionTypeObserver* observer);
103
104 // Unregisters |observer| from receiving notifications. This must be called
105 // on the same thread on which AddObserver() was called.
106 // All observers must be unregistered before |this| is destroyed.
107 void RemoveEffectiveConnectionTypeObserver(
108 EffectiveConnectionTypeObserver* observer);
109
110 // Registers |observer| to receive notifications of RTT or throughput changes.
111 // This should be called on the same thread as the thread on which |this| is
112 // created. The |observer| would be called back with notifications on that
113 // same thread. The |observer| is notified of the current HTTP RTT, transport
114 // RTT and downstrean bandwidth estimates on the same thread. If either of the
115 // RTT estimate are unavailable, then the value of that estimate is set to
116 // base::TimeDelta(). If downstream estimate is unavailable, its value is set
117 // to INT32_MAX. The |observer| is notified of the current RTT and
118 // throughput estimates synchronously when this method is invoked.
119 void AddRTTAndThroughputEstimatesObserver(
120 RTTAndThroughputEstimatesObserver* observer);
121
122 // Unregisters |observer| from receiving notifications. This must be called
123 // on the same thread on which AddObserver() was called.
124 // All observers must be unregistered before |this| is destroyed.
125 void RemoveRTTAndThroughputEstimatesObserver(
126 RTTAndThroughputEstimatesObserver* observer);
127
128 // Changes effective connection type estimate to the provided value, and
129 // reports |effective_connection_type| to all
130 // EffectiveConnectionTypeObservers. Calling this also disables all organic
131 // notifications sent to observers.
132 void ReportEffectiveConnectionTypeForTesting(
133 net::EffectiveConnectionType effective_connection_type);
134
135 // Changes RTT and throughput estimate to the provided estimates, and
136 // reports it to all RTTAndThroughputEstimatesObservers. Calling this also
137 // disables all organic notifications sent to observers.
138 void ReportRTTsAndThroughputForTesting(base::TimeDelta http_rtt,
139 int32_t downstream_throughput_kbps);
140
141 protected:
142 // Constructor for testing purposes only without the network service instance.
143 NetworkQualityTracker();
144
145 // NetworkQualityEstimatorManagerClient implementation. Protected for testing.
146 void OnNetworkQualityChanged(
147 net::EffectiveConnectionType effective_connection_type,
148 base::TimeDelta http_rtt,
149 base::TimeDelta transport_rtt,
150 int32_t downlink_bandwidth_kbps) override;
151
152 private:
153 // Starts listening for network quality change notifications from
154 // network_service. Observers may be added and GetEffectiveConnectionType
155 // called, but no network information will be provided until this method is
156 // called.
157 void InitializeMojoChannel();
158
159 void HandleNetworkServicePipeBroken();
160
161 // Running the |get_network_service_callback_| returns the network service in
162 // use.
163 const base::RepeatingCallback<network::mojom::NetworkService*()>
164 get_network_service_callback_;
165
166 net::EffectiveConnectionType effective_connection_type_;
167 base::TimeDelta http_rtt_;
168 base::TimeDelta transport_rtt_;
169 int32_t downlink_bandwidth_kbps_;
170
171 // True if network quality has been overridden by tests. If set to true, it
172 // disables all organic notifications sent to observers.
173 bool network_quality_overridden_for_testing_;
174
175 base::ObserverList<EffectiveConnectionTypeObserver>::Unchecked
176 effective_connection_type_observer_list_;
177
178 base::ObserverList<RTTAndThroughputEstimatesObserver>::Unchecked
179 rtt_and_throughput_observer_list_;
180
181 mojo::Receiver<network::mojom::NetworkQualityEstimatorManagerClient>
182 receiver_{this};
183
184 SEQUENCE_CHECKER(sequence_checker_);
185
186 DISALLOW_COPY_AND_ASSIGN(NetworkQualityTracker);
187 };
188
189 } // namespace network
190
191 #endif // SERVICES_NETWORK_PUBLIC_CPP_NETWORK_QUALITY_TRACKER_H_
192