Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Side by Side Diff: net/base/network_change_notifier_mac.cc

Issue 266243004: Clang format slam. Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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_service.h" 12 #include "net/dns/dns_config_service.h"
13 13
14 namespace net { 14 namespace net {
15 15
16 static bool CalculateReachability(SCNetworkConnectionFlags flags) { 16 static bool CalculateReachability(SCNetworkConnectionFlags flags) {
17 bool reachable = flags & kSCNetworkFlagsReachable; 17 bool reachable = flags & kSCNetworkFlagsReachable;
18 bool connection_required = flags & kSCNetworkFlagsConnectionRequired; 18 bool connection_required = flags & kSCNetworkFlagsConnectionRequired;
19 return reachable && !connection_required; 19 return reachable && !connection_required;
20 } 20 }
21 21
22 NetworkChangeNotifier::ConnectionType CalculateConnectionType( 22 NetworkChangeNotifier::ConnectionType CalculateConnectionType(
23 SCNetworkConnectionFlags flags) { 23 SCNetworkConnectionFlags flags) {
24 bool reachable = CalculateReachability(flags); 24 bool reachable = CalculateReachability(flags);
25 if (reachable) { 25 if (reachable) {
26 #if defined(OS_IOS) 26 #if defined(OS_IOS)
27 return (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 27 return (flags & kSCNetworkReachabilityFlagsIsWWAN)
28 NetworkChangeNotifier::CONNECTION_3G : 28 ? NetworkChangeNotifier::CONNECTION_3G
29 NetworkChangeNotifier::CONNECTION_WIFI; 29 : NetworkChangeNotifier::CONNECTION_WIFI;
30 #else 30 #else
31 // TODO(droger): Get something more detailed than CONNECTION_UNKNOWN. 31 // TODO(droger): Get something more detailed than CONNECTION_UNKNOWN.
32 // http://crbug.com/112937 32 // http://crbug.com/112937
33 return NetworkChangeNotifier::CONNECTION_UNKNOWN; 33 return NetworkChangeNotifier::CONNECTION_UNKNOWN;
34 #endif // defined(OS_IOS) 34 #endif // defined(OS_IOS)
35 } else { 35 } else {
36 return NetworkChangeNotifier::CONNECTION_NONE; 36 return NetworkChangeNotifier::CONNECTION_NONE;
37 } 37 }
38 } 38 }
39 39
40 // Thread on which we can run DnsConfigService, which requires a TYPE_IO 40 // Thread on which we can run DnsConfigService, which requires a TYPE_IO
41 // message loop. 41 // message loop.
42 class NetworkChangeNotifierMac::DnsConfigServiceThread : public base::Thread { 42 class NetworkChangeNotifierMac::DnsConfigServiceThread : public base::Thread {
43 public: 43 public:
44 DnsConfigServiceThread() : base::Thread("DnsConfigService") {} 44 DnsConfigServiceThread() : base::Thread("DnsConfigService") {}
45 45
46 virtual ~DnsConfigServiceThread() { 46 virtual ~DnsConfigServiceThread() { Stop(); }
47 Stop();
48 }
49 47
50 virtual void Init() OVERRIDE { 48 virtual void Init() OVERRIDE {
51 service_ = DnsConfigService::CreateSystemService(); 49 service_ = DnsConfigService::CreateSystemService();
52 service_->WatchConfig(base::Bind(&NetworkChangeNotifier::SetDnsConfig)); 50 service_->WatchConfig(base::Bind(&NetworkChangeNotifier::SetDnsConfig));
53 } 51 }
54 52
55 virtual void CleanUp() OVERRIDE { 53 virtual void CleanUp() OVERRIDE { service_.reset(); }
56 service_.reset();
57 }
58 54
59 private: 55 private:
60 scoped_ptr<DnsConfigService> service_; 56 scoped_ptr<DnsConfigService> service_;
61 57
62 DISALLOW_COPY_AND_ASSIGN(DnsConfigServiceThread); 58 DISALLOW_COPY_AND_ASSIGN(DnsConfigServiceThread);
63 }; 59 };
64 60
65 NetworkChangeNotifierMac::NetworkChangeNotifierMac() 61 NetworkChangeNotifierMac::NetworkChangeNotifierMac()
66 : NetworkChangeNotifier(NetworkChangeCalculatorParamsMac()), 62 : NetworkChangeNotifier(NetworkChangeCalculatorParamsMac()),
67 connection_type_(CONNECTION_UNKNOWN), 63 connection_type_(CONNECTION_UNKNOWN),
68 connection_type_initialized_(false), 64 connection_type_initialized_(false),
69 initial_connection_type_cv_(&connection_type_lock_), 65 initial_connection_type_cv_(&connection_type_lock_),
70 forwarder_(this), 66 forwarder_(this),
71 dns_config_service_thread_(new DnsConfigServiceThread()) { 67 dns_config_service_thread_(new DnsConfigServiceThread()) {
72 // Must be initialized after the rest of this object, as it may call back into 68 // Must be initialized after the rest of this object, as it may call back into
73 // SetInitialConnectionType(). 69 // SetInitialConnectionType().
74 config_watcher_.reset(new NetworkConfigWatcherMac(&forwarder_)); 70 config_watcher_.reset(new NetworkConfigWatcherMac(&forwarder_));
75 dns_config_service_thread_->StartWithOptions( 71 dns_config_service_thread_->StartWithOptions(
76 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); 72 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
77 } 73 }
78 74
79 NetworkChangeNotifierMac::~NetworkChangeNotifierMac() { 75 NetworkChangeNotifierMac::~NetworkChangeNotifierMac() {
80 // Delete the ConfigWatcher to join the notifier thread, ensuring that 76 // Delete the ConfigWatcher to join the notifier thread, ensuring that
81 // StartReachabilityNotifications() has an opportunity to run to completion. 77 // StartReachabilityNotifications() has an opportunity to run to completion.
82 config_watcher_.reset(); 78 config_watcher_.reset();
83 79
84 // Now that StartReachabilityNotifications() has either run to completion or 80 // Now that StartReachabilityNotifications() has either run to completion or
85 // never run at all, unschedule reachability_ if it was previously scheduled. 81 // never run at all, unschedule reachability_ if it was previously scheduled.
86 if (reachability_.get() && run_loop_.get()) { 82 if (reachability_.get() && run_loop_.get()) {
87 SCNetworkReachabilityUnscheduleFromRunLoop(reachability_.get(), 83 SCNetworkReachabilityUnscheduleFromRunLoop(
88 run_loop_.get(), 84 reachability_.get(), run_loop_.get(), kCFRunLoopCommonModes);
89 kCFRunLoopCommonModes);
90 } 85 }
91 } 86 }
92 87
93 // static 88 // static
94 NetworkChangeNotifier::NetworkChangeCalculatorParams 89 NetworkChangeNotifier::NetworkChangeCalculatorParams
95 NetworkChangeNotifierMac::NetworkChangeCalculatorParamsMac() { 90 NetworkChangeNotifierMac::NetworkChangeCalculatorParamsMac() {
96 NetworkChangeCalculatorParams params; 91 NetworkChangeCalculatorParams params;
97 // Delay values arrived at by simple experimentation and adjusted so as to 92 // Delay values arrived at by simple experimentation and adjusted so as to
98 // produce a single signal when switching between network connections. 93 // produce a single signal when switching between network connections.
99 params.ip_address_offline_delay_ = base::TimeDelta::FromMilliseconds(500); 94 params.ip_address_offline_delay_ = base::TimeDelta::FromMilliseconds(500);
100 params.ip_address_online_delay_ = base::TimeDelta::FromMilliseconds(500); 95 params.ip_address_online_delay_ = base::TimeDelta::FromMilliseconds(500);
101 params.connection_type_offline_delay_ = 96 params.connection_type_offline_delay_ =
102 base::TimeDelta::FromMilliseconds(1000); 97 base::TimeDelta::FromMilliseconds(1000);
103 params.connection_type_online_delay_ = base::TimeDelta::FromMilliseconds(500); 98 params.connection_type_online_delay_ = base::TimeDelta::FromMilliseconds(500);
104 return params; 99 return params;
105 } 100 }
106 101
107 NetworkChangeNotifier::ConnectionType 102 NetworkChangeNotifier::ConnectionType
108 NetworkChangeNotifierMac::GetCurrentConnectionType() const { 103 NetworkChangeNotifierMac::GetCurrentConnectionType() const {
109 base::AutoLock lock(connection_type_lock_); 104 base::AutoLock lock(connection_type_lock_);
110 // Make sure the initial connection type is set before returning. 105 // Make sure the initial connection type is set before returning.
111 while (!connection_type_initialized_) { 106 while (!connection_type_initialized_) {
112 initial_connection_type_cv_.Wait(); 107 initial_connection_type_cv_.Wait();
113 } 108 }
114 return connection_type_; 109 return connection_type_;
115 } 110 }
116 111
117 void NetworkChangeNotifierMac::Forwarder::Init() { 112 void NetworkChangeNotifierMac::Forwarder::Init() {
118 net_config_watcher_->SetInitialConnectionType(); 113 net_config_watcher_->SetInitialConnectionType();
119 } 114 }
120 115
121 void NetworkChangeNotifierMac::Forwarder::StartReachabilityNotifications() { 116 void NetworkChangeNotifierMac::Forwarder::StartReachabilityNotifications() {
122 net_config_watcher_->StartReachabilityNotifications(); 117 net_config_watcher_->StartReachabilityNotifications();
123 } 118 }
124 119
125 void NetworkChangeNotifierMac::Forwarder::SetDynamicStoreNotificationKeys( 120 void NetworkChangeNotifierMac::Forwarder::SetDynamicStoreNotificationKeys(
126 SCDynamicStoreRef store) { 121 SCDynamicStoreRef store) {
127 net_config_watcher_->SetDynamicStoreNotificationKeys(store); 122 net_config_watcher_->SetDynamicStoreNotificationKeys(store);
128 } 123 }
129 124
130 void NetworkChangeNotifierMac::Forwarder::OnNetworkConfigChange( 125 void NetworkChangeNotifierMac::Forwarder::OnNetworkConfigChange(
131 CFArrayRef changed_keys) { 126 CFArrayRef changed_keys) {
132 net_config_watcher_->OnNetworkConfigChange(changed_keys); 127 net_config_watcher_->OnNetworkConfigChange(changed_keys);
133 } 128 }
134 129
135 void NetworkChangeNotifierMac::SetInitialConnectionType() { 130 void NetworkChangeNotifierMac::SetInitialConnectionType() {
136 // Called on notifier thread. 131 // Called on notifier thread.
137 132
138 // Try to reach 0.0.0.0. This is the approach taken by Firefox: 133 // Try to reach 0.0.0.0. This is the approach taken by Firefox:
139 // 134 //
140 // http://mxr.mozilla.org/mozilla2.0/source/netwerk/system/mac/nsNetworkLinkSe rvice.mm 135 // http://mxr.mozilla.org/mozilla2.0/source/netwerk/system/mac/nsNetworkLinkSe rvice.mm
141 // 136 //
(...skipping 21 matching lines...) Expand all
163 } 158 }
164 } 159 }
165 160
166 void NetworkChangeNotifierMac::StartReachabilityNotifications() { 161 void NetworkChangeNotifierMac::StartReachabilityNotifications() {
167 // Called on notifier thread. 162 // Called on notifier thread.
168 run_loop_.reset(CFRunLoopGetCurrent()); 163 run_loop_.reset(CFRunLoopGetCurrent());
169 CFRetain(run_loop_.get()); 164 CFRetain(run_loop_.get());
170 165
171 DCHECK(reachability_); 166 DCHECK(reachability_);
172 SCNetworkReachabilityContext reachability_context = { 167 SCNetworkReachabilityContext reachability_context = {
173 0, // version 168 0, // version
174 this, // user data 169 this, // user data
175 NULL, // retain 170 NULL, // retain
176 NULL, // release 171 NULL, // release
177 NULL // description 172 NULL // description
178 }; 173 };
179 if (!SCNetworkReachabilitySetCallback( 174 if (!SCNetworkReachabilitySetCallback(
180 reachability_, 175 reachability_,
181 &NetworkChangeNotifierMac::ReachabilityCallback, 176 &NetworkChangeNotifierMac::ReachabilityCallback,
182 &reachability_context)) { 177 &reachability_context)) {
183 LOG(DFATAL) << "Could not set network reachability callback"; 178 LOG(DFATAL) << "Could not set network reachability callback";
184 reachability_.reset(); 179 reachability_.reset();
185 } else if (!SCNetworkReachabilityScheduleWithRunLoop(reachability_, 180 } else if (!SCNetworkReachabilityScheduleWithRunLoop(
186 run_loop_, 181 reachability_, run_loop_, kCFRunLoopCommonModes)) {
187 kCFRunLoopCommonModes)) {
188 LOG(DFATAL) << "Could not schedule network reachability on run loop"; 182 LOG(DFATAL) << "Could not schedule network reachability on run loop";
189 reachability_.reset(); 183 reachability_.reset();
190 } 184 }
191 } 185 }
192 186
193 void NetworkChangeNotifierMac::SetDynamicStoreNotificationKeys( 187 void NetworkChangeNotifierMac::SetDynamicStoreNotificationKeys(
194 SCDynamicStoreRef store) { 188 SCDynamicStoreRef store) {
195 #if defined(OS_IOS) 189 #if defined(OS_IOS)
196 // SCDynamicStore API does not exist on iOS. 190 // SCDynamicStore API does not exist on iOS.
197 NOTREACHED(); 191 NOTREACHED();
198 #else 192 #else
199 base::ScopedCFTypeRef<CFMutableArrayRef> notification_keys( 193 base::ScopedCFTypeRef<CFMutableArrayRef> notification_keys(
200 CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); 194 CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks));
201 base::ScopedCFTypeRef<CFStringRef> key( 195 base::ScopedCFTypeRef<CFStringRef> key(
202 SCDynamicStoreKeyCreateNetworkGlobalEntity( 196 SCDynamicStoreKeyCreateNetworkGlobalEntity(
203 NULL, kSCDynamicStoreDomainState, kSCEntNetInterface)); 197 NULL, kSCDynamicStoreDomainState, kSCEntNetInterface));
204 CFArrayAppendValue(notification_keys.get(), key.get()); 198 CFArrayAppendValue(notification_keys.get(), key.get());
205 key.reset(SCDynamicStoreKeyCreateNetworkGlobalEntity( 199 key.reset(SCDynamicStoreKeyCreateNetworkGlobalEntity(
206 NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4)); 200 NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4));
207 CFArrayAppendValue(notification_keys.get(), key.get()); 201 CFArrayAppendValue(notification_keys.get(), key.get());
208 key.reset(SCDynamicStoreKeyCreateNetworkGlobalEntity( 202 key.reset(SCDynamicStoreKeyCreateNetworkGlobalEntity(
209 NULL, kSCDynamicStoreDomainState, kSCEntNetIPv6)); 203 NULL, kSCDynamicStoreDomainState, kSCEntNetIPv6));
210 CFArrayAppendValue(notification_keys.get(), key.get()); 204 CFArrayAppendValue(notification_keys.get(), key.get());
211 205
212 // Set the notification keys. This starts us receiving notifications. 206 // Set the notification keys. This starts us receiving notifications.
213 bool ret = SCDynamicStoreSetNotificationKeys( 207 bool ret =
214 store, notification_keys.get(), NULL); 208 SCDynamicStoreSetNotificationKeys(store, notification_keys.get(), NULL);
215 // TODO(willchan): Figure out a proper way to handle this rather than crash. 209 // TODO(willchan): Figure out a proper way to handle this rather than crash.
216 CHECK(ret); 210 CHECK(ret);
217 #endif // defined(OS_IOS) 211 #endif // defined(OS_IOS)
218 } 212 }
219 213
220 void NetworkChangeNotifierMac::OnNetworkConfigChange(CFArrayRef changed_keys) { 214 void NetworkChangeNotifierMac::OnNetworkConfigChange(CFArrayRef changed_keys) {
221 #if defined(OS_IOS) 215 #if defined(OS_IOS)
222 // SCDynamicStore API does not exist on iOS. 216 // SCDynamicStore API does not exist on iOS.
223 NOTREACHED(); 217 NOTREACHED();
224 #else 218 #else
225 DCHECK_EQ(run_loop_.get(), CFRunLoopGetCurrent()); 219 DCHECK_EQ(run_loop_.get(), CFRunLoopGetCurrent());
226 220
227 for (CFIndex i = 0; i < CFArrayGetCount(changed_keys); ++i) { 221 for (CFIndex i = 0; i < CFArrayGetCount(changed_keys); ++i) {
228 CFStringRef key = static_cast<CFStringRef>( 222 CFStringRef key =
229 CFArrayGetValueAtIndex(changed_keys, i)); 223 static_cast<CFStringRef>(CFArrayGetValueAtIndex(changed_keys, i));
230 if (CFStringHasSuffix(key, kSCEntNetIPv4) || 224 if (CFStringHasSuffix(key, kSCEntNetIPv4) ||
231 CFStringHasSuffix(key, kSCEntNetIPv6)) { 225 CFStringHasSuffix(key, kSCEntNetIPv6)) {
232 NotifyObserversOfIPAddressChange(); 226 NotifyObserversOfIPAddressChange();
233 return; 227 return;
234 } 228 }
235 if (CFStringHasSuffix(key, kSCEntNetInterface)) { 229 if (CFStringHasSuffix(key, kSCEntNetInterface)) {
236 // TODO(willchan): Does not appear to be working. Look into this. 230 // TODO(willchan): Does not appear to be working. Look into this.
237 // Perhaps this isn't needed anyway. 231 // Perhaps this isn't needed anyway.
238 } else { 232 } else {
239 NOTREACHED(); 233 NOTREACHED();
(...skipping 23 matching lines...) Expand all
263 NotifyObserversOfConnectionTypeChange(); 257 NotifyObserversOfConnectionTypeChange();
264 258
265 #if defined(OS_IOS) 259 #if defined(OS_IOS)
266 // On iOS, the SCDynamicStore API does not exist, and we use the reachability 260 // On iOS, the SCDynamicStore API does not exist, and we use the reachability
267 // API to detect IP address changes instead. 261 // API to detect IP address changes instead.
268 NotifyObserversOfIPAddressChange(); 262 NotifyObserversOfIPAddressChange();
269 #endif // defined(OS_IOS) 263 #endif // defined(OS_IOS)
270 } 264 }
271 265
272 } // namespace net 266 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698