• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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