// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_BASE_NETWORK_CHANGE_NOTIFIER_H_
#define NET_BASE_NETWORK_CHANGE_NOTIFIER_H_

#include <stdint.h>

#include <memory>
#include <vector>

#include "base/macros.h"
#include "base/observer_list_threadsafe.h"
#include "base/time/time.h"
#include "net/base/net_export.h"

namespace net {

struct DnsConfig;
class NetworkChangeNotifierFactory;
struct NetworkInterface;
typedef std::vector<NetworkInterface> NetworkInterfaceList;

#if defined(OS_LINUX)
namespace internal {
class AddressTrackerLinux;
}
#endif

// NetworkChangeNotifier monitors the system for network changes, and notifies
// registered observers of those events.  Observers may register on any thread,
// and will be called back on the thread from which they registered.
// NetworkChangeNotifiers are threadsafe, though they must be created and
// destroyed on the same thread.
class NET_EXPORT NetworkChangeNotifier {
 public:
  // This is a superset of the connection types in the NetInfo v3 specification:
  // http://w3c.github.io/netinfo/.
  //
  // A Java counterpart will be generated for this enum.
  // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net
  //
  // New enum values should only be added to the end of the enum and no values
  // should be modified or reused, as this is reported via UMA.
  enum ConnectionType {
    CONNECTION_UNKNOWN = 0,  // A connection exists, but its type is unknown.
                             // Also used as a default value.
    CONNECTION_ETHERNET = 1,
    CONNECTION_WIFI = 2,
    CONNECTION_2G = 3,
    CONNECTION_3G = 4,
    CONNECTION_4G = 5,
    CONNECTION_NONE = 6,     // No connection.
    CONNECTION_BLUETOOTH = 7,
    CONNECTION_LAST = CONNECTION_BLUETOOTH
  };

  // This is the NetInfo v3 set of connection technologies as seen in
  // http://w3c.github.io/netinfo/. This enum is duplicated in histograms.xml
  // so be sure to change both at once. Additionally, since this enum is used in
  // a UMA histogram, it should not be re-ordered and any new values should be
  // added to the end.
  //
  // A Java counterpart will be generated for this enum.
  // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net
  enum ConnectionSubtype {
    SUBTYPE_UNKNOWN = 0,
    SUBTYPE_NONE,
    SUBTYPE_OTHER,
    SUBTYPE_GSM,
    SUBTYPE_IDEN,
    SUBTYPE_CDMA,
    SUBTYPE_1XRTT,
    SUBTYPE_GPRS,
    SUBTYPE_EDGE,
    SUBTYPE_UMTS,
    SUBTYPE_EVDO_REV_0,
    SUBTYPE_EVDO_REV_A,
    SUBTYPE_HSPA,
    SUBTYPE_EVDO_REV_B,
    SUBTYPE_HSDPA,
    SUBTYPE_HSUPA,
    SUBTYPE_EHRPD,
    SUBTYPE_HSPAP,
    SUBTYPE_LTE,
    SUBTYPE_LTE_ADVANCED,
    SUBTYPE_BLUETOOTH_1_2,
    SUBTYPE_BLUETOOTH_2_1,
    SUBTYPE_BLUETOOTH_3_0,
    SUBTYPE_BLUETOOTH_4_0,
    SUBTYPE_ETHERNET,
    SUBTYPE_FAST_ETHERNET,
    SUBTYPE_GIGABIT_ETHERNET,
    SUBTYPE_10_GIGABIT_ETHERNET,
    SUBTYPE_WIFI_B,
    SUBTYPE_WIFI_G,
    SUBTYPE_WIFI_N,
    SUBTYPE_WIFI_AC,
    SUBTYPE_WIFI_AD,
    SUBTYPE_LAST = SUBTYPE_WIFI_AD
  };

  // DEPRECATED. Please use NetworkChangeObserver instead. crbug.com/754695.
  class NET_EXPORT IPAddressObserver {
   public:
    // Will be called when the IP address of the primary interface changes.
    // This includes when the primary interface itself changes.
    virtual void OnIPAddressChanged() = 0;

   protected:
    IPAddressObserver() {}
    virtual ~IPAddressObserver() {}

   private:
    DISALLOW_COPY_AND_ASSIGN(IPAddressObserver);
  };

