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

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