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