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