Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2012 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 #include "net/base/network_change_notifier_linux.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/compiler_specific.h"
      9 #include "base/threading/thread.h"
     10 #include "net/base/address_tracker_linux.h"
     11 #include "net/dns/dns_config_service.h"
     12 
     13 namespace net {
     14 
     15 class NetworkChangeNotifierLinux::Thread : public base::Thread {
     16  public:
     17   Thread();
     18   virtual ~Thread();
     19 
     20   // Plumbing for NetworkChangeNotifier::GetCurrentConnectionType.
     21   // Safe to call from any thread.
     22   NetworkChangeNotifier::ConnectionType GetCurrentConnectionType() {
     23     return address_tracker_.GetCurrentConnectionType();
     24   }
     25 
     26   const internal::AddressTrackerLinux* address_tracker() const {
     27     return &address_tracker_;
     28   }
     29 
     30  protected:
     31   // base::Thread
     32   virtual void Init() OVERRIDE;
     33   virtual void CleanUp() OVERRIDE;
     34 
     35  private:
     36   scoped_ptr<DnsConfigService> dns_config_service_;
     37   // Used to detect online/offline state and IP address changes.
     38   internal::AddressTrackerLinux address_tracker_;
     39 
     40   DISALLOW_COPY_AND_ASSIGN(Thread);
     41 };
     42 
     43 NetworkChangeNotifierLinux::Thread::Thread()
     44     : base::Thread("NetworkChangeNotifier"),
     45       address_tracker_(
     46           base::Bind(&NetworkChangeNotifier::
     47                      NotifyObserversOfIPAddressChange),
     48           base::Bind(&NetworkChangeNotifier::
     49                      NotifyObserversOfConnectionTypeChange),
     50           base::Bind(base::DoNothing)) {
     51 }
     52 
     53 NetworkChangeNotifierLinux::Thread::~Thread() {
     54   DCHECK(!Thread::IsRunning());
     55 }
     56 
     57 void NetworkChangeNotifierLinux::Thread::Init() {
     58   address_tracker_.Init();
     59   dns_config_service_ = DnsConfigService::CreateSystemService();
     60   dns_config_service_->WatchConfig(
     61       base::Bind(&NetworkChangeNotifier::SetDnsConfig));
     62 }
     63 
     64 void NetworkChangeNotifierLinux::Thread::CleanUp() {
     65   dns_config_service_.reset();
     66 }
     67 
     68 NetworkChangeNotifierLinux* NetworkChangeNotifierLinux::Create() {
     69   return new NetworkChangeNotifierLinux();
     70 }
     71 
     72 NetworkChangeNotifierLinux::NetworkChangeNotifierLinux()
     73     : NetworkChangeNotifier(NetworkChangeCalculatorParamsLinux()),
     74       notifier_thread_(new Thread()) {
     75   // We create this notifier thread because the notification implementation
     76   // needs a MessageLoopForIO, and there's no guarantee that
     77   // MessageLoop::current() meets that criterion.
     78   base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0);
     79   notifier_thread_->StartWithOptions(thread_options);
     80 }
     81 
     82 NetworkChangeNotifierLinux::~NetworkChangeNotifierLinux() {
     83   // Stopping from here allows us to sanity- check that the notifier
     84   // thread shut down properly.
     85   notifier_thread_->Stop();
     86 }
     87 
     88 // static
     89 NetworkChangeNotifier::NetworkChangeCalculatorParams
     90 NetworkChangeNotifierLinux::NetworkChangeCalculatorParamsLinux() {
     91   NetworkChangeCalculatorParams params;
     92   // Delay values arrived at by simple experimentation and adjusted so as to
     93   // produce a single signal when switching between network connections.
     94   params.ip_address_offline_delay_ = base::TimeDelta::FromMilliseconds(2000);
     95   params.ip_address_online_delay_ = base::TimeDelta::FromMilliseconds(2000);
     96   params.connection_type_offline_delay_ =
     97       base::TimeDelta::FromMilliseconds(1500);
     98   params.connection_type_online_delay_ = base::TimeDelta::FromMilliseconds(500);
     99   return params;
    100 }
    101 
    102 NetworkChangeNotifier::ConnectionType
    103 NetworkChangeNotifierLinux::GetCurrentConnectionType() const {
    104   return notifier_thread_->GetCurrentConnectionType();
    105 }
    106 
    107 const internal::AddressTrackerLinux*
    108 NetworkChangeNotifierLinux::GetAddressTrackerInternal() const {
    109   return notifier_thread_->address_tracker();
    110 }
    111 
    112 }  // namespace net
    113