  // DEPRECATED. Please use NetworkChangeObserver instead. crbug.com/754695.
  class NET_EXPORT ConnectionTypeObserver {
   public:
    // Will be called when the connection type of the system has changed.
    // See NetworkChangeNotifier::GetConnectionType() for important caveats
    // about the unreliability of using this signal to infer the ability to
    // reach remote sites.
    virtual void OnConnectionTypeChanged(ConnectionType type) = 0;

   protected:
    ConnectionTypeObserver() {}
    virtual ~ConnectionTypeObserver() {}

   private:
    DISALLOW_COPY_AND_ASSIGN(ConnectionTypeObserver);
  };

  class NET_EXPORT DNSObserver {
   public:
    // Will be called when the DNS settings of the system may have changed.
    // Use GetDnsConfig to obtain the current settings.
    virtual void OnDNSChanged() = 0;
    // Will be called when DNS settings of the system have been loaded.
    // Use GetDnsConfig to obtain the current settings.
    // NOTE(pauljensen): This will not be called if the initial DNS config
    // has already been read before this observer is registered.
    // Determining if a DNS config has already been read can be done by
    // calling GetDnsConfig() after registering an observer, and seeing if
    // the DnsConfig's IsValid() returns true.
    virtual void OnInitialDNSConfigRead();

   protected:
    DNSObserver() {}
    virtual ~DNSObserver() {}

   private:
    DISALLOW_COPY_AND_ASSIGN(DNSObserver);
  };

  class NET_EXPORT NetworkChangeObserver {
   public:
    // OnNetworkChanged will be called when a change occurs to the host
    // computer's hardware or software that affects the route network packets
    // take to any network server. Some examples:
    //   1. A network connection becoming available or going away. For example
    //      plugging or unplugging an Ethernet cable, WiFi or cellular modem
    //      connecting or disconnecting from a network, or a VPN tunnel being
    //      established or taken down.
    //   2. An active network connection's IP address changes.
    //   3. A change to the local IP routing tables.
    // The signal shall only be produced when the change is complete.  For
    // example if a new network connection has become available, only give the
    // signal once we think the O/S has finished establishing the connection
    // (i.e. DHCP is done) to the point where the new connection is usable.
    // The signal shall not be produced spuriously as it will be triggering some
    // expensive operations, like socket pools closing all connections and
    // sockets and then re-establishing them.
    // |type| indicates the type of the active primary network connection after
    // the change.  Observers performing "constructive" activities like trying
    // to establish a connection to a server should only do so when
    // |type != CONNECTION_NONE|.  Observers performing "destructive" activities
    // like resetting already established server connections should only do so
    // when |type == CONNECTION_NONE|.  OnNetworkChanged will always be called
    // with CONNECTION_NONE immediately prior to being called with an online
    // state; this is done to make sure that destructive actions take place
    // prior to constructive actions.
    virtual void OnNetworkChanged(ConnectionType type) = 0;

   protected:
    NetworkChangeObserver() {}
    virtual ~NetworkChangeObserver() {}

   private:
    DISALLOW_COPY_AND_ASSIGN(NetworkChangeObserver);
  };

  class NET_EXPORT MaxBandwidthObserver {
   public:
    // Called when a change occurs to the network's maximum bandwidth as
    // defined in http://w3c.github.io/netinfo/. Also called on type change,
    // even if the maximum bandwidth doesn't change. See the documentation of
    // GetMaxBanwidthAndConnectionType for what to expect for the values of
    // |max_bandwidth_mbps|.
    virtual void OnMaxBandwidthChanged(double max_bandwidth_mbps,
                                       ConnectionType type) = 0;

   protected:
    MaxBandwidthObserver() {}
    virtual ~MaxBandwidthObserver() {}

   private:
    DISALLOW_COPY_AND_ASSIGN(MaxBandwidthObserver);
  };

  // Opaque handle for device-wide connection to a particular network. For
  // example an association with a particular WiFi network with a particular
  // SSID or a connection to particular cellular network.
  // The meaning of this handle is target-dependent. On Android NetworkHandles
  // are equivalent to:
  //   On Lollipop, the framework's concept of NetIDs (e.g. Network.netId), and
  //   On Marshmallow and newer releases, network handles
  //           (e.g. Network.getNetworkHandle()).
  typedef int64_t NetworkHandle;

  // A list of networks.
  typedef std::vector<NetworkHandle> NetworkList;

