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