• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2010 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 #pragma once
8 
9 #include "base/basictypes.h"
10 #include "base/observer_list_threadsafe.h"
11 #include "net/base/net_export.h"
12 
13 namespace net {
14 
15 // NetworkChangeNotifier monitors the system for network changes, and notifies
16 // registered observers of those events.  Observers may register on any thread,
17 // and will be called back on the thread from which they registered.
18 class NET_EXPORT NetworkChangeNotifier {
19  public:
20   class NET_EXPORT IPAddressObserver {
21    public:
~IPAddressObserver()22     virtual ~IPAddressObserver() {}
23 
24     // Will be called when the IP address of the primary interface changes.
25     // This includes when the primary interface itself changes.
26     virtual void OnIPAddressChanged() = 0;
27 
28    protected:
IPAddressObserver()29     IPAddressObserver() {}
30 
31    private:
32     DISALLOW_COPY_AND_ASSIGN(IPAddressObserver);
33   };
34 
35   class NET_EXPORT OnlineStateObserver {
36    public:
~OnlineStateObserver()37     virtual ~OnlineStateObserver() {}
38 
39     // Will be called when the online state of the system may have changed.
40     // See NetworkChangeNotifier::IsOffline() for important caveats about
41     // the unreliability of this signal.
42     virtual void OnOnlineStateChanged(bool online) = 0;
43 
44    protected:
OnlineStateObserver()45     OnlineStateObserver() {}
46 
47    private:
48     DISALLOW_COPY_AND_ASSIGN(OnlineStateObserver);
49   };
50 
51   virtual ~NetworkChangeNotifier();
52 
53   // See the description of NetworkChangeNotifier::IsOffline().
54   // Implementations must be thread-safe. Implementations must also be
55   // cheap as this could be called (repeatedly) from the IO thread.
56   virtual bool IsCurrentlyOffline() const = 0;
57 
58   // Creates the process-wide, platform-specific NetworkChangeNotifier.  The
59   // caller owns the returned pointer.  You may call this on any thread.  You
60   // may also avoid creating this entirely (in which case nothing will be
61   // monitored), but if you do create it, you must do so before any other
62   // threads try to access the API below, and it must outlive all other threads
63   // which might try to use it.
64   static NetworkChangeNotifier* Create();
65 
66   // Returns true if there is currently no internet connection.
67   //
68   // A return value of |true| is a pretty strong indicator that the user
69   // won't be able to connect to remote sites. However, a return value of
70   // |false| is inconclusive; even if some link is up, it is uncertain
71   // whether a particular connection attempt to a particular remote site
72   // will be successfully.
73   static bool IsOffline();
74 
75   // Like Create(), but for use in tests.  The mock object doesn't monitor any
76   // events, it merely rebroadcasts notifications when requested.
77   static NetworkChangeNotifier* CreateMock();
78 
79   // Registers |observer| to receive notifications of network changes.  The
80   // thread on which this is called is the thread on which |observer| will be
81   // called back with notifications.  This is safe to call if Create() has not
82   // been called (as long as it doesn't race the Create() call on another
83   // thread), in which case it will simply do nothing.
84   static void AddIPAddressObserver(IPAddressObserver* observer);
85   static void AddOnlineStateObserver(OnlineStateObserver* observer);
86 
87   // Unregisters |observer| from receiving notifications.  This must be called
88   // on the same thread on which AddObserver() was called.  Like AddObserver(),
89   // this is safe to call if Create() has not been called (as long as it doesn't
90   // race the Create() call on another thread), in which case it will simply do
91   // nothing.  Technically, it's also safe to call after the notifier object has
92   // been destroyed, if the call doesn't race the notifier's destruction, but
93   // there's no reason to use the API in this risky way, so don't do it.
94   static void RemoveIPAddressObserver(IPAddressObserver* observer);
95   static void RemoveOnlineStateObserver(OnlineStateObserver* observer);
96 
97 #ifdef UNIT_TEST
98   // Allow unit tests to trigger notifications.
NotifyObserversOfIPAddressChangeForTests()99   static void NotifyObserversOfIPAddressChangeForTests() {
100     NotifyObserversOfIPAddressChange();
101   }
102 #endif
103 
104  protected:
105   NetworkChangeNotifier();
106 
107   // Broadcasts a notification to all registered observers.  Note that this
108   // happens asynchronously, even for observers on the current thread, even in
109   // tests.
110   static void NotifyObserversOfIPAddressChange();
111   void NotifyObserversOfOnlineStateChange();
112 
113  private:
114   const scoped_refptr<ObserverListThreadSafe<IPAddressObserver> >
115       ip_address_observer_list_;
116   const scoped_refptr<ObserverListThreadSafe<OnlineStateObserver> >
117       online_state_observer_list_;
118 
119   DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifier);
120 };
121 
122 }  // namespace net
123 
124 #endif  // NET_BASE_NETWORK_CHANGE_NOTIFIER_H_
125