blob: fe8d091a6e35edce51c25bed30e79b85823fba93 [file] [log] [blame]
[email protected]446df2952012-02-28 07:22:511// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]100d5fb92009-12-21 21:08:352// 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_CHANGE_NOTIFIER_H_
6#define NET_BASE_NETWORK_CHANGE_NOTIFIER_H_
7
8#include "base/basictypes.h"
[email protected]66761b952010-06-25 21:30:389#include "base/observer_list_threadsafe.h"
[email protected]03848872012-12-08 02:46:4110#include "base/time.h"
[email protected]172da1b2011-08-12 15:52:2611#include "net/base/net_export.h"
[email protected]100d5fb92009-12-21 21:08:3512
[email protected]cde8b3c2012-08-13 19:20:5213class GURL;
14
[email protected]100d5fb92009-12-21 21:08:3515namespace net {
16
[email protected]bb0e34542012-08-31 19:52:4017struct DnsConfig;
[email protected]cde8b3c2012-08-13 19:20:5218class HistogramWatcher;
[email protected]373badd2011-07-11 21:55:5819class NetworkChangeNotifierFactory;
20
[email protected]67172802012-07-16 22:27:2421#if defined(OS_LINUX)
[email protected]bb0e34542012-08-31 19:52:4022namespace internal {
[email protected]67172802012-07-16 22:27:2423class AddressTrackerLinux;
[email protected]05aad32d2012-05-16 18:10:5324}
[email protected]bb0e34542012-08-31 19:52:4025#endif
[email protected]05aad32d2012-05-16 18:10:5326
[email protected]100d5fb92009-12-21 21:08:3527// NetworkChangeNotifier monitors the system for network changes, and notifies
[email protected]66761b952010-06-25 21:30:3828// registered observers of those events. Observers may register on any thread,
29// and will be called back on the thread from which they registered.
[email protected]aab66932011-10-05 17:08:1330// NetworkChangeNotifiers are threadsafe, though they must be created and
31// destroyed on the same thread.
[email protected]172da1b2011-08-12 15:52:2632class NET_EXPORT NetworkChangeNotifier {
[email protected]100d5fb92009-12-21 21:08:3533 public:
[email protected]8bbc7a792012-05-24 11:30:0534 // Using the terminology of the Network Information API:
35 // http://www.w3.org/TR/netinfo-api.
36 enum ConnectionType {
[email protected]e0535b02012-09-11 00:30:3737 CONNECTION_UNKNOWN = 0, // A connection exists, but its type is unknown.
38 CONNECTION_ETHERNET = 1,
39 CONNECTION_WIFI = 2,
40 CONNECTION_2G = 3,
41 CONNECTION_3G = 4,
42 CONNECTION_4G = 5,
43 CONNECTION_NONE = 6 // No connection.
[email protected]a6b32f6e2012-06-20 23:46:2644 };
[email protected]8bbc7a792012-05-24 11:30:0545
[email protected]172da1b2011-08-12 15:52:2646 class NET_EXPORT IPAddressObserver {
[email protected]100d5fb92009-12-21 21:08:3547 public:
[email protected]100d5fb92009-12-21 21:08:3548 // Will be called when the IP address of the primary interface changes.
49 // This includes when the primary interface itself changes.
50 virtual void OnIPAddressChanged() = 0;
51
52 protected:
[email protected]232a5812011-03-04 22:42:0853 IPAddressObserver() {}
[email protected]e0845d5f2012-05-29 00:11:4154 virtual ~IPAddressObserver() {}
[email protected]100d5fb92009-12-21 21:08:3555
56 private:
[email protected]232a5812011-03-04 22:42:0857 DISALLOW_COPY_AND_ASSIGN(IPAddressObserver);
58 };
59
[email protected]8bbc7a792012-05-24 11:30:0560 class NET_EXPORT ConnectionTypeObserver {
[email protected]232a5812011-03-04 22:42:0861 public:
[email protected]e0845d5f2012-05-29 00:11:4162 // Will be called when the connection type of the system has changed.
63 // See NetworkChangeNotifier::GetConnectionType() for important caveats
64 // about the unreliability of using this signal to infer the ability to
65 // reach remote sites.
[email protected]8bbc7a792012-05-24 11:30:0566 virtual void OnConnectionTypeChanged(ConnectionType type) = 0;
[email protected]232a5812011-03-04 22:42:0867
68 protected:
[email protected]8bbc7a792012-05-24 11:30:0569 ConnectionTypeObserver() {}
[email protected]e0845d5f2012-05-29 00:11:4170 virtual ~ConnectionTypeObserver() {}
[email protected]232a5812011-03-04 22:42:0871
72 private:
[email protected]8bbc7a792012-05-24 11:30:0573 DISALLOW_COPY_AND_ASSIGN(ConnectionTypeObserver);
[email protected]100d5fb92009-12-21 21:08:3574 };
75
[email protected]46018c9d2011-09-06 03:42:3476 class NET_EXPORT DNSObserver {
77 public:
[email protected]446df2952012-02-28 07:22:5178 // Will be called when the DNS settings of the system may have changed.
[email protected]bb0e34542012-08-31 19:52:4079 // Use GetDnsConfig to obtain the current settings.
80 virtual void OnDNSChanged() = 0;
[email protected]46018c9d2011-09-06 03:42:3481
82 protected:
83 DNSObserver() {}
[email protected]e0845d5f2012-05-29 00:11:4184 virtual ~DNSObserver() {}
[email protected]46018c9d2011-09-06 03:42:3485
86 private:
87 DISALLOW_COPY_AND_ASSIGN(DNSObserver);
88 };
89
[email protected]03848872012-12-08 02:46:4190 class NET_EXPORT NetworkChangeObserver {
91 public:
92 // OnNetworkChanged will be called when a change occurs to the host
93 // computer's hardware or software that affects the route network packets
94 // take to any network server. Some examples:
95 // 1. A network connection becoming available or going away. For example
96 // plugging or unplugging an Ethernet cable, WiFi or cellular modem
97 // connecting or disconnecting from a network, or a VPN tunnel being
98 // established or taken down.
99 // 2. An active network connection's IP address changes.
100 // 3. A change to the local IP routing tables.
101 // The signal shall only be produced when the change is complete. For
102 // example if a new network connection has become available, only give the
103 // signal once we think the O/S has finished establishing the connection
104 // (i.e. DHCP is done) to the point where the new connection is usable.
105 // The signal shall not be produced spuriously as it will be triggering some
106 // expensive operations, like socket pools closing all connections and
107 // sockets and then re-establishing them.
108 // |type| indicates the type of the active primary network connection after
109 // the change. Observers performing "constructive" activities like trying
110 // to establish a connection to a server should only do so when
111 // |type != CONNECTION_NONE|. Observers performing "destructive" activities
112 // like resetting already established server connections should only do so
113 // when |type == CONNECTION_NONE|. OnNetworkChanged will always be called
114 // with CONNECTION_NONE immediately prior to being called with an online
115 // state; this is done to make sure that destructive actions take place
116 // prior to constructive actions.
117 virtual void OnNetworkChanged(ConnectionType type) = 0;
118
119 protected:
120 NetworkChangeObserver() {}
121 virtual ~NetworkChangeObserver() {}
122
123 private:
124 DISALLOW_COPY_AND_ASSIGN(NetworkChangeObserver);
125 };
126
[email protected]66761b952010-06-25 21:30:38127 virtual ~NetworkChangeNotifier();
[email protected]100d5fb92009-12-21 21:08:35128
[email protected]8bbc7a792012-05-24 11:30:05129 // See the description of NetworkChangeNotifier::GetConnectionType().
[email protected]2d3b7762010-10-09 00:35:47130 // Implementations must be thread-safe. Implementations must also be
[email protected]bb0e34542012-08-31 19:52:40131 // cheap as this could be called (repeatedly) from the network thread.
[email protected]8bbc7a792012-05-24 11:30:05132 virtual ConnectionType GetCurrentConnectionType() const = 0;
[email protected]2d3b7762010-10-09 00:35:47133
[email protected]373badd2011-07-11 21:55:58134 // Replaces the default class factory instance of NetworkChangeNotifier class.
135 // The method will take over the ownership of |factory| object.
136 static void SetFactory(NetworkChangeNotifierFactory* factory);
137
[email protected]66761b952010-06-25 21:30:38138 // Creates the process-wide, platform-specific NetworkChangeNotifier. The
139 // caller owns the returned pointer. You may call this on any thread. You
140 // may also avoid creating this entirely (in which case nothing will be
141 // monitored), but if you do create it, you must do so before any other
142 // threads try to access the API below, and it must outlive all other threads
143 // which might try to use it.
144 static NetworkChangeNotifier* Create();
[email protected]100d5fb92009-12-21 21:08:35145
[email protected]8bbc7a792012-05-24 11:30:05146 // Returns the connection type.
147 // A return value of |CONNECTION_NONE| is a pretty strong indicator that the
148 // user won't be able to connect to remote sites. However, another return
149 // value doesn't imply that the user will be able to connect to remote sites;
150 // even if some link is up, it is uncertain whether a particular connection
151 // attempt to a particular remote site will be successful.
[email protected]720f2afe2012-11-05 14:05:54152 // The returned value only describes the connection currently used by the
153 // device, and does not take into account other machines on the network. For
154 // example, if the device is connected using Wifi to a 3G gateway to access
155 // the internet, the connection type is CONNECTION_WIFI.
[email protected]8bbc7a792012-05-24 11:30:05156 static ConnectionType GetConnectionType();
157
[email protected]bb0e34542012-08-31 19:52:40158 // Retrieve the last read DnsConfig. This could be expensive if the system has
159 // a large HOSTS file.
160 static void GetDnsConfig(DnsConfig* config);
161
[email protected]67172802012-07-16 22:27:24162#if defined(OS_LINUX)
163 // Returns the AddressTrackerLinux if present.
164 static const internal::AddressTrackerLinux* GetAddressTracker();
165#endif
166
[email protected]8bbc7a792012-05-24 11:30:05167 // Convenience method to determine if the user is offline.
[email protected]2d3b7762010-10-09 00:35:47168 // Returns true if there is currently no internet connection.
169 //
170 // A return value of |true| is a pretty strong indicator that the user
171 // won't be able to connect to remote sites. However, a return value of
172 // |false| is inconclusive; even if some link is up, it is uncertain
173 // whether a particular connection attempt to a particular remote site
174 // will be successfully.
[email protected]720f2afe2012-11-05 14:05:54175 static bool IsOffline();
176
177 // Returns true if |type| is a cellular connection.
178 // Returns false if |type| is CONNECTION_UNKNOWN, and thus, depending on the
179 // implementation of GetConnectionType(), it is possible that
180 // IsConnectionCellular(GetConnectionType()) returns false even if the
181 // current connection is cellular.
182 static bool IsConnectionCellular(ConnectionType type);
[email protected]2d3b7762010-10-09 00:35:47183
[email protected]66761b952010-06-25 21:30:38184 // Like Create(), but for use in tests. The mock object doesn't monitor any
185 // events, it merely rebroadcasts notifications when requested.
[email protected]2d3b7762010-10-09 00:35:47186 static NetworkChangeNotifier* CreateMock();
[email protected]66761b952010-06-25 21:30:38187
188 // Registers |observer| to receive notifications of network changes. The
189 // thread on which this is called is the thread on which |observer| will be
190 // called back with notifications. This is safe to call if Create() has not
191 // been called (as long as it doesn't race the Create() call on another
192 // thread), in which case it will simply do nothing.
[email protected]232a5812011-03-04 22:42:08193 static void AddIPAddressObserver(IPAddressObserver* observer);
[email protected]8bbc7a792012-05-24 11:30:05194 static void AddConnectionTypeObserver(ConnectionTypeObserver* observer);
[email protected]46018c9d2011-09-06 03:42:34195 static void AddDNSObserver(DNSObserver* observer);
[email protected]03848872012-12-08 02:46:41196 static void AddNetworkChangeObserver(NetworkChangeObserver* observer);
[email protected]66761b952010-06-25 21:30:38197
198 // Unregisters |observer| from receiving notifications. This must be called
199 // on the same thread on which AddObserver() was called. Like AddObserver(),
200 // this is safe to call if Create() has not been called (as long as it doesn't
201 // race the Create() call on another thread), in which case it will simply do
202 // nothing. Technically, it's also safe to call after the notifier object has
203 // been destroyed, if the call doesn't race the notifier's destruction, but
204 // there's no reason to use the API in this risky way, so don't do it.
[email protected]232a5812011-03-04 22:42:08205 static void RemoveIPAddressObserver(IPAddressObserver* observer);
[email protected]8bbc7a792012-05-24 11:30:05206 static void RemoveConnectionTypeObserver(ConnectionTypeObserver* observer);
[email protected]46018c9d2011-09-06 03:42:34207 static void RemoveDNSObserver(DNSObserver* observer);
[email protected]03848872012-12-08 02:46:41208 static void RemoveNetworkChangeObserver(NetworkChangeObserver* observer);
[email protected]66761b952010-06-25 21:30:38209
[email protected]66761b952010-06-25 21:30:38210 // Allow unit tests to trigger notifications.
211 static void NotifyObserversOfIPAddressChangeForTests() {
212 NotifyObserversOfIPAddressChange();
213 }
[email protected]66761b952010-06-25 21:30:38214
[email protected]3d5aaad2012-10-27 12:31:28215 // Return a string equivalent to |type|.
216 static const char* ConnectionTypeToString(ConnectionType type);
217
[email protected]cde8b3c2012-08-13 19:20:52218 // Let the NetworkChangeNotifier know we received some data.
219 // This is used strictly for producing histogram data about the accuracy of
220 // the NetworkChangenotifier's online detection.
221 static void NotifyDataReceived(const GURL& source);
222
223 // Register the Observer callbacks for producing histogram data. This
224 // should be called from the network thread to avoid race conditions.
225 static void InitHistogramWatcher();
226
[email protected]66761b952010-06-25 21:30:38227 protected:
[email protected]03848872012-12-08 02:46:41228 // NetworkChanged signal is calculated from the IPAddressChanged and
229 // ConnectionTypeChanged signals. Delay parameters control how long to delay
230 // producing NetworkChanged signal after particular input signals so as to
231 // combine duplicates. In other words if an input signal is repeated within
232 // the corresponding delay period, only one resulting NetworkChange signal is
233 // produced.
234 struct NET_EXPORT NetworkChangeCalculatorParams {
235 NetworkChangeCalculatorParams();
236 // Controls delay after OnIPAddressChanged when transitioning from an
237 // offline state.
238 base::TimeDelta ip_address_offline_delay_;
239 // Controls delay after OnIPAddressChanged when transitioning from an
240 // online state.
241 base::TimeDelta ip_address_online_delay_;
242 // Controls delay after OnConnectionTypeChanged when transitioning from an
243 // offline state.
244 base::TimeDelta connection_type_offline_delay_;
245 // Controls delay after OnConnectionTypeChanged when transitioning from an
246 // online state.
247 base::TimeDelta connection_type_online_delay_;
248 };
249
250 explicit NetworkChangeNotifier(
251 const NetworkChangeCalculatorParams& params =
252 NetworkChangeCalculatorParams());
[email protected]66761b952010-06-25 21:30:38253
[email protected]67172802012-07-16 22:27:24254#if defined(OS_LINUX)
255 // Returns the AddressTrackerLinux if present.
[email protected]bb0e34542012-08-31 19:52:40256 // TODO(szym): Retrieve AddressMap from NetworkState. http://crbug.com/144212
[email protected]67172802012-07-16 22:27:24257 virtual const internal::AddressTrackerLinux*
258 GetAddressTrackerInternal() const;
259#endif
260
[email protected]66761b952010-06-25 21:30:38261 // Broadcasts a notification to all registered observers. Note that this
262 // happens asynchronously, even for observers on the current thread, even in
263 // tests.
264 static void NotifyObserversOfIPAddressChange();
[email protected]8bbc7a792012-05-24 11:30:05265 static void NotifyObserversOfConnectionTypeChange();
[email protected]bb0e34542012-08-31 19:52:40266 static void NotifyObserversOfDNSChange();
[email protected]03848872012-12-08 02:46:41267 static void NotifyObserversOfNetworkChange(ConnectionType type);
[email protected]bb0e34542012-08-31 19:52:40268
269 // Stores |config| in NetworkState and notifies observers.
270 static void SetDnsConfig(const DnsConfig& config);
[email protected]100d5fb92009-12-21 21:08:35271
272 private:
[email protected]bb0e34542012-08-31 19:52:40273 friend class HostResolverImplDnsTest;
[email protected]ab3309da2012-09-20 02:27:14274 friend class NetworkChangeNotifierAndroidTest;
[email protected]ae66a48d2011-11-16 22:28:06275 friend class NetworkChangeNotifierLinuxTest;
[email protected]aab66932011-10-05 17:08:13276 friend class NetworkChangeNotifierWinTest;
277
[email protected]bb0e34542012-08-31 19:52:40278 class NetworkState;
[email protected]03848872012-12-08 02:46:41279 class NetworkChangeCalculator;
[email protected]bb0e34542012-08-31 19:52:40280
[email protected]aab66932011-10-05 17:08:13281 // Allows a second NetworkChangeNotifier to be created for unit testing, so
282 // the test suite can create a MockNetworkChangeNotifier, but platform
283 // specific NetworkChangeNotifiers can also be created for testing. To use,
284 // create an DisableForTest object, and then create the new
285 // NetworkChangeNotifier object. The NetworkChangeNotifier must be
286 // destroyed before the DisableForTest object, as its destruction will restore
287 // the original NetworkChangeNotifier.
288 class NET_EXPORT_PRIVATE DisableForTest {
289 public:
290 DisableForTest();
291 ~DisableForTest();
292
293 private:
294 // The original NetworkChangeNotifier to be restored on destruction.
295 NetworkChangeNotifier* network_change_notifier_;
296 };
297
[email protected]232a5812011-03-04 22:42:08298 const scoped_refptr<ObserverListThreadSafe<IPAddressObserver> >
299 ip_address_observer_list_;
[email protected]8bbc7a792012-05-24 11:30:05300 const scoped_refptr<ObserverListThreadSafe<ConnectionTypeObserver> >
301 connection_type_observer_list_;
[email protected]46018c9d2011-09-06 03:42:34302 const scoped_refptr<ObserverListThreadSafe<DNSObserver> >
303 resolver_state_observer_list_;
[email protected]03848872012-12-08 02:46:41304 const scoped_refptr<ObserverListThreadSafe<NetworkChangeObserver> >
305 network_change_observer_list_;
[email protected]66761b952010-06-25 21:30:38306
[email protected]bb0e34542012-08-31 19:52:40307 // The current network state. Hosts DnsConfig, exposed via GetDnsConfig.
308 scoped_ptr<NetworkState> network_state_;
[email protected]05aad32d2012-05-16 18:10:53309
[email protected]cde8b3c2012-08-13 19:20:52310 // A little-piggy-back observer that simply logs UMA histogram data.
311 scoped_ptr<HistogramWatcher> histogram_watcher_;
312
[email protected]03848872012-12-08 02:46:41313 // Computes NetworkChange signal from IPAddress and ConnectionType signals.
314 scoped_ptr<NetworkChangeCalculator> network_change_calculator_;
315
[email protected]100d5fb92009-12-21 21:08:35316 DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifier);
317};
318
319} // namespace net
320
321#endif // NET_BASE_NETWORK_CHANGE_NOTIFIER_H_