  // An interface that when implemented and added via AddNeworkObserver(),
  // provides notifications when networks come and go.
  // Only implemented for Android (Lollipop and newer), no callbacks issued when
  // unimplemented.
  class NET_EXPORT NetworkObserver {
   public:
    // Called when device connects to |network|. For example device associates
    // with a WiFi access point. This does not imply the network has Internet
    // access as it may well be behind a captive portal.
    virtual void OnNetworkConnected(NetworkHandle network) = 0;
    // Called when device disconnects from |network|.
    virtual void OnNetworkDisconnected(NetworkHandle network) = 0;
    // Called when device determines the connection to |network| is no longer
    // preferred, for example when a device transitions from cellular to WiFi
    // it might deem the cellular connection no longer preferred. The device
    // will disconnect from |network| in a period of time (30s on Android),
    // allowing network communications via |network| to wrap up.
    virtual void OnNetworkSoonToDisconnect(NetworkHandle network) = 0;
    // Called when |network| is made the default network for communication.
    virtual void OnNetworkMadeDefault(NetworkHandle network) = 0;

   protected:
    NetworkObserver() {}
    virtual ~NetworkObserver() {}

   private:
    DISALLOW_COPY_AND_ASSIGN(NetworkObserver);
  };

  // An invalid NetworkHandle.
  static const NetworkHandle kInvalidNetworkHandle;

  virtual ~NetworkChangeNotifier();

  // Returns the factory or nullptr if it is not set.
  static NetworkChangeNotifierFactory* GetFactory();

  // Replaces the default class factory instance of NetworkChangeNotifier class.
  // The method will take over the ownership of |factory| object.
  static void SetFactory(NetworkChangeNotifierFactory* factory);

  // Creates the process-wide, platform-specific NetworkChangeNotifier.  The
  // caller owns the returned pointer.  You may call this on any thread.  You
  // may also avoid creating this entirely (in which case nothing will be
  // monitored), but if you do create it, you must do so before any other
  // threads try to access the API below, and it must outlive all other threads
  // which might try to use it.
  static NetworkChangeNotifier* Create();

  // Returns whether the process-wide, platform-specific NetworkChangeNotifier
  // has been created.
  static bool HasNetworkChangeNotifier();

  // Returns the connection type.
  // A return value of |CONNECTION_NONE| is a pretty strong indicator that the
  // user won't be able to connect to remote sites. However, another return
  // value doesn't imply that the user will be able to connect to remote sites;
  // even if some link is up, it is uncertain whether a particular connection
  // attempt to a particular remote site will be successful.
  // The returned value only describes the first-hop connection, for example if
  // the device is connected via WiFi to a 4G hotspot, the returned value will
  // be CONNECTION_WIFI, not CONNECTION_4G.
  static ConnectionType GetConnectionType();

  // Returns the device's current default active network connection's subtype.
  // The returned value only describes the first-hop connection, for example if
  // the device is connected via WiFi to a 4G hotspot, the returned value will
  // reflect WiFi, not 4G. This method may return SUBTYPE_UNKNOWN even if the
  // connection type is known.
  static ConnectionSubtype GetConnectionSubtype();

  // Sets |max_bandwidth_mbps| to a theoretical upper limit on download
  // bandwidth, potentially based on underlying connection type, signal
  // strength, or some other signal. If the network subtype is unknown then
  // |max_bandwidth_mbps| is set to +Infinity and if there is no network
  // connection then it is set to 0.0. The circumstances in which a more
  // specific value is given are: when an Android device is connected to a
  // cellular or WiFi network, and when a ChromeOS device is connected to a
  // cellular network. See the NetInfo spec for the mapping of
  // specific subtypes to bandwidth values: http://w3c.github.io/netinfo/.
  // |connection_type| is set to the current active default network's connection
  // type.
  static void GetMaxBandwidthAndConnectionType(double* max_bandwidth_mbps,
                                               ConnectionType* connection_type);

  // Returns a theoretical upper limit (in Mbps) on download bandwidth given a
  // connection subtype. The mapping of connection type to maximum bandwidth is
  // provided in the NetInfo spec: http://w3c.github.io/netinfo/.
  static double GetMaxBandwidthMbpsForConnectionSubtype(
      ConnectionSubtype subtype);

  // Returns true if the platform supports use of APIs based on NetworkHandles.
  // Public methods that use NetworkHandles are GetNetworkConnectionType(),
  // GetNetworkConnectionType(), GetDefaultNetwork(), AddNetworkObserver(),
  // RemoveNetworkObserver(), and all public NetworkObserver methods.
  static bool AreNetworkHandlesSupported();

