Upstream version 7.36.149.0
[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   // ShutdownHistogramWatcher() must be called prior to NetworkChangeNotifier
228   // destruction.
229   static void InitHistogramWatcher();
230
231   // Unregister the Observer callbacks for producing histogram data.  This
232   // should be called from the network thread to avoid race conditions.
233   static void ShutdownHistogramWatcher();
234
235   // Log the |NCN.NetworkOperatorMCCMNC| histogram.
236   static void LogOperatorCodeHistogram(ConnectionType type);
237
238   // Allows a second NetworkChangeNotifier to be created for unit testing, so
239   // the test suite can create a MockNetworkChangeNotifier, but platform
240   // specific NetworkChangeNotifiers can also be created for testing.  To use,
241   // create an DisableForTest object, and then create the new
242   // NetworkChangeNotifier object.  The NetworkChangeNotifier must be
243   // destroyed before the DisableForTest object, as its destruction will restore
244   // the original NetworkChangeNotifier.
245   class NET_EXPORT DisableForTest {
246    public:
247     DisableForTest();
248     ~DisableForTest();
249
250    private:
251     // The original NetworkChangeNotifier to be restored on destruction.
252     NetworkChangeNotifier* network_change_notifier_;
253   };
254
255  protected:
256   // NetworkChanged signal is calculated from the IPAddressChanged and
257   // ConnectionTypeChanged signals. Delay parameters control how long to delay
258   // producing NetworkChanged signal after particular input signals so as to
259   // combine duplicates.  In other words if an input signal is repeated within
260   // the corresponding delay period, only one resulting NetworkChange signal is
261   // produced.
262   struct NET_EXPORT NetworkChangeCalculatorParams {
263     NetworkChangeCalculatorParams();
264     // Controls delay after OnIPAddressChanged when transitioning from an
265     // offline state.
266     base::TimeDelta ip_address_offline_delay_;
267     // Controls delay after OnIPAddressChanged when transitioning from an
268     // online state.
269     base::TimeDelta ip_address_online_delay_;
270     // Controls delay after OnConnectionTypeChanged when transitioning from an
271     // offline state.
272     base::TimeDelta connection_type_offline_delay_;
273     // Controls delay after OnConnectionTypeChanged when transitioning from an
274     // online state.
275     base::TimeDelta connection_type_online_delay_;
276   };
277
278   explicit NetworkChangeNotifier(
279       const NetworkChangeCalculatorParams& params =
280           NetworkChangeCalculatorParams());
281
282 #if defined(OS_LINUX)
283   // Returns the AddressTrackerLinux if present.
284   // TODO(szym): Retrieve AddressMap from NetworkState. http://crbug.com/144212
285   virtual const internal::AddressTrackerLinux*
286       GetAddressTrackerInternal() const;
287 #endif
288
289   // Broadcasts a notification to all registered observers.  Note that this
290   // happens asynchronously, even for observers on the current thread, even in
291   // tests.
292   static void NotifyObserversOfIPAddressChange();
293   static void NotifyObserversOfConnectionTypeChange();
294   static void NotifyObserversOfDNSChange();
295   static void NotifyObserversOfNetworkChange(ConnectionType type);
296
297   // Stores |config| in NetworkState and notifies observers.
298   static void SetDnsConfig(const DnsConfig& config);
299
300  private:
301   friend class HostResolverImplDnsTest;
302   friend class NetworkChangeNotifierAndroidTest;
303   friend class NetworkChangeNotifierLinuxTest;
304   friend class NetworkChangeNotifierWinTest;
305
306   class NetworkState;
307   class NetworkChangeCalculator;
308
309   const scoped_refptr<ObserverListThreadSafe<IPAddressObserver> >
310       ip_address_observer_list_;
311   const scoped_refptr<ObserverListThreadSafe<ConnectionTypeObserver> >
312       connection_type_observer_list_;
313   const scoped_refptr<ObserverListThreadSafe<DNSObserver> >
314       resolver_state_observer_list_;
315   const scoped_refptr<ObserverListThreadSafe<NetworkChangeObserver> >
316       network_change_observer_list_;
317
318   // The current network state. Hosts DnsConfig, exposed via GetDnsConfig.
319   scoped_ptr<NetworkState> network_state_;
320
321   // A little-piggy-back observer that simply logs UMA histogram data.
322   scoped_ptr<HistogramWatcher> histogram_watcher_;
323
324   // Computes NetworkChange signal from IPAddress and ConnectionType signals.
325   scoped_ptr<NetworkChangeCalculator> network_change_calculator_;
326
327   DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifier);
328 };
329
330 }  // namespace net
331
332 #endif  // NET_BASE_NETWORK_CHANGE_NOTIFIER_H_