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: 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: 28 IPAddressObserver() {} 29 30 private: 31 DISALLOW_COPY_AND_ASSIGN(IPAddressObserver); 32 }; 33 34 class OnlineStateObserver { 35 public: 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: 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. 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