  // Sets |network_list| to a list of all networks that are currently connected.
  // Only implemented for Android (Lollipop and newer), leaves |network_list|
  // empty when unimplemented. Requires NetworkHandles support, see
  // AreNetworkHandlesSupported().
  static void GetConnectedNetworks(NetworkList* network_list);

  // Returns the type of connection |network| uses. Note that this may vary
  // slightly over time (e.g. CONNECTION_2G to CONNECTION_3G). If |network|
  // is no longer connected, it will return CONNECTION_UNKNOWN.
  // Only implemented for Android (Lollipop and newer), returns
  // CONNECTION_UNKNOWN when unimplemented. Requires NetworkHandles support,
  // see AreNetworkHandlesSupported().
  static ConnectionType GetNetworkConnectionType(NetworkHandle network);

  // Returns the device's current default network connection. This is the
  // network used for newly created socket communication for sockets that are
  // not explicitly bound to a particular network (e.g. via
  // DatagramClientSocket.BindToNetwork). Returns |kInvalidNetworkHandle| if
  // there is no default connected network.
  // Only implemented for Android (Lollipop and newer), returns
  // |kInvalidNetworkHandle| when unimplemented.
  // Requires NetworkHandles support, see AreNetworkHandlesSupported().
  static NetworkHandle GetDefaultNetwork();

  // Retrieve the last read DnsConfig. This could be expensive if the system has
  // a large HOSTS file.
  static void GetDnsConfig(DnsConfig* config);

#if defined(OS_LINUX)
  // Returns the AddressTrackerLinux if present.
  static const internal::AddressTrackerLinux* GetAddressTracker();
#endif

  // Convenience method to determine if the user is offline.
  // Returns true if there is currently no internet connection.
  //
  // A return value of |true| is a pretty strong indicator that the user
  // won't be able to connect to remote sites. However, a return value of
  // |false| is inconclusive; even if some link is up, it is uncertain
  // whether a particular connection attempt to a particular remote site
  // will be successfully.
  static bool IsOffline();

  // Returns true if |type| is a cellular connection.
  // Returns false if |type| is CONNECTION_UNKNOWN, and thus, depending on the
  // implementation of GetConnectionType(), it is possible that
  // IsConnectionCellular(GetConnectionType()) returns false even if the
  // current connection is cellular.
  static bool IsConnectionCellular(ConnectionType type);

  // Gets the current connection type based on |interfaces|. Returns
  // CONNECTION_NONE if there are no interfaces, CONNECTION_UNKNOWN if two
  // interfaces have different connection types or the connection type of all
  // interfaces if they have the same interface type.
  static ConnectionType ConnectionTypeFromInterfaceList(
      const NetworkInterfaceList& interfaces);

  // Like Create(), but for use in tests.  The mock object doesn't monitor any
  // events, it merely rebroadcasts notifications when requested.
  static NetworkChangeNotifier* CreateMock();

  // Registers |observer| to receive notifications of network changes.  The
  // thread on which this is called is the thread on which |observer| will be
  // called back with notifications.  This is safe to call if Create() has not
  // been called (as long as it doesn't race the Create() call on another
  // thread), in which case it will simply do nothing.

  // DEPRECATED. IPAddressObserver is deprecated. Please use
  // NetworkChangeObserver instead. crbug.com/754695.
  static void AddIPAddressObserver(IPAddressObserver* observer);
  // DEPRECATED. ConnectionTypeObserver is deprecated. Please use
  // NetworkChangeObserver instead. crbug.com/754695.
  static void AddConnectionTypeObserver(ConnectionTypeObserver* observer);
  static void AddDNSObserver(DNSObserver* observer);
  static void AddNetworkChangeObserver(NetworkChangeObserver* observer);
  static void AddMaxBandwidthObserver(MaxBandwidthObserver* observer);
  static void AddNetworkObserver(NetworkObserver* observer);

  // Unregisters |observer| from receiving notifications.  This must be called
  // on the same thread on which AddObserver() was called.  Like AddObserver(),
  // this is safe to call if Create() has not been called (as long as it doesn't
  // race the Create() call on another thread), in which case it will simply do
  // nothing.  Technically, it's also safe to call after the notifier object has
  // been destroyed, if the call doesn't race the notifier's destruction, but
  // there's no reason to use the API in this risky way, so don't do it.

