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