| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef NET_BASE_NETWORK_CHANGE_NOTIFIER_H_ | 5 #ifndef NET_BASE_NETWORK_CHANGE_NOTIFIER_H_ |
| 6 #define NET_BASE_NETWORK_CHANGE_NOTIFIER_H_ | 6 #define NET_BASE_NETWORK_CHANGE_NOTIFIER_H_ |
| 7 | 7 |
| 8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
| 9 #include "base/observer_list_threadsafe.h" | 9 #include "base/observer_list_threadsafe.h" |
| 10 #include "base/synchronization/lock.h" | |
| 11 #include "net/base/net_export.h" | 10 #include "net/base/net_export.h" |
| 12 | 11 |
| 13 class GURL; | 12 class GURL; |
| 14 | 13 |
| 15 namespace net { | 14 namespace net { |
| 16 | 15 |
| 16 struct DnsConfig; |
| 17 class HistogramWatcher; | 17 class HistogramWatcher; |
| 18 class NetworkChangeNotifierFactory; | 18 class NetworkChangeNotifierFactory; |
| 19 | 19 |
| 20 #if defined(OS_LINUX) |
| 20 namespace internal { | 21 namespace internal { |
| 21 class DnsConfigWatcher; | |
| 22 | |
| 23 #if defined(OS_LINUX) | |
| 24 class AddressTrackerLinux; | 22 class AddressTrackerLinux; |
| 23 } |
| 25 #endif | 24 #endif |
| 26 } | |
| 27 | 25 |
| 28 // NetworkChangeNotifier monitors the system for network changes, and notifies | 26 // NetworkChangeNotifier monitors the system for network changes, and notifies |
| 29 // registered observers of those events. Observers may register on any thread, | 27 // registered observers of those events. Observers may register on any thread, |
| 30 // and will be called back on the thread from which they registered. | 28 // and will be called back on the thread from which they registered. |
| 31 // NetworkChangeNotifiers are threadsafe, though they must be created and | 29 // NetworkChangeNotifiers are threadsafe, though they must be created and |
| 32 // destroyed on the same thread. | 30 // destroyed on the same thread. |
| 33 class NET_EXPORT NetworkChangeNotifier { | 31 class NET_EXPORT NetworkChangeNotifier { |
| 34 public: | 32 public: |
| 35 // Flags which are ORed together to form |detail| in OnDNSChanged. | |
| 36 // | |
| 37 // TODO(akalin): Name this enum type and use it instead of plain | |
| 38 // 'unsigned' in OnDNSChanged. ORing together enum values always | |
| 39 // results in a valid enum value by the C++ standard. | |
| 40 enum { | |
| 41 // The DNS configuration (name servers, suffix search) has changed. | |
| 42 CHANGE_DNS_SETTINGS = 1 << 0, | |
| 43 // The HOSTS file has changed. | |
| 44 CHANGE_DNS_HOSTS = 1 << 1, | |
| 45 // The watcher has started. | |
| 46 CHANGE_DNS_WATCH_STARTED = 1 << 2, | |
| 47 // The watcher has failed and will not be available until further notice. | |
| 48 CHANGE_DNS_WATCH_FAILED = 1 << 3, | |
| 49 }; | |
| 50 | |
| 51 // Using the terminology of the Network Information API: | 33 // Using the terminology of the Network Information API: |
| 52 // http://www.w3.org/TR/netinfo-api. | 34 // http://www.w3.org/TR/netinfo-api. |
| 53 enum ConnectionType { | 35 enum ConnectionType { |
| 54 CONNECTION_UNKNOWN, // A connection exists, but its type is unknown. | 36 CONNECTION_UNKNOWN, // A connection exists, but its type is unknown. |
| 55 CONNECTION_ETHERNET, | 37 CONNECTION_ETHERNET, |
| 56 CONNECTION_WIFI, | 38 CONNECTION_WIFI, |
| 57 CONNECTION_2G, | 39 CONNECTION_2G, |
| 58 CONNECTION_3G, | 40 CONNECTION_3G, |
| 59 CONNECTION_4G, | 41 CONNECTION_4G, |
| 60 CONNECTION_NONE // No connection. | 42 CONNECTION_NONE // No connection. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 86 ConnectionTypeObserver() {} | 68 ConnectionTypeObserver() {} |
| 87 virtual ~ConnectionTypeObserver() {} | 69 virtual ~ConnectionTypeObserver() {} |
| 88 | 70 |
| 89 private: | 71 private: |
| 90 DISALLOW_COPY_AND_ASSIGN(ConnectionTypeObserver); | 72 DISALLOW_COPY_AND_ASSIGN(ConnectionTypeObserver); |
| 91 }; | 73 }; |
| 92 | 74 |
| 93 class NET_EXPORT DNSObserver { | 75 class NET_EXPORT DNSObserver { |
| 94 public: | 76 public: |
| 95 // Will be called when the DNS settings of the system may have changed. | 77 // Will be called when the DNS settings of the system may have changed. |
| 96 // The flags set in |detail| provide the specific set of changes. | 78 // Use GetDnsConfig to obtain the current settings. |
| 97 virtual void OnDNSChanged(unsigned detail) = 0; | 79 virtual void OnDNSChanged() = 0; |
| 98 | 80 |
| 99 protected: | 81 protected: |
| 100 DNSObserver() {} | 82 DNSObserver() {} |
| 101 virtual ~DNSObserver() {} | 83 virtual ~DNSObserver() {} |
| 102 | 84 |
| 103 private: | 85 private: |
| 104 DISALLOW_COPY_AND_ASSIGN(DNSObserver); | 86 DISALLOW_COPY_AND_ASSIGN(DNSObserver); |
| 105 }; | 87 }; |
| 106 | 88 |
| 107 virtual ~NetworkChangeNotifier(); | 89 virtual ~NetworkChangeNotifier(); |
| 108 | 90 |
| 109 // See the description of NetworkChangeNotifier::GetConnectionType(). | 91 // See the description of NetworkChangeNotifier::GetConnectionType(). |
| 110 // Implementations must be thread-safe. Implementations must also be | 92 // Implementations must be thread-safe. Implementations must also be |
| 111 // cheap as this could be called (repeatedly) from the IO thread. | 93 // cheap as this could be called (repeatedly) from the network thread. |
| 112 virtual ConnectionType GetCurrentConnectionType() const = 0; | 94 virtual ConnectionType GetCurrentConnectionType() const = 0; |
| 113 | 95 |
| 114 // Replaces the default class factory instance of NetworkChangeNotifier class. | 96 // Replaces the default class factory instance of NetworkChangeNotifier class. |
| 115 // The method will take over the ownership of |factory| object. | 97 // The method will take over the ownership of |factory| object. |
| 116 static void SetFactory(NetworkChangeNotifierFactory* factory); | 98 static void SetFactory(NetworkChangeNotifierFactory* factory); |
| 117 | 99 |
| 118 // Creates the process-wide, platform-specific NetworkChangeNotifier. The | 100 // Creates the process-wide, platform-specific NetworkChangeNotifier. The |
| 119 // caller owns the returned pointer. You may call this on any thread. You | 101 // caller owns the returned pointer. You may call this on any thread. You |
| 120 // may also avoid creating this entirely (in which case nothing will be | 102 // may also avoid creating this entirely (in which case nothing will be |
| 121 // monitored), but if you do create it, you must do so before any other | 103 // monitored), but if you do create it, you must do so before any other |
| 122 // threads try to access the API below, and it must outlive all other threads | 104 // threads try to access the API below, and it must outlive all other threads |
| 123 // which might try to use it. | 105 // which might try to use it. |
| 124 static NetworkChangeNotifier* Create(); | 106 static NetworkChangeNotifier* Create(); |
| 125 | 107 |
| 126 // Returns the connection type. | 108 // Returns the connection type. |
| 127 // A return value of |CONNECTION_NONE| is a pretty strong indicator that the | 109 // A return value of |CONNECTION_NONE| is a pretty strong indicator that the |
| 128 // user won't be able to connect to remote sites. However, another return | 110 // user won't be able to connect to remote sites. However, another return |
| 129 // value doesn't imply that the user will be able to connect to remote sites; | 111 // value doesn't imply that the user will be able to connect to remote sites; |
| 130 // even if some link is up, it is uncertain whether a particular connection | 112 // even if some link is up, it is uncertain whether a particular connection |
| 131 // attempt to a particular remote site will be successful. | 113 // attempt to a particular remote site will be successful. |
| 132 static ConnectionType GetConnectionType(); | 114 static ConnectionType GetConnectionType(); |
| 133 | 115 |
| 116 // Retrieve the last read DnsConfig. This could be expensive if the system has |
| 117 // a large HOSTS file. |
| 118 static void GetDnsConfig(DnsConfig* config); |
| 119 |
| 134 #if defined(OS_LINUX) | 120 #if defined(OS_LINUX) |
| 135 // Returns the AddressTrackerLinux if present. | 121 // Returns the AddressTrackerLinux if present. |
| 136 static const internal::AddressTrackerLinux* GetAddressTracker(); | 122 static const internal::AddressTrackerLinux* GetAddressTracker(); |
| 137 #endif | 123 #endif |
| 138 | 124 |
| 139 // Convenience method to determine if the user is offline. | 125 // Convenience method to determine if the user is offline. |
| 140 // Returns true if there is currently no internet connection. | 126 // Returns true if there is currently no internet connection. |
| 141 // | 127 // |
| 142 // A return value of |true| is a pretty strong indicator that the user | 128 // A return value of |true| is a pretty strong indicator that the user |
| 143 // won't be able to connect to remote sites. However, a return value of | 129 // won't be able to connect to remote sites. However, a return value of |
| 144 // |false| is inconclusive; even if some link is up, it is uncertain | 130 // |false| is inconclusive; even if some link is up, it is uncertain |
| 145 // whether a particular connection attempt to a particular remote site | 131 // whether a particular connection attempt to a particular remote site |
| 146 // will be successfully. | 132 // will be successfully. |
| 147 static bool IsOffline() { | 133 static bool IsOffline() { |
| 148 return GetConnectionType() == CONNECTION_NONE; | 134 return GetConnectionType() == CONNECTION_NONE; |
| 149 } | 135 } |
| 150 | 136 |
| 151 // Returns true if DNS watcher is operational. | |
| 152 static bool IsWatchingDNS(); | |
| 153 | |
| 154 // Like Create(), but for use in tests. The mock object doesn't monitor any | 137 // Like Create(), but for use in tests. The mock object doesn't monitor any |
| 155 // events, it merely rebroadcasts notifications when requested. | 138 // events, it merely rebroadcasts notifications when requested. |
| 156 static NetworkChangeNotifier* CreateMock(); | 139 static NetworkChangeNotifier* CreateMock(); |
| 157 | 140 |
| 158 // Registers |observer| to receive notifications of network changes. The | 141 // Registers |observer| to receive notifications of network changes. The |
| 159 // thread on which this is called is the thread on which |observer| will be | 142 // thread on which this is called is the thread on which |observer| will be |
| 160 // called back with notifications. This is safe to call if Create() has not | 143 // called back with notifications. This is safe to call if Create() has not |
| 161 // been called (as long as it doesn't race the Create() call on another | 144 // been called (as long as it doesn't race the Create() call on another |
| 162 // thread), in which case it will simply do nothing. | 145 // thread), in which case it will simply do nothing. |
| 163 static void AddIPAddressObserver(IPAddressObserver* observer); | 146 static void AddIPAddressObserver(IPAddressObserver* observer); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 183 // Let the NetworkChangeNotifier know we received some data. | 166 // Let the NetworkChangeNotifier know we received some data. |
| 184 // This is used strictly for producing histogram data about the accuracy of | 167 // This is used strictly for producing histogram data about the accuracy of |
| 185 // the NetworkChangenotifier's online detection. | 168 // the NetworkChangenotifier's online detection. |
| 186 static void NotifyDataReceived(const GURL& source); | 169 static void NotifyDataReceived(const GURL& source); |
| 187 | 170 |
| 188 // Register the Observer callbacks for producing histogram data. This | 171 // Register the Observer callbacks for producing histogram data. This |
| 189 // should be called from the network thread to avoid race conditions. | 172 // should be called from the network thread to avoid race conditions. |
| 190 static void InitHistogramWatcher(); | 173 static void InitHistogramWatcher(); |
| 191 | 174 |
| 192 protected: | 175 protected: |
| 193 friend class internal::DnsConfigWatcher; | |
| 194 | |
| 195 NetworkChangeNotifier(); | 176 NetworkChangeNotifier(); |
| 196 | 177 |
| 197 #if defined(OS_LINUX) | 178 #if defined(OS_LINUX) |
| 198 // Returns the AddressTrackerLinux if present. | 179 // Returns the AddressTrackerLinux if present. |
| 180 // TODO(szym): Retrieve AddressMap from NetworkState. http://crbug.com/144212 |
| 199 virtual const internal::AddressTrackerLinux* | 181 virtual const internal::AddressTrackerLinux* |
| 200 GetAddressTrackerInternal() const; | 182 GetAddressTrackerInternal() const; |
| 201 #endif | 183 #endif |
| 202 | 184 |
| 203 // Broadcasts a notification to all registered observers. Note that this | 185 // Broadcasts a notification to all registered observers. Note that this |
| 204 // happens asynchronously, even for observers on the current thread, even in | 186 // happens asynchronously, even for observers on the current thread, even in |
| 205 // tests. | 187 // tests. |
| 206 static void NotifyObserversOfIPAddressChange(); | 188 static void NotifyObserversOfIPAddressChange(); |
| 207 static void NotifyObserversOfConnectionTypeChange(); | 189 static void NotifyObserversOfConnectionTypeChange(); |
| 208 static void NotifyObserversOfDNSChange(unsigned detail); | 190 static void NotifyObserversOfDNSChange(); |
| 191 |
| 192 // Stores |config| in NetworkState and notifies observers. |
| 193 static void SetDnsConfig(const DnsConfig& config); |
| 209 | 194 |
| 210 private: | 195 private: |
| 196 friend class HostResolverImplDnsTest; |
| 211 friend class NetworkChangeNotifierLinuxTest; | 197 friend class NetworkChangeNotifierLinuxTest; |
| 212 friend class NetworkChangeNotifierWinTest; | 198 friend class NetworkChangeNotifierWinTest; |
| 213 | 199 |
| 200 class NetworkState; |
| 201 |
| 214 // Allows a second NetworkChangeNotifier to be created for unit testing, so | 202 // Allows a second NetworkChangeNotifier to be created for unit testing, so |
| 215 // the test suite can create a MockNetworkChangeNotifier, but platform | 203 // the test suite can create a MockNetworkChangeNotifier, but platform |
| 216 // specific NetworkChangeNotifiers can also be created for testing. To use, | 204 // specific NetworkChangeNotifiers can also be created for testing. To use, |
| 217 // create an DisableForTest object, and then create the new | 205 // create an DisableForTest object, and then create the new |
| 218 // NetworkChangeNotifier object. The NetworkChangeNotifier must be | 206 // NetworkChangeNotifier object. The NetworkChangeNotifier must be |
| 219 // destroyed before the DisableForTest object, as its destruction will restore | 207 // destroyed before the DisableForTest object, as its destruction will restore |
| 220 // the original NetworkChangeNotifier. | 208 // the original NetworkChangeNotifier. |
| 221 class NET_EXPORT_PRIVATE DisableForTest { | 209 class NET_EXPORT_PRIVATE DisableForTest { |
| 222 public: | 210 public: |
| 223 DisableForTest(); | 211 DisableForTest(); |
| 224 ~DisableForTest(); | 212 ~DisableForTest(); |
| 225 | 213 |
| 226 private: | 214 private: |
| 227 // The original NetworkChangeNotifier to be restored on destruction. | 215 // The original NetworkChangeNotifier to be restored on destruction. |
| 228 NetworkChangeNotifier* network_change_notifier_; | 216 NetworkChangeNotifier* network_change_notifier_; |
| 229 }; | 217 }; |
| 230 | 218 |
| 231 const scoped_refptr<ObserverListThreadSafe<IPAddressObserver> > | 219 const scoped_refptr<ObserverListThreadSafe<IPAddressObserver> > |
| 232 ip_address_observer_list_; | 220 ip_address_observer_list_; |
| 233 const scoped_refptr<ObserverListThreadSafe<ConnectionTypeObserver> > | 221 const scoped_refptr<ObserverListThreadSafe<ConnectionTypeObserver> > |
| 234 connection_type_observer_list_; | 222 connection_type_observer_list_; |
| 235 const scoped_refptr<ObserverListThreadSafe<DNSObserver> > | 223 const scoped_refptr<ObserverListThreadSafe<DNSObserver> > |
| 236 resolver_state_observer_list_; | 224 resolver_state_observer_list_; |
| 237 | 225 |
| 238 // True iff DNS watchers are operational. | 226 // The current network state. Hosts DnsConfig, exposed via GetDnsConfig. |
| 239 // Otherwise, OnDNSChanged might not be issued for future changes. | 227 scoped_ptr<NetworkState> network_state_; |
| 240 // TODO(szym): This is a temporary interface, consider restarting them. | |
| 241 // http://crbug.com/116139 | |
| 242 base::Lock watching_dns_lock_; | |
| 243 bool watching_dns_; | |
| 244 | 228 |
| 245 // A little-piggy-back observer that simply logs UMA histogram data. | 229 // A little-piggy-back observer that simply logs UMA histogram data. |
| 246 scoped_ptr<HistogramWatcher> histogram_watcher_; | 230 scoped_ptr<HistogramWatcher> histogram_watcher_; |
| 247 | 231 |
| 248 DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifier); | 232 DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifier); |
| 249 }; | 233 }; |
| 250 | 234 |
| 251 } // namespace net | 235 } // namespace net |
| 252 | 236 |
| 253 #endif // NET_BASE_NETWORK_CHANGE_NOTIFIER_H_ | 237 #endif // NET_BASE_NETWORK_CHANGE_NOTIFIER_H_ |
| OLD | NEW |