  // DEPRECATED. IPAddressObserver is deprecated. Please use
  // NetworkChangeObserver instead. crbug.com/754695.
  static void RemoveIPAddressObserver(IPAddressObserver* observer);
  // DEPRECATED. ConnectionTypeObserver is deprecated. Please use
  // NetworkChangeObserver instead. crbug.com/754695.
  static void RemoveConnectionTypeObserver(ConnectionTypeObserver* observer);
  static void RemoveDNSObserver(DNSObserver* observer);
  static void RemoveNetworkChangeObserver(NetworkChangeObserver* observer);
  static void RemoveMaxBandwidthObserver(MaxBandwidthObserver* observer);
  static void RemoveNetworkObserver(NetworkObserver* observer);

  // Allow unit tests to trigger notifications.
  static void NotifyObserversOfIPAddressChangeForTests();
  static void NotifyObserversOfConnectionTypeChangeForTests(
      ConnectionType type);
  static void NotifyObserversOfDNSChangeForTests();
  static void NotifyObserversOfNetworkChangeForTests(ConnectionType type);
  static void NotifyObserversOfInitialDNSConfigReadForTests();
  static void NotifyObserversOfMaxBandwidthChangeForTests(
      double max_bandwidth_mbps,
      ConnectionType type);

  // Enable or disable notifications from the host. After setting to true, be
  // sure to pump the RunLoop until idle to finish any preexisting
  // notifications. To use this, it must must be called before a
  // NetworkChangeNotifier is created.
  static void SetTestNotificationsOnly(bool test_only);

  // Return a string equivalent to |type|.
  static const char* ConnectionTypeToString(ConnectionType type);

  // Invoked at the time a new user metrics log record is being finalized, on
  // the main thread. NCN Histograms that want to be logged once per record
  // should be logged in this method. Platform-specific histograms should be
  // logged in an overridden implementaton of OnFinalizingMetricsLogRecord.
  static void FinalizingMetricsLogRecord();

  // Log the |NCN.NetworkOperatorMCCMNC| histogram.
  static void LogOperatorCodeHistogram(ConnectionType type);

  // Allows a second NetworkChangeNotifier to be created for unit testing, so
  // the test suite can create a MockNetworkChangeNotifier, but platform
  // specific NetworkChangeNotifiers can also be created for testing.  To use,
  // create an DisableForTest object, and then create the new
  // NetworkChangeNotifier object.  The NetworkChangeNotifier must be
  // destroyed before the DisableForTest object, as its destruction will restore
  // the original NetworkChangeNotifier.
  class NET_EXPORT DisableForTest {
   public:
    DisableForTest();
    ~DisableForTest();

   private:
    // The original NetworkChangeNotifier to be restored on destruction.
    NetworkChangeNotifier* network_change_notifier_;
  };

 protected:
  // Types of network changes specified to
  // NotifyObserversOfSpecificNetworkChange.
  enum NetworkChangeType {
    CONNECTED,
    DISCONNECTED,
    SOON_TO_DISCONNECT,
    MADE_DEFAULT
  };

  // NetworkChanged signal is calculated from the IPAddressChanged and
  // ConnectionTypeChanged signals. Delay parameters control how long to delay
  // producing NetworkChanged signal after particular input signals so as to
  // combine duplicates.  In other words if an input signal is repeated within
  // the corresponding delay period, only one resulting NetworkChange signal is
  // produced.
  struct NET_EXPORT NetworkChangeCalculatorParams {
    NetworkChangeCalculatorParams();
    // Controls delay after OnIPAddressChanged when transitioning from an
    // offline state.
    base::TimeDelta ip_address_offline_delay_;
    // Controls delay after OnIPAddressChanged when transitioning from an
    // online state.
    base::TimeDelta ip_address_online_delay_;
    // Controls delay after OnConnectionTypeChanged when transitioning from an
    // offline state.
    base::TimeDelta connection_type_offline_delay_;
    // Controls delay after OnConnectionTypeChanged when transitioning from an
    // online state.
    base::TimeDelta connection_type_online_delay_;
  };

  explicit NetworkChangeNotifier(
      const NetworkChangeCalculatorParams& params =
          NetworkChangeCalculatorParams());

#if defined(OS_LINUX)
  // Returns the AddressTrackerLinux if present.
  // TODO(szym): Retrieve AddressMap from NetworkState. http://crbug.com/144212
  virtual const internal::AddressTrackerLinux*
      GetAddressTrackerInternal() const;
#endif

