[Mac] Enable MacViews bookmark editor behind --enable-mac-views-dialogs.
[chromium-blink-merge.git] / net / base / network_change_notifier.h
blobabced4859a29857b493bf52012a0041ad6c9828b
1 // Copyright (c) 2012 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_CHANGE_NOTIFIER_H_
6 #define NET_BASE_NETWORK_CHANGE_NOTIFIER_H_
8 #include <vector>
10 #include "base/basictypes.h"
11 #include "base/observer_list_threadsafe.h"
12 #include "base/time/time.h"
13 #include "net/base/net_export.h"
15 class GURL;
17 namespace net {
19 struct DnsConfig;
20 class HistogramWatcher;
21 class NetworkChangeNotifierFactory;
22 struct NetworkInterface;
23 typedef std::vector<NetworkInterface> NetworkInterfaceList;
24 class URLRequest;
26 #if defined(OS_LINUX)
27 namespace internal {
28 class AddressTrackerLinux;
30 #endif
32 // NetworkChangeNotifier monitors the system for network changes, and notifies
33 // registered observers of those events. Observers may register on any thread,
34 // and will be called back on the thread from which they registered.
35 // NetworkChangeNotifiers are threadsafe, though they must be created and
36 // destroyed on the same thread.
37 class NET_EXPORT NetworkChangeNotifier {
38 public:
39 // This is a superset of the connection types in the NetInfo v3 specification:
40 // http://w3c.github.io/netinfo/.
42 // A Java counterpart will be generated for this enum.
43 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net
45 // New enum values should only be added to the end of the enum and no values
46 // should be modified or reused, as this is reported via UMA.
47 enum ConnectionType {
48 CONNECTION_UNKNOWN = 0, // A connection exists, but its type is unknown.
49 // Also used as a default value.
50 CONNECTION_ETHERNET = 1,
51 CONNECTION_WIFI = 2,
52 CONNECTION_2G = 3,
53 CONNECTION_3G = 4,
54 CONNECTION_4G = 5,
55 CONNECTION_NONE = 6, // No connection.
56 CONNECTION_BLUETOOTH = 7,
57 CONNECTION_LAST = CONNECTION_BLUETOOTH
60 // This is the NetInfo v3 set of connection technologies as seen in
61 // http://w3c.github.io/netinfo/. This enum is copied in
62 // NetworkChangeNotifier.java so be sure to change both at once.
64 // A Java counterpart will be generated for this enum.
65 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net
66 enum ConnectionSubtype {
67 SUBTYPE_GSM = 0,
68 SUBTYPE_IDEN,
69 SUBTYPE_CDMA,
70 SUBTYPE_1XRTT,
71 SUBTYPE_GPRS,
72 SUBTYPE_EDGE,
73 SUBTYPE_UMTS,
74 SUBTYPE_EVDO_REV_0,
75 SUBTYPE_EVDO_REV_A,
76 SUBTYPE_HSPA,
77 SUBTYPE_EVDO_REV_B,
78 SUBTYPE_HSDPA,
79 SUBTYPE_HSUPA,
80 SUBTYPE_EHRPD,
81 SUBTYPE_HSPAP,
82 SUBTYPE_LTE,
83 SUBTYPE_LTE_ADVANCED,
84 SUBTYPE_BLUETOOTH_1_2,
85 SUBTYPE_BLUETOOTH_2_1,
86 SUBTYPE_BLUETOOTH_3_0,
87 SUBTYPE_BLUETOOTH_4_0,
88 SUBTYPE_ETHERNET,
89 SUBTYPE_FAST_ETHERNET,
90 SUBTYPE_GIGABIT_ETHERNET,
91 SUBTYPE_10_GIGABIT_ETHERNET,
92 SUBTYPE_WIFI_B,
93 SUBTYPE_WIFI_G,
94 SUBTYPE_WIFI_N,
95 SUBTYPE_WIFI_AC,
96 SUBTYPE_WIFI_AD,
97 SUBTYPE_UNKNOWN,
98 SUBTYPE_NONE,
99 SUBTYPE_OTHER,
100 SUBTYPE_LAST = SUBTYPE_OTHER
103 class NET_EXPORT IPAddressObserver {
104 public:
105 // Will be called when the IP address of the primary interface changes.
106 // This includes when the primary interface itself changes.
107 virtual void OnIPAddressChanged() = 0;
109 protected:
110 IPAddressObserver() {}
111 virtual ~IPAddressObserver() {}
113 private:
114 DISALLOW_COPY_AND_ASSIGN(IPAddressObserver);
117 class NET_EXPORT ConnectionTypeObserver {
118 public:
119 // Will be called when the connection type of the system has changed.
120 // See NetworkChangeNotifier::GetConnectionType() for important caveats
121 // about the unreliability of using this signal to infer the ability to
122 // reach remote sites.
123 virtual void OnConnectionTypeChanged(ConnectionType type) = 0;
125 protected:
126 ConnectionTypeObserver() {}
127 virtual ~ConnectionTypeObserver() {}
129 private:
130 DISALLOW_COPY_AND_ASSIGN(ConnectionTypeObserver);
133 class NET_EXPORT DNSObserver {
134 public:
135 // Will be called when the DNS settings of the system may have changed.
136 // Use GetDnsConfig to obtain the current settings.
137 virtual void OnDNSChanged() = 0;
138 // Will be called when DNS settings of the system have been loaded.
139 // Use GetDnsConfig to obtain the current settings.
140 virtual void OnInitialDNSConfigRead();
142 protected:
143 DNSObserver() {}
144 virtual ~DNSObserver() {}
146 private:
147 DISALLOW_COPY_AND_ASSIGN(DNSObserver);
150 class NET_EXPORT NetworkChangeObserver {
151 public:
152 // OnNetworkChanged will be called when a change occurs to the host
153 // computer's hardware or software that affects the route network packets
154 // take to any network server. Some examples:
155 // 1. A network connection becoming available or going away. For example
156 // plugging or unplugging an Ethernet cable, WiFi or cellular modem
157 // connecting or disconnecting from a network, or a VPN tunnel being
158 // established or taken down.
159 // 2. An active network connection's IP address changes.
160 // 3. A change to the local IP routing tables.
161 // The signal shall only be produced when the change is complete. For
162 // example if a new network connection has become available, only give the
163 // signal once we think the O/S has finished establishing the connection
164 // (i.e. DHCP is done) to the point where the new connection is usable.
165 // The signal shall not be produced spuriously as it will be triggering some
166 // expensive operations, like socket pools closing all connections and
167 // sockets and then re-establishing them.
168 // |type| indicates the type of the active primary network connection after
169 // the change. Observers performing "constructive" activities like trying
170 // to establish a connection to a server should only do so when
171 // |type != CONNECTION_NONE|. Observers performing "destructive" activities
172 // like resetting already established server connections should only do so
173 // when |type == CONNECTION_NONE|. OnNetworkChanged will always be called
174 // with CONNECTION_NONE immediately prior to being called with an online
175 // state; this is done to make sure that destructive actions take place
176 // prior to constructive actions.
177 virtual void OnNetworkChanged(ConnectionType type) = 0;
179 protected:
180 NetworkChangeObserver() {}
181 virtual ~NetworkChangeObserver() {}
183 private:
184 DISALLOW_COPY_AND_ASSIGN(NetworkChangeObserver);
187 class NET_EXPORT MaxBandwidthObserver {
188 public:
189 // Will be called when a change occurs to the network's maximum bandwidth as
190 // defined in http://w3c.github.io/netinfo/. Generally this will only be
191 // called on bandwidth changing network connection/disconnection events.
192 // Some platforms may call it more frequently, such as when WiFi signal
193 // strength changes.
194 // TODO(jkarlin): This is currently only implemented for Android. Implement
195 // on every platform.
196 virtual void OnMaxBandwidthChanged(double max_bandwidth_mbps) = 0;
198 protected:
199 MaxBandwidthObserver() {}
200 virtual ~MaxBandwidthObserver() {}
202 private:
203 DISALLOW_COPY_AND_ASSIGN(MaxBandwidthObserver);
206 virtual ~NetworkChangeNotifier();
208 // See the description of NetworkChangeNotifier::GetConnectionType().
209 // Implementations must be thread-safe. Implementations must also be
210 // cheap as it is called often.
211 virtual ConnectionType GetCurrentConnectionType() const = 0;
213 // Replaces the default class factory instance of NetworkChangeNotifier class.
214 // The method will take over the ownership of |factory| object.
215 static void SetFactory(NetworkChangeNotifierFactory* factory);
217 // Creates the process-wide, platform-specific NetworkChangeNotifier. The
218 // caller owns the returned pointer. You may call this on any thread. You
219 // may also avoid creating this entirely (in which case nothing will be
220 // monitored), but if you do create it, you must do so before any other
221 // threads try to access the API below, and it must outlive all other threads
222 // which might try to use it.
223 static NetworkChangeNotifier* Create();
225 // Returns the connection type.
226 // A return value of |CONNECTION_NONE| is a pretty strong indicator that the
227 // user won't be able to connect to remote sites. However, another return
228 // value doesn't imply that the user will be able to connect to remote sites;
229 // even if some link is up, it is uncertain whether a particular connection
230 // attempt to a particular remote site will be successful.
231 // The returned value only describes the connection currently used by the
232 // device, and does not take into account other machines on the network. For
233 // example, if the device is connected using Wifi to a 3G gateway to access
234 // the internet, the connection type is CONNECTION_WIFI.
235 static ConnectionType GetConnectionType();
237 // Returns a theoretical upper limit on download bandwidth, potentially based
238 // on underlying connection type, signal strength, or some other signal. The
239 // default mapping of connection type to maximum bandwidth is provided in the
240 // NetInfo spec: http://w3c.github.io/netinfo/. Host-specific application
241 // permissions may be required, please see host-specific declaration for more
242 // information.
243 static double GetMaxBandwidth();
245 // Retrieve the last read DnsConfig. This could be expensive if the system has
246 // a large HOSTS file.
247 static void GetDnsConfig(DnsConfig* config);
249 #if defined(OS_LINUX)
250 // Returns the AddressTrackerLinux if present.
251 static const internal::AddressTrackerLinux* GetAddressTracker();
252 #endif
254 // Convenience method to determine if the user is offline.
255 // Returns true if there is currently no internet connection.
257 // A return value of |true| is a pretty strong indicator that the user
258 // won't be able to connect to remote sites. However, a return value of
259 // |false| is inconclusive; even if some link is up, it is uncertain
260 // whether a particular connection attempt to a particular remote site
261 // will be successfully.
262 static bool IsOffline();
264 // Returns true if |type| is a cellular connection.
265 // Returns false if |type| is CONNECTION_UNKNOWN, and thus, depending on the
266 // implementation of GetConnectionType(), it is possible that
267 // IsConnectionCellular(GetConnectionType()) returns false even if the
268 // current connection is cellular.
269 static bool IsConnectionCellular(ConnectionType type);
271 // Gets the current connection type based on |interfaces|. Returns
272 // CONNECTION_NONE if there are no interfaces, CONNECTION_UNKNOWN if two
273 // interfaces have different connection types or the connection type of all
274 // interfaces if they have the same interface type.
275 static ConnectionType ConnectionTypeFromInterfaceList(
276 const NetworkInterfaceList& interfaces);
278 // Like Create(), but for use in tests. The mock object doesn't monitor any
279 // events, it merely rebroadcasts notifications when requested.
280 static NetworkChangeNotifier* CreateMock();
282 // Registers |observer| to receive notifications of network changes. The
283 // thread on which this is called is the thread on which |observer| will be
284 // called back with notifications. This is safe to call if Create() has not
285 // been called (as long as it doesn't race the Create() call on another
286 // thread), in which case it will simply do nothing.
287 static void AddIPAddressObserver(IPAddressObserver* observer);
288 static void AddConnectionTypeObserver(ConnectionTypeObserver* observer);
289 static void AddDNSObserver(DNSObserver* observer);
290 static void AddNetworkChangeObserver(NetworkChangeObserver* observer);
291 static void AddMaxBandwidthObserver(MaxBandwidthObserver* observer);
293 // Unregisters |observer| from receiving notifications. This must be called
294 // on the same thread on which AddObserver() was called. Like AddObserver(),
295 // this is safe to call if Create() has not been called (as long as it doesn't
296 // race the Create() call on another thread), in which case it will simply do
297 // nothing. Technically, it's also safe to call after the notifier object has
298 // been destroyed, if the call doesn't race the notifier's destruction, but
299 // there's no reason to use the API in this risky way, so don't do it.
300 static void RemoveIPAddressObserver(IPAddressObserver* observer);
301 static void RemoveConnectionTypeObserver(ConnectionTypeObserver* observer);
302 static void RemoveDNSObserver(DNSObserver* observer);
303 static void RemoveNetworkChangeObserver(NetworkChangeObserver* observer);
304 static void RemoveMaxBandwidthObserver(MaxBandwidthObserver* observer);
306 // Allow unit tests to trigger notifications.
307 static void NotifyObserversOfIPAddressChangeForTests();
308 static void NotifyObserversOfConnectionTypeChangeForTests(
309 ConnectionType type);
310 static void NotifyObserversOfNetworkChangeForTests(ConnectionType type);
311 static void NotifyObserversOfInitialDNSConfigReadForTests();
313 // Enable or disable notifications from the host. After setting to true, be
314 // sure to pump the RunLoop until idle to finish any preexisting
315 // notifications. To use this, it must must be called before a
316 // NetworkChangeNotifier is created.
317 static void SetTestNotificationsOnly(bool test_only);
319 // Return a string equivalent to |type|.
320 static const char* ConnectionTypeToString(ConnectionType type);
322 // Let the NetworkChangeNotifier know we received some data.
323 // This is used for producing histogram data about the accuracy of
324 // the NetworkChangenotifier's online detection and rough network
325 // connection measurements.
326 static void NotifyDataReceived(const URLRequest& request, int bytes_read);
328 // Register the Observer callbacks for producing histogram data. This
329 // should be called from the network thread to avoid race conditions.
330 // ShutdownHistogramWatcher() must be called prior to NetworkChangeNotifier
331 // destruction.
332 static void InitHistogramWatcher();
334 // Unregister the Observer callbacks for producing histogram data. This
335 // should be called from the network thread to avoid race conditions.
336 static void ShutdownHistogramWatcher();
338 // Log the |NCN.NetworkOperatorMCCMNC| histogram.
339 static void LogOperatorCodeHistogram(ConnectionType type);
341 // Allows a second NetworkChangeNotifier to be created for unit testing, so
342 // the test suite can create a MockNetworkChangeNotifier, but platform
343 // specific NetworkChangeNotifiers can also be created for testing. To use,
344 // create an DisableForTest object, and then create the new
345 // NetworkChangeNotifier object. The NetworkChangeNotifier must be
346 // destroyed before the DisableForTest object, as its destruction will restore
347 // the original NetworkChangeNotifier.
348 class NET_EXPORT DisableForTest {
349 public:
350 DisableForTest();
351 ~DisableForTest();
353 private:
354 // The original NetworkChangeNotifier to be restored on destruction.
355 NetworkChangeNotifier* network_change_notifier_;
358 protected:
359 // NetworkChanged signal is calculated from the IPAddressChanged and
360 // ConnectionTypeChanged signals. Delay parameters control how long to delay
361 // producing NetworkChanged signal after particular input signals so as to
362 // combine duplicates. In other words if an input signal is repeated within
363 // the corresponding delay period, only one resulting NetworkChange signal is
364 // produced.
365 struct NET_EXPORT NetworkChangeCalculatorParams {
366 NetworkChangeCalculatorParams();
367 // Controls delay after OnIPAddressChanged when transitioning from an
368 // offline state.
369 base::TimeDelta ip_address_offline_delay_;
370 // Controls delay after OnIPAddressChanged when transitioning from an
371 // online state.
372 base::TimeDelta ip_address_online_delay_;
373 // Controls delay after OnConnectionTypeChanged when transitioning from an
374 // offline state.
375 base::TimeDelta connection_type_offline_delay_;
376 // Controls delay after OnConnectionTypeChanged when transitioning from an
377 // online state.
378 base::TimeDelta connection_type_online_delay_;
381 explicit NetworkChangeNotifier(
382 const NetworkChangeCalculatorParams& params =
383 NetworkChangeCalculatorParams());
385 #if defined(OS_LINUX)
386 // Returns the AddressTrackerLinux if present.
387 // TODO(szym): Retrieve AddressMap from NetworkState. http://crbug.com/144212
388 virtual const internal::AddressTrackerLinux*
389 GetAddressTrackerInternal() const;
390 #endif
392 // See the description of NetworkChangeNotifier::GetMaxBandwidth().
393 // Implementations must be thread-safe. Implementations must also be
394 // cheap as it is called often.
395 virtual double GetCurrentMaxBandwidth() const;
397 // Returns a theoretical upper limit on download bandwidth given a connection
398 // subtype. The mapping of connection type to maximum bandwidth is provided in
399 // the NetInfo spec: http://w3c.github.io/netinfo/.
400 static double GetMaxBandwidthForConnectionSubtype(ConnectionSubtype subtype);
402 // Broadcasts a notification to all registered observers. Note that this
403 // happens asynchronously, even for observers on the current thread, even in
404 // tests.
405 static void NotifyObserversOfIPAddressChange();
406 static void NotifyObserversOfConnectionTypeChange();
407 static void NotifyObserversOfDNSChange();
408 static void NotifyObserversOfInitialDNSConfigRead();
409 static void NotifyObserversOfNetworkChange(ConnectionType type);
410 static void NotifyObserversOfMaxBandwidthChange(double max_bandwidth_mbps);
412 // Stores |config| in NetworkState and notifies OnDNSChanged observers.
413 static void SetDnsConfig(const DnsConfig& config);
414 // Stores |config| in NetworkState and notifies OnInitialDNSConfigRead
415 // observers.
416 static void SetInitialDnsConfig(const DnsConfig& config);
418 private:
419 friend class HostResolverImplDnsTest;
420 friend class NetworkChangeNotifierAndroidTest;
421 friend class NetworkChangeNotifierLinuxTest;
422 friend class NetworkChangeNotifierWinTest;
424 class NetworkState;
425 class NetworkChangeCalculator;
427 void NotifyObserversOfIPAddressChangeImpl();
428 void NotifyObserversOfConnectionTypeChangeImpl(ConnectionType type);
429 void NotifyObserversOfDNSChangeImpl();
430 void NotifyObserversOfInitialDNSConfigReadImpl();
431 void NotifyObserversOfNetworkChangeImpl(ConnectionType type);
432 void NotifyObserversOfMaxBandwidthChangeImpl(double max_bandwidth_mbps);
434 const scoped_refptr<base::ObserverListThreadSafe<IPAddressObserver>>
435 ip_address_observer_list_;
436 const scoped_refptr<base::ObserverListThreadSafe<ConnectionTypeObserver>>
437 connection_type_observer_list_;
438 const scoped_refptr<base::ObserverListThreadSafe<DNSObserver>>
439 resolver_state_observer_list_;
440 const scoped_refptr<base::ObserverListThreadSafe<NetworkChangeObserver>>
441 network_change_observer_list_;
442 const scoped_refptr<base::ObserverListThreadSafe<MaxBandwidthObserver>>
443 max_bandwidth_observer_list_;
445 // The current network state. Hosts DnsConfig, exposed via GetDnsConfig.
446 scoped_ptr<NetworkState> network_state_;
448 // A little-piggy-back observer that simply logs UMA histogram data.
449 scoped_ptr<HistogramWatcher> histogram_watcher_;
451 // Computes NetworkChange signal from IPAddress and ConnectionType signals.
452 scoped_ptr<NetworkChangeCalculator> network_change_calculator_;
454 // Set true to disable non-test notifications (to prevent flakes in tests).
455 static bool test_notifications_only_;
457 DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifier);
460 } // namespace net
462 #endif // NET_BASE_NETWORK_CHANGE_NOTIFIER_H_