- add sources.
[platform/framework/web/crosswalk.git] / src / net / base / network_change_notifier.h
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.
4
5 #ifndef NET_BASE_NETWORK_CHANGE_NOTIFIER_H_
6 #define NET_BASE_NETWORK_CHANGE_NOTIFIER_H_
7
8 #include "base/basictypes.h"
9 #include "base/observer_list_threadsafe.h"
10 #include "base/time/time.h"
11 #include "net/base/net_export.h"
12
13 class GURL;
14
15 namespace net {
16
17 struct DnsConfig;
18 class HistogramWatcher;
19 class NetworkChangeNotifierFactory;
20 class URLRequest;
21
22 #if defined(OS_LINUX)
23 namespace internal {
24 class AddressTrackerLinux;
25 }
26 #endif
27
28 // NetworkChangeNotifier monitors the system for network changes, and notifies
29 // registered observers of those events.  Observers may register on any thread,
30 // and will be called back on the thread from which they registered.
31 // NetworkChangeNotifiers are threadsafe, though they must be created and
32 // destroyed on the same thread.
33 class NET_EXPORT NetworkChangeNotifier {
34  public:
35   // Using the terminology of the Network Information API:
36   // http://www.w3.org/TR/netinfo-api.
37   enum ConnectionType {
38     CONNECTION_UNKNOWN = 0, // A connection exists, but its type is unknown.
39     CONNECTION_ETHERNET = 1,
40     CONNECTION_WIFI = 2,
41     CONNECTION_2G = 3,
42     CONNECTION_3G = 4,
43     CONNECTION_4G = 5,
44     CONNECTION_NONE = 6     // No connection.
45   };
46
47   class NET_EXPORT IPAddressObserver {
48    public:
49     // Will be called when the IP address of the primary interface changes.
50     // This includes when the primary interface itself changes.
51     virtual void OnIPAddressChanged() = 0;
52
53    protected:
54     IPAddressObserver() {}
55     virtual ~IPAddressObserver() {}
56
57    private:
58     DISALLOW_COPY_AND_ASSIGN(IPAddressObserver);
59   };
60
61   class NET_EXPORT ConnectionTypeObserver {
62    public:
63     // Will be called when the connection type of the system has changed.
64     // See NetworkChangeNotifier::GetConnectionType() for important caveats
65     // about the unreliability of using this signal to infer the ability to
66     // reach remote sites.
67     virtual void OnConnectionTypeChanged(ConnectionType type) = 0;
68
69    protected:
70     ConnectionTypeObserver() {}
71     virtual ~ConnectionTypeObserver() {}
72
73    private:
74     DISALLOW_COPY_AND_ASSIGN(ConnectionTypeObserver);
75   };
76
77   class NET_EXPORT DNSObserver {
78    public:
79     // Will be called when the DNS settings of the system may have changed.
80     // Use GetDnsConfig to obtain the current settings.
81     virtual void OnDNSChanged() = 0;
82
83    protected:
84     DNSObserver() {}
85     virtual ~DNSObserver() {}
86
87    private:
88     DISALLOW_COPY_AND_ASSIGN(DNSObserver);
89   };
90
91   class NET_EXPORT NetworkChangeObserver {
92    public:
93     // OnNetworkChanged will be called when a change occurs to the host
94     // computer's hardware or software that affects the route network packets
95     // take to any network server. Some examples:
96     //   1. A network connection becoming available or going away. For example
97     //      plugging or unplugging an Ethernet cable, WiFi or cellular modem
98     //      connecting or disconnecting from a network, or a VPN tunnel being
99     //      established or taken down.
100     //   2. An active network connection's IP address changes.
101     //   3. A change to the local IP routing tables.
102     // The signal shall only be produced when the change is complete.  For
103     // example if a new network connection has become available, only give the
104     // signal once we think the O/S has finished establishing the connection
105     // (i.e. DHCP is done) to the point where the new connection is usable.
106     // The signal shall not be produced spuriously as it will be triggering some
107     // expensive operations, like socket pools closing all connections and
108     // sockets and then re-establishing them.
109     // |type| indicates the type of the active primary network connection after
110     // the change.  Observers performing "constructive" activities like trying
111     // to establish a connection to a server should only do so when
112     // |type != CONNECTION_NONE|.  Observers performing "destructive" activities
113     // like resetting already established server connections should only do so
114     // when |type == CONNECTION_NONE|.  OnNetworkChanged will always be called
115     // with CONNECTION_NONE immediately prior to being called with an online
116     // state; this is done to make sure that destructive actions take place
117     // prior to constructive actions.
118     virtual void OnNetworkChanged(ConnectionType type) = 0;
119
120    protected:
121     NetworkChangeObserver() {}
122     virtual ~NetworkChangeObserver() {}
123
124    private:
125     DISALLOW_COPY_AND_ASSIGN(NetworkChangeObserver);
126   };
127
128   virtual ~NetworkChangeNotifier();
129
130   // See the description of NetworkChangeNotifier::GetConnectionType().
131   // Implementations must be thread-safe. Implementations must also be
132   // cheap as this could be called (repeatedly) from the network thread.
133   virtual ConnectionType GetCurrentConnectionType() const = 0;
134
135   // Replaces the default class factory instance of NetworkChangeNotifier class.
136   // The method will take over the ownership of |factory| object.
137   static void SetFactory(NetworkChangeNotifierFactory* factory);
138
139   // Creates the process-wide, platform-specific NetworkChangeNotifier.  The
140   // caller owns the returned pointer.  You may call this on any thread.  You
141   // may also avoid creating this entirely (in which case nothing will be
142   // monitored), but if you do create it, you must do so before any other
143   // threads try to access the API below, and it must outlive all other threads
144   // which might try to use it.
145   static NetworkChangeNotifier* Create();
146
147   // Returns the connection type.
148   // A return value of |CONNECTION_NONE| is a pretty strong indicator that the
149   // user won't be able to connect to remote sites. However, another return
150   // value doesn't imply that the user will be able to connect to remote sites;
151   // even if some link is up, it is uncertain whether a particular connection
152   // attempt to a particular remote site will be successful.
153   // The returned value only describes the connection currently used by the
154   // device, and does not take into account other machines on the network. For
155   // example, if the device is connected using Wifi to a 3G gateway to access
156   // the internet, the connection type is CONNECTION_WIFI.
157   static ConnectionType GetConnectionType();
158
159   // Retrieve the last read DnsConfig. This could be expensive if the system has
160   // a large HOSTS file.
161   static void GetDnsConfig(DnsConfig* config);
162
163 #if defined(OS_LINUX)
164   // Returns the AddressTrackerLinux if present.
165   static const internal::AddressTrackerLinux* GetAddressTracker();
166 #endif
167
168   // Convenience method to determine if the user is offline.
169   // Returns true if there is currently no internet connection.
170   //
171   // A return value of |true| is a pretty strong indicator that the user
172   // won't be able to connect to remote sites. However, a return value of
173   // |false| is inconclusive; even if some link is up, it is uncertain
174   // whether a particular connection attempt to a particular remote site
175   // will be successfully.
176   static bool IsOffline();
177
178   // Returns true if |type| is a cellular connection.
179   // Returns false if |type| is CONNECTION_UNKNOWN, and thus, depending on the
180   // implementation of GetConnectionType(), it is possible that
181   // IsConnectionCellular(GetConnectionType()) returns false even if the
182   // current connection is cellular.
183   static bool IsConnectionCellular(ConnectionType type);
184
185   // Like Create(), but for use in tests.  The mock object doesn't monitor any
186   // events, it merely rebroadcasts notifications when requested.
187   static NetworkChangeNotifier* CreateMock();
188
189   // Registers |observer| to receive notifications of network changes.  The
190   // thread on which this is called is the thread on which |observer| will be
191   // called back with notifications.  This is safe to call if Create() has not
192   // been called (as long as it doesn't race the Create() call on another
193   // thread), in which case it will simply do nothing.
194   static void AddIPAddressObserver(IPAddressObserver* observer);
195   static void AddConnectionTypeObserver(ConnectionTypeObserver* observer);
196   static void AddDNSObserver(DNSObserver* observer);
197   static void AddNetworkChangeObserver(NetworkChangeObserver* observer);
198
199   // Unregisters |observer| from receiving notifications.  This must be called
200   // on the same thread on which AddObserver() was called.  Like AddObserver(),
201   // this is safe to call if Create() has not been called (as long as it doesn't
202   // race the Create() call on another thread), in which case it will simply do
203   // nothing.  Technically, it's also safe to call after the notifier object has
204   // been destroyed, if the call doesn't race the notifier's destruction, but
205   // there's no reason to use the API in this risky way, so don't do it.
206   static void RemoveIPAddressObserver(IPAddressObserver* observer);
207   static void RemoveConnectionTypeObserver(ConnectionTypeObserver* observer);
208   static void RemoveDNSObserver(DNSObserver* observer);
209   static void RemoveNetworkChangeObserver(NetworkChangeObserver* observer);
210
211   // Allow unit tests to trigger notifications.
212   static void NotifyObserversOfIPAddressChangeForTests() {
213     NotifyObserversOfIPAddressChange();
214   }
215
216   // Return a string equivalent to |type|.
217   static const char* ConnectionTypeToString(ConnectionType type);
218
219   // Let the NetworkChangeNotifier know we received some data.
220   // This is used for producing histogram data about the accuracy of
221   // the NetworkChangenotifier's online detection and rough network
222   // connection measurements.
223   static void NotifyDataReceived(const URLRequest& request, int bytes_read);
224
225   // Register the Observer callbacks for producing histogram data.  This
226   // should be called from the network thread to avoid race conditions.
227   static void InitHistogramWatcher();
228
229   // Allows a second NetworkChangeNotifier to be created for unit testing, so
230   // the test suite can create a MockNetworkChangeNotifier, but platform
231   // specific NetworkChangeNotifiers can also be created for testing.  To use,
232   // create an DisableForTest object, and then create the new
233   // NetworkChangeNotifier object.  The NetworkChangeNotifier must be
234   // destroyed before the DisableForTest object, as its destruction will restore
235   // the original NetworkChangeNotifier.
236   class NET_EXPORT DisableForTest {
237    public:
238     DisableForTest();
239     ~DisableForTest();
240
241    private:
242     // The original NetworkChangeNotifier to be restored on destruction.
243     NetworkChangeNotifier* network_change_notifier_;
244   };
245
246  protected:
247   // NetworkChanged signal is calculated from the IPAddressChanged and
248   // ConnectionTypeChanged signals. Delay parameters control how long to delay
249   // producing NetworkChanged signal after particular input signals so as to
250   // combine duplicates.  In other words if an input signal is repeated within
251   // the corresponding delay period, only one resulting NetworkChange signal is
252   // produced.
253   struct NET_EXPORT NetworkChangeCalculatorParams {
254     NetworkChangeCalculatorParams();
255     // Controls delay after OnIPAddressChanged when transitioning from an
256     // offline state.
257     base::TimeDelta ip_address_offline_delay_;
258     // Controls delay after OnIPAddressChanged when transitioning from an
259     // online state.
260     base::TimeDelta ip_address_online_delay_;
261     // Controls delay after OnConnectionTypeChanged when transitioning from an
262     // offline state.
263     base::TimeDelta connection_type_offline_delay_;
264     // Controls delay after OnConnectionTypeChanged when transitioning from an
265     // online state.
266     base::TimeDelta connection_type_online_delay_;
267   };
268
269   explicit NetworkChangeNotifier(
270       const NetworkChangeCalculatorParams& params =
271           NetworkChangeCalculatorParams());
272
273 #if defined(OS_LINUX)
274   // Returns the AddressTrackerLinux if present.
275   // TODO(szym): Retrieve AddressMap from NetworkState. http://crbug.com/144212
276   virtual const internal::AddressTrackerLinux*
277       GetAddressTrackerInternal() const;
278 #endif
279
280   // Broadcasts a notification to all registered observers.  Note that this
281   // happens asynchronously, even for observers on the current thread, even in
282   // tests.
283   static void NotifyObserversOfIPAddressChange();
284   static void NotifyObserversOfConnectionTypeChange();
285   static void NotifyObserversOfDNSChange();
286   static void NotifyObserversOfNetworkChange(ConnectionType type);
287
288   // Stores |config| in NetworkState and notifies observers.
289   static void SetDnsConfig(const DnsConfig& config);
290
291  private:
292   friend class HostResolverImplDnsTest;
293   friend class NetworkChangeNotifierAndroidTest;
294   friend class NetworkChangeNotifierLinuxTest;
295   friend class NetworkChangeNotifierWinTest;
296
297   class NetworkState;
298   class NetworkChangeCalculator;
299
300   const scoped_refptr<ObserverListThreadSafe<IPAddressObserver> >
301       ip_address_observer_list_;
302   const scoped_refptr<ObserverListThreadSafe<ConnectionTypeObserver> >
303       connection_type_observer_list_;
304   const scoped_refptr<ObserverListThreadSafe<DNSObserver> >
305       resolver_state_observer_list_;
306   const scoped_refptr<ObserverListThreadSafe<NetworkChangeObserver> >
307       network_change_observer_list_;
308
309   // The current network state. Hosts DnsConfig, exposed via GetDnsConfig.
310   scoped_ptr<NetworkState> network_state_;
311
312   // A little-piggy-back observer that simply logs UMA histogram data.
313   scoped_ptr<HistogramWatcher> histogram_watcher_;
314
315   // Computes NetworkChange signal from IPAddress and ConnectionType signals.
316   scoped_ptr<NetworkChangeCalculator> network_change_calculator_;
317
318   DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifier);
319 };
320
321 }  // namespace net
322
323 #endif  // NET_BASE_NETWORK_CHANGE_NOTIFIER_H_