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

Side by Side Diff: components/wifi/wifi_service_mac.mm

Issue 64683014: Mac OS X-specific implementation of Networking Private API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address codereview comments. Created 6 years, 11 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
« no previous file with comments | « components/wifi/wifi_service.cc ('k') | components/wifi/wifi_service_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
tbarzic 2014/01/08 23:06:23 the copyright header is out of date :P
mef 2014/01/09 22:41:46 Done.
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 "components/wifi/wifi_service.h"
6
7 #import <netinet/in.h>
8 #import <CoreWLAN/CoreWLAN.h>
9 #import <SystemConfiguration/SystemConfiguration.h>
10
11 #include "base/bind.h"
12 #include "base/mac/scoped_cftyperef.h"
13 #include "base/mac/scoped_nsautorelease_pool.h"
14 #include "base/mac/scoped_nsobject.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/strings/sys_string_conversions.h"
17 #include "components/onc/onc_constants.h"
18
19 namespace {
20 // Declare notification names from the 10.7 SDK.
21 const char* kCWSSIDDidChangeNotification_chrome =
22 "com.apple.coreWLAN.notification.ssid";
23 } // namespace
24
25 #if !defined(MAC_OS_X_VERSION_10_7) || \
26 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
27
28 // Local definitions of API added in Mac OS X 10.7
29
30 @interface CWInterface (LionAPI)
31 - (BOOL)associateToNetwork:(CWNetwork*)network
32 password:(NSString*)password
33 error:(NSError**)error;
34 - (NSSet*)scanForNetworksWithName:(NSString*)networkName
35 error:(NSError**)error;
36 @end
37
38 enum CWChannelBand {
39 kCWChannelBandUnknown = 0,
40 kCWChannelBand2GHz = 1,
41 kCWChannelBand5GHz = 2,
42 };
43
44 @interface CWChannel : NSObject
45 @property(readonly) CWChannelBand channelBand;
46 @end
47
48 @interface CWNetwork (LionAPI)
49 @property(readonly) CWChannel* wlanChannel;
50 @end
51
52 #endif // 10.7
53
54 namespace wifi {
55
56 const char kErrorAssociateToNetwork[] = "Error.AssociateToNetwork";
57 const char kErrorGetProperties[] = "Error.GetProperties";
58 const char kErrorNotConnected[] = "Error.NotConnected";
59 const char kErrorNotFound[] = "Error.NotFound";
60 const char kErrorNotImplemented[] = "Error.NotImplemented";
61 const char kErrorScanForNetworksWithName[] = "Error.ScanForNetworksWithName";
62
63 // Implementation of WiFiService for Mac OS X.
64 class WiFiServiceMac : public WiFiService {
65 public:
66 WiFiServiceMac();
67 virtual ~WiFiServiceMac();
68
69 // WiFiService interface implementation.
70 virtual void Initialize(
71 scoped_refptr<base::SequencedTaskRunner> task_runner) OVERRIDE;
72
73 virtual void UnInitialize() OVERRIDE;
74
75 virtual void GetProperties(const std::string& network_guid,
76 base::DictionaryValue* properties,
77 std::string* error) OVERRIDE;
78
79 virtual void GetManagedProperties(const std::string& network_guid,
80 base::DictionaryValue* managed_properties,
81 std::string* error) OVERRIDE;
82
83 virtual void GetState(const std::string& network_guid,
84 base::DictionaryValue* properties,
85 std::string* error) OVERRIDE;
86
87 virtual void SetProperties(const std::string& network_guid,
88 scoped_ptr<base::DictionaryValue> properties,
89 std::string* error) OVERRIDE;
90
91 virtual void CreateNetwork(bool shared,
92 scoped_ptr<base::DictionaryValue> properties,
93 std::string* network_guid,
94 std::string* error) OVERRIDE;
95
96 virtual void GetVisibleNetworks(const std::string& network_type,
97 base::ListValue* network_list) OVERRIDE;
98
99 virtual void RequestNetworkScan() OVERRIDE;
100
101 virtual void StartConnect(const std::string& network_guid,
102 std::string* error) OVERRIDE;
103
104 virtual void StartDisconnect(const std::string& network_guid,
105 std::string* error) OVERRIDE;
106
107 virtual void SetEventObservers(
108 scoped_refptr<base::MessageLoopProxy> message_loop_proxy,
109 const NetworkGuidListCallback& networks_changed_observer,
110 const NetworkGuidListCallback& network_list_changed_observer) OVERRIDE;
111
112 private:
113 // Check |ns_error| and if is not |nil|, then store |error_name|
114 // into |error|.
115 bool CheckError(NSError* ns_error,
116 const char* error_name,
117 std::string* error) const;
118
119 // Get |ssid| from unique |network_guid|.
120 NSString* SSIDFromGUID(const std::string& network_guid) const {
121 return base::SysUTF8ToNSString(network_guid);
122 }
123
124 // Get unique |network_guid| string based on |ssid|.
125 std::string GUIDFromSSID(NSString* ssid) const {
126 return base::SysNSStringToUTF8(ssid);
127 }
128
129 // Populate |properties| from |network|.
130 void NetworkPropertiesFromCWNetwork(const CWNetwork* network,
131 NetworkProperties* properties) const;
132
133 // Convert |CWSecurityMode| into onc::wifi::k{WPA|WEP}* security constant.
134 std::string SecurityFromCWSecurityMode(CWSecurityMode security) const;
135
136 // Wait up to |kMaxAttempts| with |kAttemptDelayMs| delay for connection
137 // to network with |network_guid|. Notify that |NetworkChanged| upon success.
138 void WaitForNetworkConnect(const std::string& network_guid, int attempt);
139
140 // Get the list of visible wireless networks. If |network_guid| is not empty,
141 // then only return that network.
142 NSError* GetVisibleNetworkList(const std::string& network_guid,
143 NetworkList* network_list);
144
145 // Handle notification from |wlan_observer_|;
tbarzic 2014/01/08 23:06:23 end comment with . instead of ; Here and througho
mef 2014/01/09 22:41:46 Done.
146 void OnWlanObserverNotification();
147
148 // Notify |network_list_changed_observer_| that list of visible networks has
149 // changed to |networks|.
150 void NotifyNetworkListChanged(const NetworkList& networks);
151
152 // Notify |networks_changed_observer_| that network |network_guid| status has
153 // changed.
154 void NotifyNetworkChanged(const std::string& network_guid);
155
156 // CoreWLAN.Framework bundle.
157 base::scoped_nsobject<NSBundle> bundle_;
158 // Default interface.
159 base::scoped_nsobject<CWInterface> interface_;
160 // WLAN Notifications observer.
161 base::scoped_nsobject<NSObject> wlan_observer_;
162
163 // Observer to get notified when network(s) have changed (e.g. connect).
164 NetworkGuidListCallback networks_changed_observer_;
165 // Observer to get notified when network list has changed (scan complete).
166 NetworkGuidListCallback network_list_changed_observer_;
167 // MessageLoopProxy to post events on UI thread.
168 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
169 // Task runner for worker tasks.
170 scoped_refptr<base::SequencedTaskRunner> task_runner_;
171 // Cache of network list collected by GetVisibleNetworks.
172 NetworkList networks_;
173 // Temporary storage of network properties indexed by |network_guid|.
174 base::DictionaryValue network_properties_;
175 // If |false|, then |networks_changed_observer_| is not notified.
176 bool enable_notify_network_changed_;
177 // Number of attempts to check that network has connected successfully.
178 static const int kConnectionCheckMaxAttempts = 200;
179 // Delay between attempts to check that network has connected successfully.
180 static const int kConnectionCheckAttemptDelayMs = 100;
181 };
182
183 WiFiServiceMac::WiFiServiceMac() : enable_notify_network_changed_(true) {
184 }
185
186 WiFiServiceMac::~WiFiServiceMac() {
187 }
188
189 void WiFiServiceMac::Initialize(
190 scoped_refptr<base::SequencedTaskRunner> task_runner) {
191 // As the WLAN api binding runs on its own thread, we need to provide our own
192 // auto release pool. It's simplest to do this as an automatic variable in
193 // each method that needs it, to ensure the scoping is correct and does not
194 // interfere with any other code using autorelease pools on the thread.
195 base::mac::ScopedNSAutoreleasePool auto_pool;
196
197 task_runner_.swap(task_runner);
198
199 bundle_.reset([[NSBundle alloc]
200 initWithPath:@"/System/Library/Frameworks/CoreWLAN.framework"]);
201 if (!bundle_) {
202 DVLOG(1) << "Failed to load the CoreWLAN framework bundle";
203 return;
204 }
205
206 Class cw_interface_class = [bundle_ classNamed:@"CWInterface"];
207 interface_.reset([[cw_interface_class interface] retain]);
208 if (!bundle_) {
209 DVLOG(1) << "Failed to initialize default interface";
210 return;
211 }
212
213 }
214
215 void WiFiServiceMac::UnInitialize() {
216 [[NSNotificationCenter defaultCenter] removeObserver:wlan_observer_];
217 }
218
219 void WiFiServiceMac::GetProperties(const std::string& network_guid,
220 base::DictionaryValue* properties,
221 std::string* error) {
222 base::mac::ScopedNSAutoreleasePool auto_pool;
223
224 if (networks_.empty()) {
tbarzic 2014/01/08 23:06:23 I don't think this block is needed (at least if Re
mef 2014/01/09 22:41:46 Done.
225 DVLOG(1) << "GetProperties";
226 NSError* ns_error = GetVisibleNetworkList(std::string(), &networks_);
227 if (CheckError(ns_error, kErrorGetProperties, error))
228 return;
229 }
230
231 for (WiFiService::NetworkList::iterator it = networks_.begin();
232 it != networks_.end();
233 ++it) {
234 if (it->guid == network_guid) {
tbarzic 2014/01/08 23:06:23 the network's properties should probably be rescan
mef 2014/01/09 22:41:46 Done.
235 bool is_connected = network_guid == GUIDFromSSID([interface_ ssid]);
236 it->connection_state =
237 is_connected ? onc::connection_state::kConnected :
238 onc::connection_state::kNotConnected;
239 scoped_ptr<base::DictionaryValue> network(it->ToValue(false));
240 properties->Swap(network.get());
241 DVLOG(1) << *properties;
242 return;
243 }
244 }
245
246 *error = kErrorNotFound;
247 }
248
249 void WiFiServiceMac::GetManagedProperties(
250 const std::string& network_guid,
251 base::DictionaryValue* managed_properties,
252 std::string* error) {
253 *error = kErrorNotImplemented;
254 }
255
256 void WiFiServiceMac::GetState(const std::string& network_guid,
257 base::DictionaryValue* properties,
258 std::string* error) {
259 *error = kErrorNotImplemented;
260 }
261
262 void WiFiServiceMac::SetProperties(
263 const std::string& network_guid,
264 scoped_ptr<base::DictionaryValue> properties,
265 std::string* error) {
266 base::mac::ScopedNSAutoreleasePool auto_pool;
267 network_properties_.SetWithoutPathExpansion(network_guid,
268 properties.release());
269 }
270
271 void WiFiServiceMac::CreateNetwork(
272 bool shared,
273 scoped_ptr<base::DictionaryValue> properties,
274 std::string* network_guid,
275 std::string* error) {
276 *error = kErrorNotImplemented;
277 }
278
279 void WiFiServiceMac::GetVisibleNetworks(const std::string& network_type,
280 base::ListValue* network_list) {
281 if (!network_type.empty() &&
282 network_type != onc::network_type::kAllTypes &&
283 network_type != onc::network_type::kWiFi) {
284 return;
285 }
286
287 base::mac::ScopedNSAutoreleasePool auto_pool;
288
289 GetVisibleNetworkList(std::string(), &networks_);
290
291 // Sort networks, so connected/connecting is up front.
292 networks_.sort(NetworkProperties::OrderByType);
293
294 for (WiFiService::NetworkList::const_iterator it = networks_.begin();
295 it != networks_.end();
296 ++it) {
297 scoped_ptr<base::DictionaryValue> network(it->ToValue(true));
298 network_list->Append(network.release());
299 }
300 }
301
302 void WiFiServiceMac::RequestNetworkScan() {
303 base::mac::ScopedNSAutoreleasePool auto_pool;
304 NetworkList networks;
305
306 NSError* ns_error = GetVisibleNetworkList(std::string(), &networks);
307 if (ns_error == nil && !networks.empty()) {
308 NotifyNetworkListChanged(networks);
309 }
310 }
311
312 void WiFiServiceMac::StartConnect(const std::string& network_guid,
313 std::string* error) {
314 base::mac::ScopedNSAutoreleasePool auto_pool;
315 NSError* ns_error = nil;
316
317 DVLOG(1) << "*** StartConnect: " << network_guid;
318 // Remember previously connected network.
319 std::string connected_network_guid = GUIDFromSSID([interface_ ssid]);
320 // Check, whether desired network is already connected.
321 if (network_guid == connected_network_guid) {
322 NotifyNetworkChanged(connected_network_guid);
323 return;
324 }
325
326 NSSet* networks = [interface_
327 scanForNetworksWithName:SSIDFromGUID(network_guid)
328 error:&ns_error];
329
330 if (CheckError(ns_error, kErrorScanForNetworksWithName, error))
331 return;
332
333 CWNetwork* network = [networks anyObject];
334 if (network == nil) {
335 *error = kErrorNotFound;
336 return;
337 }
338
339 // Check whether WiFi Password is set in |network_properties_|
340 base::DictionaryValue* properties;
341 base::DictionaryValue* wifi;
342 std::string passphrase;
343 NSString* ns_password = nil;
344 if (network_properties_.GetDictionaryWithoutPathExpansion(network_guid,
345 &properties) &&
346 properties->GetDictionary(onc::network_type::kWiFi, &wifi) &&
347 wifi->GetString(onc::wifi::kPassphrase, &passphrase)) {
348 ns_password = base::SysUTF8ToNSString(passphrase);
349 }
350
351 // Disable automatic network change notifications as they get fired
352 // when network is just connected, but not yet accessible (doesn't
353 // have valid IP address).
354 enable_notify_network_changed_ = false;
355 // Number of attempts to associate to network.
356 static const int kMaxAssociationAttempts = 3;
357 // Try to associate to network several times if timeout or PMK error occurs.
358 for (int i = 0; i < kMaxAssociationAttempts; ++i) {
359 // Nil out the PMK to prevent stale data from causing invalid PMK error
360 // (CoreWLANTypes -3924).
361 [interface_ setPairwiseMasterKey:nil error:&ns_error];
362 if ([interface_ associateToNetwork:network
363 password:ns_password
364 error:&ns_error]) {
365 // Notify that previously connected network has changed.
366 NotifyNetworkChanged(connected_network_guid);
367
368 // Start waiting for network connection state change. WaiForNetworkConnect
369 // is async and it'll reset enable_notify_network_changed_.
370 if (!networks_changed_observer_.is_null()) {
371 WaitForNetworkConnect(network_guid, 0);
372 return;
373 }
374 } else {
375 NSInteger error_code = [ns_error code];
376 if (error_code != kCWTimeoutErr && error_code != kCWInvalidPMKErr) {
377 break;
378 }
379 }
380 }
381 enable_notify_network_changed_ = true;
382 CheckError(ns_error, kErrorAssociateToNetwork, error);
383 }
384
385 void WiFiServiceMac::StartDisconnect(const std::string& network_guid,
386 std::string* error) {
387 base::mac::ScopedNSAutoreleasePool auto_pool;
388 DVLOG(1) << "*** StartDisconnect: " << network_guid;
389
390 if (network_guid == GUIDFromSSID([interface_ ssid])) {
391 [interface_ disassociate];
392 } else {
393 *error = kErrorNotConnected;
394 }
395 }
396
397 void WiFiServiceMac::SetEventObservers(
398 scoped_refptr<base::MessageLoopProxy> message_loop_proxy,
399 const NetworkGuidListCallback& networks_changed_observer,
400 const NetworkGuidListCallback& network_list_changed_observer) {
401 base::mac::ScopedNSAutoreleasePool auto_pool;
402 message_loop_proxy_.swap(message_loop_proxy);
403 networks_changed_observer_ = networks_changed_observer;
404 network_list_changed_observer_ = network_list_changed_observer;
405
406 // Subscribe to OS notifications.
407 wlan_observer_.reset([[NSNotificationCenter defaultCenter]
408 addObserverForName:base::SysUTF8ToNSString(
409 kCWSSIDDidChangeNotification_chrome)
410 object:nil
411 queue:nil
412 usingBlock:^(NSNotification* notification) {
413 task_runner_->PostTask(
414 FROM_HERE,
415 base::Bind(&WiFiServiceMac::OnWlanObserverNotification,
416 base::Unretained(this)));
417 }]);
418 }
419
420 void WiFiServiceMac::WaitForNetworkConnect(const std::string& network_guid,
421 int attempt) {
422 // If network didn't get connected in |kMaxAttempts|, then restore automatic
423 // network change notifications and stop waiting.
424 if (attempt > kConnectionCheckMaxAttempts) {
425 DLOG(ERROR) << kConnectionCheckMaxAttempts
426 << " attempts exceeded waiting for connect to "
427 << network_guid;
428 // Restore previously suppressed notifications.
429 enable_notify_network_changed_ = true;
430 return;
431 }
432
433 // Check whether WiFi network is reachable.
434 struct sockaddr_in local_wifi_address;
435 bzero(&local_wifi_address, sizeof(local_wifi_address));
436 local_wifi_address.sin_len = sizeof(local_wifi_address);
437 local_wifi_address.sin_family = AF_INET;
438 local_wifi_address.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);
439
440 base::ScopedCFTypeRef<SCNetworkReachabilityRef> reachability(
441 SCNetworkReachabilityCreateWithAddress(
442 kCFAllocatorDefault,
443 reinterpret_cast<const struct sockaddr*>(&local_wifi_address)));
444 SCNetworkReachabilityFlags flags = 0u;
445 if (SCNetworkReachabilityGetFlags(reachability, &flags) &&
446 (flags & kSCNetworkReachabilityFlagsReachable) &&
447 (flags & kSCNetworkReachabilityFlagsIsDirect)) {
448 DVLOG(1) << "WiFi Connected, Reachable: " << network_guid;
449 // Restore previously suppressed notifications.
450 enable_notify_network_changed_ = true;
451 NotifyNetworkChanged(network_guid);
452 } else {
453 DVLOG(1) << "Attempt:" << attempt << ", reachability:" << flags;
454 // Continue waiting for network connection state change.
455 task_runner_->PostDelayedTask(
456 FROM_HERE,
457 base::Bind(&WiFiServiceMac::WaitForNetworkConnect,
458 base::Unretained(this),
459 network_guid,
460 ++attempt),
461 base::TimeDelta::FromMilliseconds(kConnectionCheckAttemptDelayMs));
462 }
463 }
464
465
466 NSError* WiFiServiceMac::GetVisibleNetworkList(const std::string& network_guid,
tbarzic 2014/01/08 23:06:23 Instead of returning network_list here, why don't
mef 2014/01/09 22:41:46 Done.
467 NetworkList* network_list) {
468
469 NSError* ns_error = nil;
470 NSString* network_name = nil;
471
472 DVLOG(1) << "<<< GetVisibleNetworkList: " << network_guid;
473
474 if (!network_guid.empty())
475 network_name = SSIDFromGUID(network_guid);
476
477 NSSet* networks = [interface_ scanForNetworksWithName:network_name
478 error:&ns_error];
479 if (ns_error != nil)
480 return ns_error;
481
482 std::map<std::string, NetworkProperties*> network_properties_map;
483
484 CWNetwork* network;
485 // There is one |network| per BSS in |networks|, so go through the set and
486 // combine them, paying attention to supported frequencies.
487 for (network in networks) {
tbarzic 2014/01/08 23:06:23 should network_list be cleared before the loop?
mef 2014/01/09 22:41:46 Done.
488 NetworkProperties network_properties;
489 NetworkPropertiesFromCWNetwork(network, &network_properties);
490
491 if (network_properties_map.find(network_properties.guid) ==
492 network_properties_map.end()) {
493 network_list->push_back(network_properties);
494 network_properties_map[network_properties.guid] = &network_list->back();
495 } else {
496 NetworkProperties* existing = network_properties_map.at(
497 network_properties.guid);
498 existing->frequency_set.insert(*network_properties.frequency_set.begin());
499 }
500 }
501 DVLOG(1) << ">>> GetVisibleNetworkList: " << network_guid;
502
503 return nil;
504 }
505
506 bool WiFiServiceMac::CheckError(NSError* ns_error,
507 const char* error_name,
508 std::string* error) const {
509 if (ns_error != nil) {
510 DLOG(ERROR) << "*** Error:" << error_name << ":" << [ns_error code];
511 *error = error_name;
512 return true;
513 }
514 return false;
515 }
516
517 void WiFiServiceMac::NetworkPropertiesFromCWNetwork(
518 const CWNetwork* network,
519 NetworkProperties* properties) const {
520
521 if ([[network ssid] compare:[interface_ ssid]] == NSOrderedSame)
522 properties->connection_state = onc::connection_state::kConnected;
523 else
524 properties->connection_state = onc::connection_state::kNotConnected;
525
526 properties->ssid = base::SysNSStringToUTF8([network ssid]);
527 properties->name = properties->ssid;
528 properties->guid = GUIDFromSSID([network ssid]);
529 properties->type = onc::network_type::kWiFi;
530
531 properties->bssid = base::SysNSStringToUTF8([network bssid]);
532 if ([[network wlanChannel] channelBand] == kCWChannelBand2GHz)
533 properties->frequency = kFrequency2400;
534 else
535 properties->frequency = kFrequency5000;
536 properties->frequency_set.insert(properties->frequency);
537 properties->security = SecurityFromCWSecurityMode(
538 static_cast<CWSecurityMode>([[network securityMode] intValue]));
539
540 properties->signal_strength = [[network rssi] intValue];
541 }
542
543 std::string WiFiServiceMac::SecurityFromCWSecurityMode(
544 CWSecurityMode security) const {
545 switch (security) {
546 case kCWSecurityModeWPA_Enterprise:
547 case kCWSecurityModeWPA2_Enterprise:
548 return onc::wifi::kWPA_EAP;
549 case kCWSecurityModeWPA_PSK:
550 case kCWSecurityModeWPA2_PSK:
551 return onc::wifi::kWPA_PSK;
552 case kCWSecurityModeWEP:
553 return onc::wifi::kWEP_PSK;
554 case kCWSecurityModeOpen:
555 return onc::wifi::kNone;
556 // TODO(mef): Figure out correct mapping.
557 case kCWSecurityModeWPS:
558 case kCWSecurityModeDynamicWEP:
559 return onc::wifi::kWPA_EAP;
560 }
561 return onc::wifi::kWPA_EAP;
562 }
563
564 void WiFiServiceMac::OnWlanObserverNotification() {
565 std::string connected_network_guid = GUIDFromSSID([interface_ ssid]);
566 DVLOG(1) << " *** Got Notification: " << connected_network_guid;
567 if (connected_network_guid.empty()) {
568 // Find previously connected network and notify that it is disconnected.
569 for (WiFiService::NetworkList::iterator it = networks_.begin();
570 it != networks_.end();
571 ++it) {
572 if (it->connection_state == onc::connection_state::kConnected) {
573 it->connection_state = onc::connection_state::kNotConnected;
574 NotifyNetworkChanged(it->guid);
575 }
576 }
577 } else {
578 NotifyNetworkChanged(connected_network_guid);
tbarzic 2014/01/08 23:06:23 You should make sure that networks_ contains the c
mef 2014/01/09 22:41:46 Done.
579 }
580 }
581
582 void WiFiServiceMac::NotifyNetworkListChanged(const NetworkList& networks) {
583 if (network_list_changed_observer_.is_null())
584 return;
585
586 NetworkGuidList current_networks;
587 for (NetworkList::const_iterator it = networks.begin();
588 it != networks.end();
589 ++it) {
590 current_networks.push_back(it->guid);
591 }
592
593 message_loop_proxy_->PostTask(
594 FROM_HERE,
595 base::Bind(network_list_changed_observer_, current_networks));
596 }
597
598 void WiFiServiceMac::NotifyNetworkChanged(const std::string& network_guid) {
599 if (!enable_notify_network_changed_ || networks_changed_observer_.is_null())
600 return;
601
602 DVLOG(1) << "NotifyNetworkChanged: " << network_guid;
603 NetworkGuidList changed_networks(1, network_guid);
604 message_loop_proxy_->PostTask(
605 FROM_HERE,
606 base::Bind(networks_changed_observer_, changed_networks));
607 }
608
609 // static
610 WiFiService* WiFiService::Create() { return new WiFiServiceMac(); }
611
612 } // namespace wifi
OLDNEW
« no previous file with comments | « components/wifi/wifi_service.cc ('k') | components/wifi/wifi_service_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698