1 // Copyright 2012 The Chromium Authors 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 8 #include <stdint.h> 9 10 #include <memory> 11 #include <vector> 12 13 #include "base/memory/raw_ptr.h" 14 #include "base/memory/scoped_refptr.h" 15 #include "base/observer_list_threadsafe.h" 16 #include "base/time/time.h" 17 #include "build/build_config.h" 18 #include "net/base/net_export.h" 19 #include "net/base/network_handle.h" 20 21 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) 22 #include "net/base/address_map_linux.h" 23 #endif 24 25 namespace net { 26 27 class NetworkChangeNotifierFactory; 28 struct NetworkInterface; 29 class SystemDnsConfigChangeNotifier; 30 typedef std::vector<NetworkInterface> NetworkInterfaceList; 31 32 namespace internal { 33 #if BUILDFLAG(IS_FUCHSIA) 34 class NetworkInterfaceCache; 35 #endif 36 } // namespace internal 37 38 // NetworkChangeNotifier monitors the system for network changes, and notifies 39 // registered observers of those events. Observers may register on any thread, 40 // and will be called back on the thread from which they registered. 41 // NetworkChangeNotifiers are threadsafe, though they must be created and 42 // destroyed on the same thread. 43 class NET_EXPORT NetworkChangeNotifier { 44 public: 45 // This is a superset of the connection types in the NetInfo v3 specification: 46 // http://w3c.github.io/netinfo/. 47 // 48 // A Java counterpart will be generated for this enum. 49 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net 50 // 51 // New enum values should only be added to the end of the enum and no values 52 // should be modified or reused, as this is reported via UMA. 53 enum ConnectionType { 54 CONNECTION_UNKNOWN = 0, // A connection exists, but its type is unknown. 55 // Also used as a default value. 56 CONNECTION_ETHERNET = 1, 57 CONNECTION_WIFI = 2, 58 CONNECTION_2G = 3, 59 CONNECTION_3G = 4, 60 CONNECTION_4G = 5, 61 CONNECTION_NONE = 6, // No connection. 62 CONNECTION_BLUETOOTH = 7, 63 CONNECTION_5G = 8, 64 CONNECTION_LAST = CONNECTION_5G 65 }; 66 67 // This is the NetInfo v3 set of connection technologies as seen in 68 // http://w3c.github.io/netinfo/. 69 // 70 // A Java counterpart will be generated for this enum. 71 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net 72 // 73 // TODO(crbug.com/1127134): Introduce subtypes for 5G networks once they can 74 // be detected. 75 enum ConnectionSubtype { 76 SUBTYPE_UNKNOWN = 0, 77 SUBTYPE_NONE, 78 SUBTYPE_OTHER, 79 SUBTYPE_GSM, 80 SUBTYPE_IDEN, 81 SUBTYPE_CDMA, 82 SUBTYPE_1XRTT, 83 SUBTYPE_GPRS, 84 SUBTYPE_EDGE, 85 SUBTYPE_UMTS, 86 SUBTYPE_EVDO_REV_0, 87 SUBTYPE_EVDO_REV_A, 88 SUBTYPE_HSPA, 89 SUBTYPE_EVDO_REV_B, 90 SUBTYPE_HSDPA, 91 SUBTYPE_HSUPA, 92 SUBTYPE_EHRPD, 93 SUBTYPE_HSPAP, 94 SUBTYPE_LTE, 95 SUBTYPE_LTE_ADVANCED, 96 SUBTYPE_BLUETOOTH_1_2, 97 SUBTYPE_BLUETOOTH_2_1, 98 SUBTYPE_BLUETOOTH_3_0, 99 SUBTYPE_BLUETOOTH_4_0, 100 SUBTYPE_ETHERNET, 101 SUBTYPE_FAST_ETHERNET, 102 SUBTYPE_GIGABIT_ETHERNET, 103 SUBTYPE_10_GIGABIT_ETHERNET, 104 SUBTYPE_WIFI_B, 105 SUBTYPE_WIFI_G, 106 SUBTYPE_WIFI_N, 107 SUBTYPE_WIFI_AC, 108 SUBTYPE_WIFI_AD, 109 SUBTYPE_LAST = SUBTYPE_WIFI_AD 110 }; 111 112 // A Java counterpart will be generated for this enum. 113 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net 114 // 115 // These values are persisted to logs. Entries should not be renumbered and 116 // numeric values should never be reused. 117 enum ConnectionCost { 118 CONNECTION_COST_UNKNOWN = 0, 119 CONNECTION_COST_UNMETERED, 120 CONNECTION_COST_METERED, 121 CONNECTION_COST_LAST 122 }; 123 124 // DEPRECATED. Please use NetworkChangeObserver instead. crbug.com/754695. 125 class NET_EXPORT IPAddressObserver { 126 public: 127 IPAddressObserver(const IPAddressObserver&) = delete; 128 IPAddressObserver& operator=(const IPAddressObserver&) = delete; 129 130 // Will be called when the IP address of the primary interface changes. 131 // This includes when the primary interface itself changes. 132 virtual void OnIPAddressChanged() = 0; 133 134 protected: 135 IPAddressObserver(); 136 virtual ~IPAddressObserver(); 137 138 private: 139 friend NetworkChangeNotifier; 140 scoped_refptr<base::ObserverListThreadSafe<IPAddressObserver>> 141 observer_list_; 142 }; 143 144 // DEPRECATED. Please use NetworkChangeObserver instead. crbug.com/754695. 145 class NET_EXPORT ConnectionTypeObserver { 146 public: 147 ConnectionTypeObserver(const ConnectionTypeObserver&) = delete; 148 ConnectionTypeObserver& operator=(const ConnectionTypeObserver&) = delete; 149 // Will be called when the connection type of the system has changed. 150 // See NetworkChangeNotifier::GetConnectionType() for important caveats 151 // about the unreliability of using this signal to infer the ability to 152 // reach remote sites. 153 virtual void OnConnectionTypeChanged(ConnectionType type) = 0; 154 155 protected: 156 ConnectionTypeObserver(); 157 virtual ~ConnectionTypeObserver(); 158 159 private: 160 friend NetworkChangeNotifier; 161 scoped_refptr<base::ObserverListThreadSafe<ConnectionTypeObserver>> 162 observer_list_; 163 }; 164 165 class NET_EXPORT DNSObserver { 166 public: 167 DNSObserver(const DNSObserver&) = delete; 168 DNSObserver& operator=(const DNSObserver&) = delete; 169 170 // Will be called when the DNS settings of the system may have changed. 171 virtual void OnDNSChanged() = 0; 172 173 protected: 174 DNSObserver(); 175 virtual ~DNSObserver(); 176 177 private: 178 friend NetworkChangeNotifier; 179 scoped_refptr<base::ObserverListThreadSafe<DNSObserver>> observer_list_; 180 }; 181 182 class NET_EXPORT NetworkChangeObserver { 183 public: 184 NetworkChangeObserver(const NetworkChangeObserver&) = delete; 185 NetworkChangeObserver& operator=(const NetworkChangeObserver&) = delete; 186 187 // OnNetworkChanged will be called when a change occurs to the host 188 // computer's hardware or software that affects the route network packets 189 // take to any network server. Some examples: 190 // 1. A network connection becoming available or going away. For example 191 // plugging or unplugging an Ethernet cable, WiFi or cellular modem 192 // connecting or disconnecting from a network, or a VPN tunnel being 193 // established or taken down. 194 // 2. An active network connection's IP address changes. 195 // 3. A change to the local IP routing tables. 196 // The signal shall only be produced when the change is complete. For 197 // example if a new network connection has become available, only give the 198 // signal once we think the O/S has finished establishing the connection 199 // (i.e. DHCP is done) to the point where the new connection is usable. 200 // The signal shall not be produced spuriously as it will be triggering some 201 // expensive operations, like socket pools closing all connections and 202 // sockets and then re-establishing them. 203 // |type| indicates the type of the active primary network connection after 204 // the change. Observers performing "constructive" activities like trying 205 // to establish a connection to a server should only do so when 206 // |type != CONNECTION_NONE|. Observers performing "destructive" activities 207 // like resetting already established server connections should only do so 208 // when |type == CONNECTION_NONE|. OnNetworkChanged will always be called 209 // with CONNECTION_NONE immediately prior to being called with an online 210 // state; this is done to make sure that destructive actions take place 211 // prior to constructive actions. 212 virtual void OnNetworkChanged(ConnectionType type) = 0; 213 214 protected: 215 NetworkChangeObserver(); 216 virtual ~NetworkChangeObserver(); 217 218 private: 219 friend NetworkChangeNotifier; 220 scoped_refptr<base::ObserverListThreadSafe<NetworkChangeObserver>> 221 observer_list_; 222 }; 223 224 class NET_EXPORT MaxBandwidthObserver { 225 public: 226 MaxBandwidthObserver(const MaxBandwidthObserver&) = delete; 227 MaxBandwidthObserver& operator=(const MaxBandwidthObserver&) = delete; 228 229 // Called when a change occurs to the network's maximum bandwidth as 230 // defined in http://w3c.github.io/netinfo/. Also called on type change, 231 // even if the maximum bandwidth doesn't change. See the documentation of 232 // GetMaxBanwidthAndConnectionType for what to expect for the values of 233 // |max_bandwidth_mbps|. 234 virtual void OnMaxBandwidthChanged(double max_bandwidth_mbps, 235 ConnectionType type) = 0; 236 237 protected: 238 MaxBandwidthObserver(); 239 virtual ~MaxBandwidthObserver(); 240 241 private: 242 friend NetworkChangeNotifier; 243 scoped_refptr<base::ObserverListThreadSafe<MaxBandwidthObserver>> 244 observer_list_; 245 }; 246 247 class NET_EXPORT ConnectionCostObserver { 248 public: 249 // Not copyable or movable 250 ConnectionCostObserver(const ConnectionCostObserver&) = delete; 251 ConnectionCostObserver& operator=(const ConnectionCostObserver&) = delete; 252 253 // Will be called when the connection cost of the default network connection 254 // of the system has changed. This will only fire if the connection cost 255 // actually changes, regardless of any other network-related changes that 256 // might have occurred (for example, changing from ethernet to wifi won't 257 // update this unless that change also results in a cost change). The cost 258 // is not tied directly to any other network-related states, as you could 259 // simply change the current connection from unmetered to metered. It is 260 // safe to assume that network traffic will default to this cost once this 261 // has fired. 262 virtual void OnConnectionCostChanged(ConnectionCost Cost) = 0; 263 264 protected: 265 ConnectionCostObserver(); 266 virtual ~ConnectionCostObserver(); 267 268 private: 269 friend NetworkChangeNotifier; 270 scoped_refptr<base::ObserverListThreadSafe<ConnectionCostObserver>> 271 observer_list_; 272 }; 273 274 // A list of networks. 275 typedef std::vector<handles::NetworkHandle> NetworkList; 276 277 // An interface that when implemented and added via AddNetworkObserver(), 278 // provides notifications when networks come and go. 279 // Only implemented for Android (Lollipop and newer), no callbacks issued when 280 // unimplemented. 281 class NET_EXPORT NetworkObserver { 282 public: 283 NetworkObserver(const NetworkObserver&) = delete; 284 NetworkObserver& operator=(const NetworkObserver&) = delete; 285 286 // Called when device connects to |network|. For example device associates 287 // with a WiFi access point. This does not imply the network has Internet 288 // access as it may well be behind a captive portal. 289 virtual void OnNetworkConnected(handles::NetworkHandle network) = 0; 290 // Called when device disconnects from |network|. 291 virtual void OnNetworkDisconnected(handles::NetworkHandle network) = 0; 292 // Called when device determines the connection to |network| is no longer 293 // preferred, for example when a device transitions from cellular to WiFi 294 // it might deem the cellular connection no longer preferred. The device 295 // will disconnect from |network| in a period of time (30s on Android), 296 // allowing network communications via |network| to wrap up. 297 virtual void OnNetworkSoonToDisconnect(handles::NetworkHandle network) = 0; 298 // Called when |network| is made the default network for communication. 299 virtual void OnNetworkMadeDefault(handles::NetworkHandle network) = 0; 300 301 protected: 302 NetworkObserver(); 303 virtual ~NetworkObserver(); 304 305 private: 306 friend NetworkChangeNotifier; 307 scoped_refptr<base::ObserverListThreadSafe<NetworkObserver>> observer_list_; 308 }; 309 310 // An interface that when implemented and added via 311 // AddDefaultNetworkActiveObserver(), provides notifications when the system 312 // default network has gone in to a high power state. 313 // Only implemented for Android (Lollipop and newer), no callbacks issued when 314 // unimplemented. 315 class NET_EXPORT DefaultNetworkActiveObserver { 316 public: 317 DefaultNetworkActiveObserver(const DefaultNetworkActiveObserver&) = delete; 318 DefaultNetworkActiveObserver& operator=( 319 const DefaultNetworkActiveObserver&) = delete; 320 321 // Called when device default network goes in to a high power state. 322 virtual void OnDefaultNetworkActive() = 0; 323 324 protected: 325 DefaultNetworkActiveObserver(); 326 virtual ~DefaultNetworkActiveObserver(); 327 328 private: 329 friend NetworkChangeNotifier; 330 scoped_refptr<base::ObserverListThreadSafe<DefaultNetworkActiveObserver>> 331 observer_list_; 332 }; 333 334 #if BUILDFLAG(IS_CHROMEOS_LACROS) 335 // TODO(crbug.com/1347382): Remove this section and align the behavior 336 // with other platforms or confirm that Lacros needs to be separated. 337 static constexpr ConnectionType kDefaultInitialConnectionType = 338 CONNECTION_UNKNOWN; 339 static constexpr ConnectionSubtype kDefaultInitialConnectionSubtype = 340 SUBTYPE_UNKNOWN; 341 #else 342 static constexpr ConnectionType kDefaultInitialConnectionType = 343 CONNECTION_NONE; 344 static constexpr ConnectionSubtype kDefaultInitialConnectionSubtype = 345 SUBTYPE_NONE; 346 #endif 347 348 NetworkChangeNotifier(const NetworkChangeNotifier&) = delete; 349 NetworkChangeNotifier& operator=(const NetworkChangeNotifier&) = delete; 350 virtual ~NetworkChangeNotifier(); 351 352 // Returns the factory or nullptr if it is not set. 353 static NetworkChangeNotifierFactory* GetFactory(); 354 355 // Replaces the default class factory instance of NetworkChangeNotifier class. 356 // The method will take over the ownership of |factory| object. 357 static void SetFactory(NetworkChangeNotifierFactory* factory); 358 359 // Creates the process-wide, platform-specific NetworkChangeNotifier if it 360 // hasn't been created. The caller owns the returned pointer. You may call 361 // this on any thread. If the process-wide NetworkChangeNotifier already 362 // exists, this call will return a nullptr. Otherwise, it will guaranteed 363 // to return a valid instance. You may also avoid creating this entirely 364 // (in which case nothing will be monitored), but if you do create it, you 365 // must do so before any other threads try to access the API below, and it 366 // must outlive all other threads which might try to use it. 367 static std::unique_ptr<NetworkChangeNotifier> CreateIfNeeded( 368 ConnectionType initial_type = kDefaultInitialConnectionType, 369 ConnectionSubtype initial_subtype = kDefaultInitialConnectionSubtype); 370 371 // Returns the most likely cost attribute for the default network connection. 372 // The value does not indicate with absolute certainty if using the connection 373 // will or will not incur a monetary cost to the user. It is a best guess 374 // based on Operating System information and network interface type. 375 static ConnectionCost GetConnectionCost(); 376 377 // Returns the connection type. 378 // A return value of |CONNECTION_NONE| is a pretty strong indicator that the 379 // user won't be able to connect to remote sites. However, another return 380 // value doesn't imply that the user will be able to connect to remote sites; 381 // even if some link is up, it is uncertain whether a particular connection 382 // attempt to a particular remote site will be successful. 383 // The returned value only describes the first-hop connection, for example if 384 // the device is connected via WiFi to a 4G hotspot, the returned value will 385 // be CONNECTION_WIFI, not CONNECTION_4G. 386 static ConnectionType GetConnectionType(); 387 388 // Returns the device's current default active network connection's subtype. 389 // The returned value only describes the first-hop connection, for example if 390 // the device is connected via WiFi to a 4G hotspot, the returned value will 391 // reflect WiFi, not 4G. This method may return SUBTYPE_UNKNOWN even if the 392 // connection type is known. 393 static ConnectionSubtype GetConnectionSubtype(); 394 395 // Sets |max_bandwidth_mbps| to a theoretical upper limit on download 396 // bandwidth, potentially based on underlying connection type, signal 397 // strength, or some other signal. If the network subtype is unknown then 398 // |max_bandwidth_mbps| is set to +Infinity and if there is no network 399 // connection then it is set to 0.0. The circumstances in which a more 400 // specific value is given are: when an Android device is connected to a 401 // cellular or WiFi network, and when a ChromeOS device is connected to a 402 // cellular network. See the NetInfo spec for the mapping of 403 // specific subtypes to bandwidth values: http://w3c.github.io/netinfo/. 404 // |connection_type| is set to the current active default network's connection 405 // type. 406 static void GetMaxBandwidthAndConnectionType(double* max_bandwidth_mbps, 407 ConnectionType* connection_type); 408 409 // Returns a theoretical upper limit (in Mbps) on download bandwidth given a 410 // connection subtype. The mapping of connection type to maximum bandwidth is 411 // provided in the NetInfo spec: http://w3c.github.io/netinfo/. 412 static double GetMaxBandwidthMbpsForConnectionSubtype( 413 ConnectionSubtype subtype); 414 415 // Returns true if the platform supports use of APIs based on 416 // handles::NetworkHandles. Public methods that use handles::NetworkHandles 417 // are GetNetworkConnectionType(), GetNetworkConnectionType(), 418 // GetDefaultNetwork(), AddNetworkObserver(), RemoveNetworkObserver(), and all 419 // public NetworkObserver methods. 420 static bool AreNetworkHandlesSupported(); 421 422 // Sets |network_list| to a list of all networks that are currently connected. 423 // Only implemented for Android (Lollipop and newer), leaves |network_list| 424 // empty when unimplemented. Requires handles::NetworkHandles support, see 425 // AreNetworkHandlesSupported(). 426 static void GetConnectedNetworks(NetworkList* network_list); 427 428 // Returns the type of connection |network| uses. Note that this may vary 429 // slightly over time (e.g. CONNECTION_2G to CONNECTION_3G). If |network| 430 // is no longer connected, it will return CONNECTION_UNKNOWN. 431 // Only implemented for Android (Lollipop and newer), returns 432 // CONNECTION_UNKNOWN when unimplemented. Requires handles::NetworkHandles 433 // support, see AreNetworkHandlesSupported(). 434 static ConnectionType GetNetworkConnectionType( 435 handles::NetworkHandle network); 436 437 // Returns the device's current default network connection. This is the 438 // network used for newly created socket communication for sockets that are 439 // not explicitly bound to a particular network (e.g. via 440 // DatagramClientSocket.BindToNetwork). Returns |kInvalidNetworkHandle| if 441 // there is no default connected network. 442 // Only implemented for Android (Lollipop and newer), returns 443 // |kInvalidNetworkHandle| when unimplemented. 444 // Requires handles::NetworkHandles support, see AreNetworkHandlesSupported(). 445 static handles::NetworkHandle GetDefaultNetwork(); 446 447 // Get the underlying SystemDnsConfigChangeNotifier, or null if there is none. 448 // Only intended for code building HostResolverManagers. Other code intending 449 // to watch for DNS config changes should use 450 // NetworkChangeNotifier::AddDNSObserver to receive notifications about both 451 // underlying system config changes and effective changes added on top by 452 // Chrome net code. 453 static SystemDnsConfigChangeNotifier* GetSystemDnsConfigNotifier(); 454 455 // Returns true if the device default network is currently in a high power 456 // state. 457 // Only implemented for Android (Lollipop and newer). Always returns true 458 // when unimplemented, required in order to avoid indefinitely batching 459 // packets sent lazily. 460 static bool IsDefaultNetworkActive(); 461 462 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) 463 // Returns the AddressTrackerLinux if present. 464 static AddressMapOwnerLinux* GetAddressMapOwner(); 465 #endif 466 467 #if BUILDFLAG(IS_FUCHSIA) 468 // Returns the NetworkInterfaceCache if present. 469 static const internal::NetworkInterfaceCache* GetNetworkInterfaceCache(); 470 #endif 471 472 // Convenience method to determine if the user is offline. 473 // Returns true if there is currently no internet connection. 474 // 475 // A return value of |true| is a pretty strong indicator that the user 476 // won't be able to connect to remote sites. However, a return value of 477 // |false| is inconclusive; even if some link is up, it is uncertain 478 // whether a particular connection attempt to a particular remote site 479 // will be successfully. 480 static bool IsOffline(); 481 482 // Returns true if |type| is a cellular connection. 483 // Returns false if |type| is CONNECTION_UNKNOWN, and thus, depending on the 484 // implementation of GetConnectionType(), it is possible that 485 // IsConnectionCellular(GetConnectionType()) returns false even if the 486 // current connection is cellular. 487 static bool IsConnectionCellular(ConnectionType type); 488 489 // Gets the current connection type based on |interfaces|. Returns 490 // CONNECTION_NONE if there are no interfaces, CONNECTION_UNKNOWN if two 491 // interfaces have different connection types or the connection type of all 492 // interfaces if they have the same interface type. 493 static ConnectionType ConnectionTypeFromInterfaceList( 494 const NetworkInterfaceList& interfaces); 495 496 // Like CreateIfNeeded(), but for use in tests. The mock object doesn't 497 // monitor any events, it merely rebroadcasts notifications when requested. 498 static std::unique_ptr<NetworkChangeNotifier> CreateMockIfNeeded(); 499 500 // Registers |observer| to receive notifications of network changes. The 501 // thread on which this is called is the thread on which |observer| will be 502 // called back with notifications. This is safe to call if Create() has not 503 // been called (as long as it doesn't race the Create() call on another 504 // thread), in which case it will add the observers to the static observer 505 // list and be notified once the network change notifier is created. 506 507 // DEPRECATED. IPAddressObserver is deprecated. Please use 508 // NetworkChangeObserver instead. crbug.com/754695. 509 static void AddIPAddressObserver(IPAddressObserver* observer); 510 // DEPRECATED. ConnectionTypeObserver is deprecated. Please use 511 // NetworkChangeObserver instead. crbug.com/754695. 512 static void AddConnectionTypeObserver(ConnectionTypeObserver* observer); 513 static void AddDNSObserver(DNSObserver* observer); 514 static void AddNetworkChangeObserver(NetworkChangeObserver* observer); 515 static void AddMaxBandwidthObserver(MaxBandwidthObserver* observer); 516 static void AddNetworkObserver(NetworkObserver* observer); 517 static void AddConnectionCostObserver(ConnectionCostObserver* observer); 518 static void AddDefaultNetworkActiveObserver( 519 DefaultNetworkActiveObserver* observer); 520 521 // Unregisters |observer| from receiving notifications. This must be called 522 // on the same thread on which AddObserver() was called. Like AddObserver(), 523 // this is safe to call if Create() has not been called (as long as it doesn't 524 // race the Create() call on another thread), in which case it will simply do 525 // nothing. Technically, it's also safe to call after the notifier object has 526 // been destroyed, if the call doesn't race the notifier's destruction, but 527 // there's no reason to use the API in this risky way, so don't do it. 528 529 // DEPRECATED. IPAddressObserver is deprecated. Please use 530 // NetworkChangeObserver instead. crbug.com/754695. 531 static void RemoveIPAddressObserver(IPAddressObserver* observer); 532 // DEPRECATED. ConnectionTypeObserver is deprecated. Please use 533 // NetworkChangeObserver instead. crbug.com/754695. 534 static void RemoveConnectionTypeObserver(ConnectionTypeObserver* observer); 535 static void RemoveDNSObserver(DNSObserver* observer); 536 static void RemoveNetworkChangeObserver(NetworkChangeObserver* observer); 537 static void RemoveMaxBandwidthObserver(MaxBandwidthObserver* observer); 538 static void RemoveNetworkObserver(NetworkObserver* observer); 539 static void RemoveConnectionCostObserver(ConnectionCostObserver* observer); 540 static void RemoveDefaultNetworkActiveObserver( 541 DefaultNetworkActiveObserver* observer); 542 543 // Called to signify a non-system DNS config change. 544 static void TriggerNonSystemDnsChange(); 545 546 // Allows unit tests to trigger notifications. 547 static void NotifyObserversOfIPAddressChangeForTests(); 548 static void NotifyObserversOfConnectionTypeChangeForTests( 549 ConnectionType type); 550 static void NotifyObserversOfDNSChangeForTests(); 551 static void NotifyObserversOfNetworkChangeForTests(ConnectionType type); 552 static void NotifyObserversOfMaxBandwidthChangeForTests( 553 double max_bandwidth_mbps, 554 ConnectionType type); 555 static void NotifyObserversOfConnectionCostChangeForTests( 556 ConnectionCost cost); 557 static void NotifyObserversOfDefaultNetworkActiveForTests(); 558 559 // Enables or disables notifications from the host. After setting to true, be 560 // sure to pump the RunLoop until idle to finish any preexisting 561 // notifications. To use this, it must must be called before a 562 // NetworkChangeNotifier is created. 563 static void SetTestNotificationsOnly(bool test_only); 564 565 // Returns true if `test_notifications_only_` is set to true. IsTestNotificationsOnly()566 static bool IsTestNotificationsOnly() { return test_notifications_only_; } 567 568 // Returns a string equivalent to |type|. 569 static const char* ConnectionTypeToString(ConnectionType type); 570 571 // Allows a second NetworkChangeNotifier to be created for unit testing, so 572 // the test suite can create a MockNetworkChangeNotifier, but platform 573 // specific NetworkChangeNotifiers can also be created for testing. To use, 574 // create an DisableForTest object, and then create the new 575 // NetworkChangeNotifier object. The NetworkChangeNotifier must be 576 // destroyed before the DisableForTest object, as its destruction will restore 577 // the original NetworkChangeNotifier. 578 class NET_EXPORT DisableForTest { 579 public: 580 DisableForTest(); 581 ~DisableForTest(); 582 583 private: 584 // The original NetworkChangeNotifier to be restored on destruction. 585 raw_ptr<NetworkChangeNotifier> network_change_notifier_; 586 }; 587 588 protected: 589 // Types of network changes specified to 590 // NotifyObserversOfSpecificNetworkChange. 591 enum class NetworkChangeType { 592 kConnected, 593 kDisconnected, 594 kSoonToDisconnect, 595 kMadeDefault 596 }; 597 598 // NetworkChanged signal is calculated from the IPAddressChanged and 599 // ConnectionTypeChanged signals. Delay parameters control how long to delay 600 // producing NetworkChanged signal after particular input signals so as to 601 // combine duplicates. In other words if an input signal is repeated within 602 // the corresponding delay period, only one resulting NetworkChange signal is 603 // produced. 604 struct NET_EXPORT NetworkChangeCalculatorParams { 605 NetworkChangeCalculatorParams(); 606 // Controls delay after OnIPAddressChanged when transitioning from an 607 // offline state. 608 base::TimeDelta ip_address_offline_delay_; 609 // Controls delay after OnIPAddressChanged when transitioning from an 610 // online state. 611 base::TimeDelta ip_address_online_delay_; 612 // Controls delay after OnConnectionTypeChanged when transitioning from an 613 // offline state. 614 base::TimeDelta connection_type_offline_delay_; 615 // Controls delay after OnConnectionTypeChanged when transitioning from an 616 // online state. 617 base::TimeDelta connection_type_online_delay_; 618 }; 619 620 // If |system_dns_config_notifier| is null (the default), a shared singleton 621 // will be used that will be leaked on shutdown. If 622 // |omit_observers_in_constructor_for_testing| is true, internal observers 623 // aren't added during construction - this is used to skip registering 624 // observers from MockNetworkChangeNotifier, and allow its construction when 625 // SingleThreadTaskRunner::CurrentDefaultHandle isn't set. 626 explicit NetworkChangeNotifier( 627 const NetworkChangeCalculatorParams& params = 628 NetworkChangeCalculatorParams(), 629 SystemDnsConfigChangeNotifier* system_dns_config_notifier = nullptr, 630 bool omit_observers_in_constructor_for_testing = false); 631 632 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) 633 // Returns the AddressMapOwnerLinux if present. 634 virtual AddressMapOwnerLinux* GetAddressMapOwnerInternal(); 635 #endif 636 637 #if BUILDFLAG(IS_FUCHSIA) 638 virtual const internal::NetworkInterfaceCache* 639 GetNetworkInterfaceCacheInternal() const; 640 #endif 641 642 // These are the actual implementations of the static queryable APIs. 643 // See the description of the corresponding functions named without "Current". 644 // Implementations must be thread-safe. Implementations must also be 645 // cheap as they are called often. 646 virtual ConnectionCost GetCurrentConnectionCost(); 647 virtual ConnectionType GetCurrentConnectionType() const = 0; 648 virtual ConnectionSubtype GetCurrentConnectionSubtype() const; 649 virtual void GetCurrentMaxBandwidthAndConnectionType( 650 double* max_bandwidth_mbps, 651 ConnectionType* connection_type) const; 652 virtual bool AreNetworkHandlesCurrentlySupported() const; 653 virtual void GetCurrentConnectedNetworks(NetworkList* network_list) const; 654 virtual ConnectionType GetCurrentNetworkConnectionType( 655 handles::NetworkHandle network) const; 656 virtual handles::NetworkHandle GetCurrentDefaultNetwork() const; 657 virtual SystemDnsConfigChangeNotifier* GetCurrentSystemDnsConfigNotifier(); 658 659 virtual bool IsDefaultNetworkActiveInternal(); 660 661 // Broadcasts a notification to all registered observers. Note that this 662 // happens asynchronously, even for observers on the current thread, even in 663 // tests. 664 static void NotifyObserversOfIPAddressChange(); 665 static void NotifyObserversOfConnectionTypeChange(); 666 static void NotifyObserversOfDNSChange(); 667 static void NotifyObserversOfNetworkChange(ConnectionType type); 668 static void NotifyObserversOfMaxBandwidthChange(double max_bandwidth_mbps, 669 ConnectionType type); 670 static void NotifyObserversOfSpecificNetworkChange( 671 NetworkChangeType type, 672 handles::NetworkHandle network); 673 static void NotifyObserversOfConnectionCostChange(); 674 static void NotifyObserversOfDefaultNetworkActive(); 675 676 // Infer connection type from |GetNetworkList|. If all network interfaces 677 // have the same type, return it, otherwise return CONNECTION_UNKNOWN. 678 static ConnectionType ConnectionTypeFromInterfaces(); 679 680 // Unregisters and clears |system_dns_config_notifier_|. Useful if a subclass 681 // owns the notifier and is destroying it before |this|'s destructor is called 682 void StopSystemDnsConfigNotifier(); 683 684 // Clears the global NetworkChangeNotifier pointer. This should be called 685 // as early as possible in the destructor to prevent races. 686 void ClearGlobalPointer(); 687 688 // Called whenever a new ConnectionCostObserver is added. This method is 689 // needed so that the implementation class can be notified and 690 // potentially take action when an observer gets added. Since the act of 691 // adding an observer and the observer list itself are both static, the 692 // implementation class has no direct capability to watch for changes. ConnectionCostObserverAdded()693 virtual void ConnectionCostObserverAdded() {} 694 695 // Listening for notifications of this type is expensive as they happen 696 // frequently. For this reason, we report {de}registration to the 697 // implementation class, so that it can decide to only listen to this type of 698 // Android system notifications when there are observers interested. DefaultNetworkActiveObserverAdded()699 virtual void DefaultNetworkActiveObserverAdded() {} DefaultNetworkActiveObserverRemoved()700 virtual void DefaultNetworkActiveObserverRemoved() {} 701 702 private: 703 friend class HostResolverManagerDnsTest; 704 friend class NetworkChangeNotifierAndroidTest; 705 friend class NetworkChangeNotifierLinuxTest; 706 friend class NetworkChangeNotifierWinTest; 707 708 class NetworkChangeCalculator; 709 class SystemDnsConfigObserver; 710 class ObserverList; 711 712 static ObserverList& GetObserverList(); 713 714 void NotifyObserversOfIPAddressChangeImpl(); 715 void NotifyObserversOfConnectionTypeChangeImpl(ConnectionType type); 716 void NotifyObserversOfDNSChangeImpl(); 717 void NotifyObserversOfNetworkChangeImpl(ConnectionType type); 718 void NotifyObserversOfMaxBandwidthChangeImpl(double max_bandwidth_mbps, 719 ConnectionType type); 720 void NotifyObserversOfSpecificNetworkChangeImpl( 721 NetworkChangeType type, 722 handles::NetworkHandle network); 723 void NotifyObserversOfConnectionCostChangeImpl(ConnectionCost cost); 724 void NotifyObserversOfDefaultNetworkActiveImpl(); 725 726 raw_ptr<SystemDnsConfigChangeNotifier> system_dns_config_notifier_; 727 std::unique_ptr<SystemDnsConfigObserver> system_dns_config_observer_; 728 729 // Computes NetworkChange signal from IPAddress and ConnectionType signals. 730 std::unique_ptr<NetworkChangeCalculator> network_change_calculator_; 731 732 // Set true to disable non-test notifications (to prevent flakes in tests). 733 static bool test_notifications_only_; 734 735 // Indicates if this instance cleared g_network_change_notifier_ yet. 736 bool cleared_global_pointer_ = false; 737 }; 738 739 } // namespace net 740 741 #endif // NET_BASE_NETWORK_CHANGE_NOTIFIER_H_ 742