  // These are the actual implementations of the static queryable APIs.
  // See the description of the corresponding functions named without "Current".
  // Implementations must be thread-safe. Implementations must also be
  // cheap as they are called often.
  virtual ConnectionType GetCurrentConnectionType() const = 0;
  virtual ConnectionSubtype GetCurrentConnectionSubtype() const;
  virtual void GetCurrentMaxBandwidthAndConnectionType(
      double* max_bandwidth_mbps,
      ConnectionType* connection_type) const;
  virtual bool AreNetworkHandlesCurrentlySupported() const;
  virtual void GetCurrentConnectedNetworks(NetworkList* network_list) const;
  virtual ConnectionType GetCurrentNetworkConnectionType(
      NetworkHandle network) const;
  virtual NetworkHandle GetCurrentDefaultNetwork() const;

  // Hook that allows derived implementations to log histograms at the time a
  // new histogram record is being finalized.
  virtual void OnFinalizingMetricsLogRecord() {}

  // Broadcasts a notification to all registered observers.  Note that this
  // happens asynchronously, even for observers on the current thread, even in
  // tests.
  static void NotifyObserversOfIPAddressChange();
  static void NotifyObserversOfConnectionTypeChange();
  static void NotifyObserversOfDNSChange();
  static void NotifyObserversOfInitialDNSConfigRead();
  static void NotifyObserversOfNetworkChange(ConnectionType type);
  static void NotifyObserversOfMaxBandwidthChange(double max_bandwidth_mbps,
                                                  ConnectionType type);
  static void NotifyObserversOfSpecificNetworkChange(NetworkChangeType type,
                                                     NetworkHandle network);

  // Stores |config| in NetworkState and notifies observers. The first
  // notification will be OnInitialDNSConfigRead, and after that OnDNSChanged.
  static void SetDnsConfig(const DnsConfig& config);

  // Clears previous DnsConfig, if any, to simulate the first one being set.
  static void ClearDnsConfigForTesting();

  // Infer connection type from |GetNetworkList|. If all network interfaces
  // have the same type, return it, otherwise return CONNECTION_UNKNOWN.
  static ConnectionType ConnectionTypeFromInterfaces();

 private:
  friend class HostResolverImplDnsTest;
  friend class NetworkChangeNotifierAndroidTest;
  friend class NetworkChangeNotifierLinuxTest;
  friend class NetworkChangeNotifierWinTest;

  class NetworkState;
  class NetworkChangeCalculator;

  void NotifyObserversOfIPAddressChangeImpl();
  void NotifyObserversOfConnectionTypeChangeImpl(ConnectionType type);
  void NotifyObserversOfDNSChangeImpl();
  void NotifyObserversOfInitialDNSConfigReadImpl();
  void NotifyObserversOfNetworkChangeImpl(ConnectionType type);
  void NotifyObserversOfMaxBandwidthChangeImpl(double max_bandwidth_mbps,
                                               ConnectionType type);
  void NotifyObserversOfSpecificNetworkChangeImpl(NetworkChangeType type,
                                                  NetworkHandle network);

  const scoped_refptr<base::ObserverListThreadSafe<IPAddressObserver>>
      ip_address_observer_list_;
  const scoped_refptr<base::ObserverListThreadSafe<ConnectionTypeObserver>>
      connection_type_observer_list_;
  const scoped_refptr<base::ObserverListThreadSafe<DNSObserver>>
      resolver_state_observer_list_;
  const scoped_refptr<base::ObserverListThreadSafe<NetworkChangeObserver>>
      network_change_observer_list_;
  const scoped_refptr<base::ObserverListThreadSafe<MaxBandwidthObserver>>
      max_bandwidth_observer_list_;
  const scoped_refptr<base::ObserverListThreadSafe<NetworkObserver>>
      network_observer_list_;

  // The current network state. Hosts DnsConfig, exposed via GetDnsConfig.
  std::unique_ptr<NetworkState> network_state_;

  // Computes NetworkChange signal from IPAddress and ConnectionType signals.
  std::unique_ptr<NetworkChangeCalculator> network_change_calculator_;

  // Set true to disable non-test notifications (to prevent flakes in tests).
  static bool test_notifications_only_;

  DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifier);
};

}  // namespace net

#endif  // NET_BASE_NETWORK_CHANGE_NOTIFIER_H_
