Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
      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 #pragma once
      8 
      9 #include "base/basictypes.h"
     10 #include "base/observer_list_threadsafe.h"
     11 #include "net/base/net_export.h"
     12 
     13 namespace net {
     14 
     15 // NetworkChangeNotifier monitors the system for network changes, and notifies
     16 // registered observers of those events.  Observers may register on any thread,
     17 // and will be called back on the thread from which they registered.
     18 class NET_EXPORT NetworkChangeNotifier {
     19  public:
     20   class NET_EXPORT IPAddressObserver {
     21    public:
     22     virtual ~IPAddressObserver() {}
     23 
     24     // Will be called when the IP address of the primary interface changes.
     25     // This includes when the primary interface itself changes.
     26     virtual void OnIPAddressChanged() = 0;
     27 
     28    protected:
     29     IPAddressObserver() {}
     30 
     31    private:
     32     DISALLOW_COPY_AND_ASSIGN(IPAddressObserver);
     33   };
     34 
     35   class NET_EXPORT OnlineStateObserver {
     36    public:
     37     virtual ~OnlineStateObserver() {}
     38 
     39     // Will be called when the online state of the system may have changed.
     40     // See NetworkChangeNotifier::IsOffline() for important caveats about
     41     // the unreliability of this signal.
     42     virtual void OnOnlineStateChanged(bool online) = 0;
     43 
     44    protected:
     45     OnlineStateObserver() {}
     46 
     47    private:
     48     DISALLOW_COPY_AND_ASSIGN(OnlineStateObserver);
     49   };
     50 
     51   virtual ~NetworkChangeNotifier();
     52 
     53   // See the description of NetworkChangeNotifier::IsOffline().
     54   // Implementations must be thread-safe. Implementations must also be
     55   // cheap as this could be called (repeatedly) from the IO thread.
     56   virtual bool IsCurrentlyOffline() const = 0;
     57 
     58   // Creates the process-wide, platform-specific NetworkChangeNotifier.  The
     59   // caller owns the returned pointer.  You may call this on any thread.  You
     60   // may also avoid creating this entirely (in which case nothing will be
     61   // monitored), but if you do create it, you must do so before any other
     62   // threads try to access the API below, and it must outlive all other threads
     63   // which might try to use it.
     64   static NetworkChangeNotifier* Create();
     65 
     66   // Returns true if there is currently no internet connection.
     67   //
     68   // A return value of |true| is a pretty strong indicator that the user
     69   // won't be able to connect to remote sites. However, a return value of
     70   // |false| is inconclusive; even if some link is up, it is uncertain
     71   // whether a particular connection attempt to a particular remote site
     72   // will be successfully.
     73   static bool IsOffline();
     74 
     75   // Like Create(), but for use in tests.  The mock object doesn't monitor any
     76   // events, it merely rebroadcasts notifications when requested.
     77   static NetworkChangeNotifier* CreateMock();
     78 
     79   // Registers |observer| to receive notifications of network changes.  The
     80   // thread on which this is called is the thread on which |observer| will be
     81   // called back with notifications.  This is safe to call if Create() has not
     82   // been called (as long as it doesn't race the Create() call on another
     83   // thread), in which case it will simply do nothing.
     84   static void AddIPAddressObserver(IPAddressObserver* observer);
     85   static void AddOnlineStateObserver(OnlineStateObserver* observer);
     86 
     87   // Unregisters |observer| from receiving notifications.  This must be called
     88   // on the same thread on which AddObserver() was called.  Like AddObserver(),
     89   // this is safe to call if Create() has not been called (as long as it doesn't
     90   // race the Create() call on another thread), in which case it will simply do
     91   // nothing.  Technically, it's also safe to call after the notifier object has
     92   // been destroyed, if the call doesn't race the notifier's destruction, but
     93   // there's no reason to use the API in this risky way, so don't do it.
     94   static void RemoveIPAddressObserver(IPAddressObserver* observer);
     95   static void RemoveOnlineStateObserver(OnlineStateObserver* observer);
     96 
     97 #ifdef UNIT_TEST
     98   // Allow unit tests to trigger notifications.
     99   static void NotifyObserversOfIPAddressChangeForTests() {
    100     NotifyObserversOfIPAddressChange();
    101   }
    102 #endif
    103 
    104  protected:
    105   NetworkChangeNotifier();
    106 
    107   // Broadcasts a notification to all registered observers.  Note that this
    108   // happens asynchronously, even for observers on the current thread, even in
    109   // tests.
    110   static void NotifyObserversOfIPAddressChange();
    111   void NotifyObserversOfOnlineStateChange();
    112 
    113  private:
    114   const scoped_refptr<ObserverListThreadSafe<IPAddressObserver> >
    115       ip_address_observer_list_;
    116   const scoped_refptr<ObserverListThreadSafe<OnlineStateObserver> >
    117       online_state_observer_list_;
    118 
    119   DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifier);
    120 };
    121 
    122 }  // namespace net
    123 
    124 #endif  // NET_BASE_NETWORK_CHANGE_NOTIFIER_H_
    125