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