| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/network_change_notifier_mac.h" | 5 #include "net/base/network_change_notifier_mac.h" |
| 6 | 6 |
| 7 #include <netinet/in.h> | 7 #include <netinet/in.h> |
| 8 #include <resolv.h> | 8 #include <resolv.h> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| 11 #include "base/threading/thread.h" | 11 #include "base/threading/thread.h" |
| 12 #include "net/dns/dns_config_watcher.h" | 12 #include "net/dns/dns_config_service.h" |
| 13 | |
| 14 #ifndef _PATH_RESCONF // Normally defined in <resolv.h> | |
| 15 #define _PATH_RESCONF "/etc/resolv.conf" | |
| 16 #endif | |
| 17 | 13 |
| 18 namespace net { | 14 namespace net { |
| 19 | 15 |
| 20 static bool CalculateReachability(SCNetworkConnectionFlags flags) { | 16 static bool CalculateReachability(SCNetworkConnectionFlags flags) { |
| 21 bool reachable = flags & kSCNetworkFlagsReachable; | 17 bool reachable = flags & kSCNetworkFlagsReachable; |
| 22 bool connection_required = flags & kSCNetworkFlagsConnectionRequired; | 18 bool connection_required = flags & kSCNetworkFlagsConnectionRequired; |
| 23 return reachable && !connection_required; | 19 return reachable && !connection_required; |
| 24 } | 20 } |
| 25 | 21 |
| 26 NetworkChangeNotifier::ConnectionType CalculateConnectionType( | 22 NetworkChangeNotifier::ConnectionType CalculateConnectionType( |
| 27 SCNetworkConnectionFlags flags) { | 23 SCNetworkConnectionFlags flags) { |
| 28 bool reachable = CalculateReachability(flags); | 24 bool reachable = CalculateReachability(flags); |
| 29 if (reachable) { | 25 if (reachable) { |
| 30 #if defined(OS_IOS) | 26 #if defined(OS_IOS) |
| 31 return (flags & kSCNetworkReachabilityFlagsIsWWAN) ? | 27 return (flags & kSCNetworkReachabilityFlagsIsWWAN) ? |
| 32 NetworkChangeNotifier::CONNECTION_3G : | 28 NetworkChangeNotifier::CONNECTION_3G : |
| 33 NetworkChangeNotifier::CONNECTION_WIFI; | 29 NetworkChangeNotifier::CONNECTION_WIFI; |
| 34 #else | 30 #else |
| 35 // TODO(droger): Get something more detailed than CONNECTION_UNKNOWN. | 31 // TODO(droger): Get something more detailed than CONNECTION_UNKNOWN. |
| 36 // http://crbug.com/112937 | 32 // http://crbug.com/112937 |
| 37 return NetworkChangeNotifier::CONNECTION_UNKNOWN; | 33 return NetworkChangeNotifier::CONNECTION_UNKNOWN; |
| 38 #endif // defined(OS_IOS) | 34 #endif // defined(OS_IOS) |
| 39 } else { | 35 } else { |
| 40 return NetworkChangeNotifier::CONNECTION_NONE; | 36 return NetworkChangeNotifier::CONNECTION_NONE; |
| 41 } | 37 } |
| 42 } | 38 } |
| 43 | 39 |
| 44 class NetworkChangeNotifierMac::DnsWatcherThread : public base::Thread { | 40 // Thread on which we can run DnsConfigService, which requires a TYPE_IO |
| 41 // message loop. |
| 42 class NetworkChangeNotifierMac::DnsConfigServiceThread : public base::Thread { |
| 45 public: | 43 public: |
| 46 DnsWatcherThread() : base::Thread("DnsWatcher") {} | 44 DnsConfigServiceThread() : base::Thread("DnsConfigService") {} |
| 47 | 45 |
| 48 virtual ~DnsWatcherThread() { | 46 virtual ~DnsConfigServiceThread() { |
| 49 Stop(); | 47 Stop(); |
| 50 } | 48 } |
| 51 | 49 |
| 52 virtual void Init() OVERRIDE { | 50 virtual void Init() OVERRIDE { |
| 53 watcher_.Init(); | 51 service_ = DnsConfigService::CreateSystemService(); |
| 52 service_->WatchConfig(base::Bind(&NetworkChangeNotifier::SetDnsConfig)); |
| 54 } | 53 } |
| 55 | 54 |
| 56 virtual void CleanUp() OVERRIDE { | 55 virtual void CleanUp() OVERRIDE { |
| 57 watcher_.CleanUp(); | 56 service_.reset(); |
| 58 } | 57 } |
| 59 | 58 |
| 60 private: | 59 private: |
| 61 internal::DnsConfigWatcher watcher_; | 60 scoped_ptr<DnsConfigService> service_; |
| 62 | 61 |
| 63 DISALLOW_COPY_AND_ASSIGN(DnsWatcherThread); | 62 DISALLOW_COPY_AND_ASSIGN(DnsConfigServiceThread); |
| 64 }; | 63 }; |
| 65 | 64 |
| 66 NetworkChangeNotifierMac::NetworkChangeNotifierMac() | 65 NetworkChangeNotifierMac::NetworkChangeNotifierMac() |
| 67 : connection_type_(CONNECTION_UNKNOWN), | 66 : connection_type_(CONNECTION_UNKNOWN), |
| 68 connection_type_initialized_(false), | 67 connection_type_initialized_(false), |
| 69 initial_connection_type_cv_(&connection_type_lock_), | 68 initial_connection_type_cv_(&connection_type_lock_), |
| 70 forwarder_(this), | 69 forwarder_(this), |
| 71 dns_watcher_thread_(new DnsWatcherThread()) { | 70 dns_config_service_thread_(new DnsConfigServiceThread()) { |
| 72 // Must be initialized after the rest of this object, as it may call back into | 71 // Must be initialized after the rest of this object, as it may call back into |
| 73 // SetInitialConnectionType(). | 72 // SetInitialConnectionType(). |
| 74 config_watcher_.reset(new NetworkConfigWatcherMac(&forwarder_)); | 73 config_watcher_.reset(new NetworkConfigWatcherMac(&forwarder_)); |
| 75 dns_watcher_thread_->StartWithOptions( | 74 dns_config_service_thread_->StartWithOptions( |
| 76 base::Thread::Options(MessageLoop::TYPE_IO, 0)); | 75 base::Thread::Options(MessageLoop::TYPE_IO, 0)); |
| 77 } | 76 } |
| 78 | 77 |
| 79 NetworkChangeNotifierMac::~NetworkChangeNotifierMac() { | 78 NetworkChangeNotifierMac::~NetworkChangeNotifierMac() { |
| 80 // Delete the ConfigWatcher to join the notifier thread, ensuring that | 79 // Delete the ConfigWatcher to join the notifier thread, ensuring that |
| 81 // StartReachabilityNotifications() has an opportunity to run to completion. | 80 // StartReachabilityNotifications() has an opportunity to run to completion. |
| 82 config_watcher_.reset(); | 81 config_watcher_.reset(); |
| 83 | 82 |
| 84 // Now that StartReachabilityNotifications() has either run to completion or | 83 // Now that StartReachabilityNotifications() has either run to completion or |
| 85 // never run at all, unschedule reachability_ if it was previously scheduled. | 84 // never run at all, unschedule reachability_ if it was previously scheduled. |
| 86 if (reachability_.get() && run_loop_.get()) { | 85 if (reachability_.get() && run_loop_.get()) { |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 | 249 |
| 251 #if defined(OS_IOS) | 250 #if defined(OS_IOS) |
| 252 // On iOS, the SCDynamicStore API does not exist, and we use the reachability | 251 // On iOS, the SCDynamicStore API does not exist, and we use the reachability |
| 253 // API to detect IP address changes instead. | 252 // API to detect IP address changes instead. |
| 254 if (new_type != CONNECTION_NONE) | 253 if (new_type != CONNECTION_NONE) |
| 255 NotifyObserversOfIPAddressChange(); | 254 NotifyObserversOfIPAddressChange(); |
| 256 #endif // defined(OS_IOS) | 255 #endif // defined(OS_IOS) |
| 257 } | 256 } |
| 258 | 257 |
| 259 } // namespace net | 258 } // namespace net |
| OLD | NEW |