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 }
     51 
     52 NetworkChangeNotifierLinux::Thread::~Thread() {
     53   DCHECK(!Thread::IsRunning());
     54 }
     55 
     56 void NetworkChangeNotifierLinux::Thread::Init() {
     57   address_tracker_.Init();
     58   dns_config_service_ = DnsConfigService::CreateSystemService();
     59   dns_config_service_->WatchConfig(
     60       base::Bind(&NetworkChangeNotifier::SetDnsConfig));
     61 }
     62 
     63 void NetworkChangeNotifierLinux::Thread::CleanUp() {
     64   dns_config_service_.reset();
     65 }
     66 
     67 NetworkChangeNotifierLinux* NetworkChangeNotifierLinux::Create() {
     68   return new NetworkChangeNotifierLinux();
     69 }
     70 
     71 NetworkChangeNotifierLinux::NetworkChangeNotifierLinux()
     72     : NetworkChangeNotifier(NetworkChangeCalculatorParamsLinux()),
     73       notifier_thread_(new Thread()) {
     74   // We create this notifier thread because the notification implementation
     75   // needs a MessageLoopForIO, and there's no guarantee that
     76   // MessageLoop::current() meets that criterion.
     77   base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0);
     78   notifier_thread_->StartWithOptions(thread_options);
     79 }
     80 
     81 NetworkChangeNotifierLinux::~NetworkChangeNotifierLinux() {
     82   // Stopping from here allows us to sanity- check that the notifier
     83   // thread shut down properly.
     84   notifier_thread_->Stop();
     85 }
     86 
     87 // static
     88 NetworkChangeNotifier::NetworkChangeCalculatorParams
     89 NetworkChangeNotifierLinux::NetworkChangeCalculatorParamsLinux() {
     90   NetworkChangeCalculatorParams params;
     91   // Delay values arrived at by simple experimentation and adjusted so as to
     92   // produce a single signal when switching between network connections.
     93   params.ip_address_offline_delay_ = base::TimeDelta::FromMilliseconds(2000);
     94   params.ip_address_online_delay_ = base::TimeDelta::FromMilliseconds(2000);
     95   params.connection_type_offline_delay_ =
     96       base::TimeDelta::FromMilliseconds(1500);
     97   params.connection_type_online_delay_ = base::TimeDelta::FromMilliseconds(500);
     98   return params;
     99 }
    100 
    101 NetworkChangeNotifier::ConnectionType
    102 NetworkChangeNotifierLinux::GetCurrentConnectionType() const {
    103   return notifier_thread_->GetCurrentConnectionType();
    104 }
    105 
    106 const internal::AddressTrackerLinux*
    107 NetworkChangeNotifierLinux::GetAddressTrackerInternal() const {
    108   return notifier_thread_->address_tracker();
    109 }
    110 
    111 }  // namespace net
    112