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

Side by Side Diff: chrome/browser/local_discovery/wifi/wifi_manager_nonchromeos.cc

Issue 226883002: WiFi client for GCD bootstrapping (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
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
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 "base/cancelable_callback.h"
6 #include "base/threading/sequenced_worker_pool.h"
7 #include "base/threading/thread.h"
8 #include "chrome/browser/local_discovery/wifi/wifi_manager_nonchromeos.h"
9 #include "components/onc/onc_constants.h"
10 #include "components/wifi/wifi_service.h"
11 #include "content/public/browser/browser_thread.h"
12
13 using wifi::WiFiService;
stevenjb 2014/05/15 18:16:26 nit: ::wifi::WiFiService would make the need for t
Noam Samuel 2014/05/20 21:19:53 Done.
14
15 namespace local_discovery {
16
17 namespace wifi {
18
19 namespace {
20
21 const int kConnectionTimeoutSeconds = 10;
22
23 scoped_ptr<base::DictionaryValue> MakeProperties(const std::string& ssid,
24 const std::string& password) {
25 scoped_ptr<base::DictionaryValue> properties(new base::DictionaryValue);
26
27 properties->SetString(onc::network_config::kType, onc::network_type::kWiFi);
28 base::DictionaryValue* wifi = new base::DictionaryValue;
29 properties->Set(onc::network_config::kWiFi, wifi);
30
31 wifi->SetString(onc::wifi::kSSID, ssid);
32 wifi->SetString(onc::wifi::kPassphrase, password);
33
34 return properties.Pass();
35 }
36
37 } // namespace
38
39 class NetworkListObserverNonChromeos : public NetworkListObserver {
40 public:
41 NetworkListObserverNonChromeos(
42 const WifiManager::SSIDListCallback& callback,
43 base::WeakPtr<WifiManagerNonChromeos> wifi_manager);
44 virtual ~NetworkListObserverNonChromeos();
45
46 virtual void Start() OVERRIDE;
47
48 void OnNetworkListChanged(const std::vector<NetworkProperties>& ssid_list);
49
50 private:
51 WifiManager::SSIDListCallback callback_;
52 bool started_;
53 base::WeakPtr<WifiManagerNonChromeos> wifi_manager_;
stevenjb 2014/05/15 18:16:26 DISALLOW_COPY_AND_ASSIGN
54 };
55
56 class WifiServiceWrapper {
stevenjb 2014/05/15 18:16:26 I think this and NetworkListObserverNonChromeos wo
Noam Samuel 2014/05/20 21:19:53 Done.
57 public:
58 WifiServiceWrapper(
59 const base::Callback<void(const base::Closure&)>& post_callback,
60 const WifiManager::SSIDListCallback& network_list_update);
61
62 ~WifiServiceWrapper();
63
64 void Start();
65
66 void GetSSIDList(const WifiManager::SSIDListCallback& callback);
67
68 void ConnectToNetwork(const std::string& ssid,
69 const std::string& password,
stevenjb 2014/05/15 18:16:26 Take Credentials or name ConnectToPskNetwork.
Noam Samuel 2014/05/20 21:19:53 Done.
70 const WifiManager::SuccessCallback& callback);
71
72 base::WeakPtr<WifiServiceWrapper> AsWeakPtr();
73
74 void RequestScan(const base::Closure& callback);
75
76 void ConnectToNetworkByID(const std::string& network_guid,
77 const WifiManager::SuccessCallback& callback);
78
79 void GetNetworkCredentials(const std::string& network_guid,
80 const WifiManager::CredentialsCallback& callback);
81
82 private:
83 void GetSSIDListInternal(std::vector<NetworkProperties>* ssid_list);
84
85 void OnNetworkListChangedEvent(const std::vector<std::string>& network_guids);
86
87 void OnNetworksChangedEvent(const std::vector<std::string>& network_guids);
88
89 std::string GetConnectedGUID();
90
91 bool IsConnected(const std::string& network_guid);
92
93 void OnConnectToNetworkTimeout();
94
95 scoped_ptr<WiFiService> wifi_service_;
96
97 base::Callback<void(const base::Closure&)> post_callback_;
98 WifiManager::SSIDListCallback network_list_update_;
99
100 WifiManager::SuccessCallback connect_success_callback_;
101 base::CancelableClosure connect_failure_callback_;
102 std::string connected_network_guid_; // SSID of previously connected network.
103 std::string
104 connecting_network_guid_; // SSID of network we are connecting to.
105
106 base::WeakPtrFactory<WifiServiceWrapper> weak_factory_;
stevenjb 2014/05/15 18:16:26 DISALLOW_COPY_AND_ASSIGN
Noam Samuel 2014/05/20 21:19:53 Done.
107 };
108
109 NetworkListObserverNonChromeos::NetworkListObserverNonChromeos(
110 const WifiManager::SSIDListCallback& callback,
111 base::WeakPtr<WifiManagerNonChromeos> wifi_manager)
112 : callback_(callback), started_(false), wifi_manager_(wifi_manager) {
113 }
114
115 NetworkListObserverNonChromeos::~NetworkListObserverNonChromeos() {
116 if (started_ && wifi_manager_) {
117 wifi_manager_->RemoveObserver(this);
118 }
stevenjb 2014/05/15 18:16:26 optional nit: Usually in chrome we don't use {} ar
Noam Samuel 2014/05/20 21:19:53 Done.
119 }
120
121 void NetworkListObserverNonChromeos::Start() {
122 DCHECK(!started_);
123
124 if (wifi_manager_) {
125 wifi_manager_->AddObserver(this);
126 }
stevenjb 2014/05/15 18:16:26 ditto
Noam Samuel 2014/05/20 21:19:53 Done.
127 }
128
129 void NetworkListObserverNonChromeos::OnNetworkListChanged(
130 const std::vector<NetworkProperties>& ssid_list) {
131 callback_.Run(ssid_list);
132 }
133
134 WifiServiceWrapper::WifiServiceWrapper(
135 const base::Callback<void(const base::Closure&)>& post_callback,
136 const WifiManager::SSIDListCallback& network_list_update)
137 : post_callback_(post_callback),
138 network_list_update_(network_list_update),
139 weak_factory_(this) {
140 }
141
142 WifiServiceWrapper::~WifiServiceWrapper() {
143 }
144
145 void WifiServiceWrapper::Start() {
146 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
147 wifi_service_.reset(WiFiService::Create());
148
149 wifi_service_->Initialize(base::MessageLoopProxy::current());
150
151 wifi_service_->SetEventObservers(
152 base::MessageLoopProxy::current(),
153 base::Bind(&WifiServiceWrapper::OnNetworksChangedEvent,
154 base::Unretained(this)),
155 base::Bind(&WifiServiceWrapper::OnNetworkListChangedEvent,
156 base::Unretained(this)));
157 }
158
159 void WifiServiceWrapper::GetSSIDList(
160 const WifiManager::SSIDListCallback& callback) {
161 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
162
163 std::vector<NetworkProperties> network_property_list;
164
165 GetSSIDListInternal(&network_property_list);
166
167 content::BrowserThread::PostTask(
168 content::BrowserThread::UI,
169 FROM_HERE,
170 base::Bind(post_callback_, base::Bind(callback, network_property_list)));
171 }
172
173 void WifiServiceWrapper::ConnectToNetwork(
tbarzic 2014/05/15 20:50:07 how is this going to be used as opposed to Connect
Noam Samuel 2014/05/20 21:19:53 This is for connecting to networks that are not ye
174 const std::string& ssid,
175 const std::string& password,
176 const WifiManager::SuccessCallback& callback) {
177 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
178 scoped_ptr<base::DictionaryValue> properties = MakeProperties(ssid, password);
179 std::string network_guid;
180 bool error = false;
181 std::string error_string;
stevenjb 2014/05/15 18:16:26 nit: declare these closer to where they are used
Noam Samuel 2014/05/20 21:19:53 Done.
182
183 std::string internal_id;
184
185 std::vector<NetworkProperties> network_property_list;
186 GetSSIDListInternal(&network_property_list);
187
188 for (std::vector<NetworkProperties>::iterator i =
189 network_property_list.begin();
190 i != network_property_list.end();
191 i++) {
192 if (i->ssid == ssid) {
193 internal_id = i->internal_id;
194 break;
195 }
196 }
197
198 if (!internal_id.empty()) {
199 network_guid = internal_id;
200 wifi_service_->SetProperties(
tbarzic 2014/05/15 20:50:07 SetProperties for setting passphrase won't work on
Noam Samuel 2014/05/20 21:19:53 Done.
201 network_guid, properties.Pass(), &error_string);
202
203 if (!error_string.empty()) {
204 LOG(ERROR) << "Could not set properties on network: " << error_string;
205 error = true;
206 }
207 } else {
208 wifi_service_->CreateNetwork(
209 false, properties.Pass(), &network_guid, &error_string);
210
211 if (!error_string.empty()) {
212 LOG(ERROR) << "Could not create network: " << error_string;
213 error = true;
214 }
215 }
216
217 if (!error) {
218 ConnectToNetworkByID(network_guid, callback);
219 } else {
220 content::BrowserThread::PostTask(
221 content::BrowserThread::UI,
222 FROM_HERE,
223 base::Bind(post_callback_, base::Bind(callback, !error)));
224 }
225 }
226
227 void WifiServiceWrapper::OnNetworkListChangedEvent(
228 const std::vector<std::string>& network_guids) {
229 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
230 std::vector<NetworkProperties> ssid_list;
231 GetSSIDListInternal(&ssid_list);
232 content::BrowserThread::PostTask(content::BrowserThread::UI,
233 FROM_HERE,
234 base::Bind(network_list_update_, ssid_list));
235 }
236
237 void WifiServiceWrapper::OnNetworksChangedEvent(
238 const std::vector<std::string>& network_guids) {
239 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
240 if (!connecting_network_guid_.empty() &&
241 IsConnected(connecting_network_guid_)) {
stevenjb 2014/05/15 18:16:26 reverse logic and early exit
Noam Samuel 2014/05/20 21:19:53 Done.
242 connecting_network_guid_.clear();
243 connect_failure_callback_.Cancel();
244
245 content::BrowserThread::PostTask(
246 content::BrowserThread::UI,
247 FROM_HERE,
248 base::Bind(post_callback_,
249 base::Bind(connect_success_callback_, true)));
250
251 connect_success_callback_.Reset();
252 }
253 }
254
255 base::WeakPtr<WifiServiceWrapper> WifiServiceWrapper::AsWeakPtr() {
256 return weak_factory_.GetWeakPtr();
257 }
258
259 void WifiServiceWrapper::RequestScan(const base::Closure& callback) {
260 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
261 wifi_service_->RequestNetworkScan();
262
263 if (!callback.is_null()) {
264 content::BrowserThread::PostTask(content::BrowserThread::UI,
265 FROM_HERE,
266 base::Bind(post_callback_, callback));
267 }
268 }
269
270 void WifiServiceWrapper::ConnectToNetworkByID(
271 const std::string& network_guid,
272 const WifiManager::SuccessCallback& callback) {
273 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
274 std::string error_string;
275 bool error = false;
276 bool connected = false;
stevenjb 2014/05/15 18:16:26 declare on line 287 when first assigned/used
Noam Samuel 2014/05/20 21:19:53 Done.
277
278 std::string connected_network_id = GetConnectedGUID();
279 wifi_service_->StartConnect(network_guid, &error_string);
280
281 if (!error_string.empty()) {
282 LOG(ERROR) << "Could not connect to network by ID: " << error_string;
283 error = true;
284 wifi_service_->StartConnect(connected_network_id, &error_string);
285 }
286
287 connected = IsConnected(network_guid);
288
289 if (error || connected) {
290 content::BrowserThread::PostTask(
291 content::BrowserThread::UI,
292 FROM_HERE,
293 base::Bind(post_callback_, base::Bind(callback, !error && connected)));
stevenjb 2014/05/15 18:16:26 return;
Noam Samuel 2014/05/20 21:19:53 Done.
294 } else {
stevenjb 2014/05/15 18:16:26 no else
Noam Samuel 2014/05/20 21:19:53 Done.
295 connect_success_callback_ = callback;
296 connecting_network_guid_ = network_guid;
297 connected_network_guid_ = connected_network_id;
298
299 connect_failure_callback_.Reset(
300 base::Bind(&WifiServiceWrapper::OnConnectToNetworkTimeout,
301 base::Unretained(this)));
302
303 base::MessageLoop::current()->PostDelayedTask(
304 FROM_HERE,
305 connect_failure_callback_.callback(),
306 base::TimeDelta::FromSeconds(kConnectionTimeoutSeconds));
307 }
308 }
309
310 void WifiServiceWrapper::OnConnectToNetworkTimeout() {
311 bool connected = IsConnected(connecting_network_guid_);
312 std::string error_string;
313
314 if (!connected) {
315 wifi_service_->StartConnect(connected_network_guid_, &error_string);
316 }
stevenjb 2014/05/15 18:16:26 optional: no {}
Noam Samuel 2014/05/20 21:19:53 Done.
317
318 connecting_network_guid_.clear();
319
320 content::BrowserThread::PostTask(
321 content::BrowserThread::UI,
322 FROM_HERE,
323 base::Bind(post_callback_,
324 base::Bind(connect_success_callback_, connected)));
325
326 connect_success_callback_.Reset();
327 }
328
329 void WifiServiceWrapper::GetNetworkCredentials(
330 const std::string& network_guid,
331 const WifiManager::CredentialsCallback& callback) {
332 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
333 std::string error_string;
334 bool error = false;
335 std::string ssid;
336 std::string key;
stevenjb 2014/05/15 18:16:26 declare where used
Noam Samuel 2014/05/20 21:19:53 Done.
337
338 base::DictionaryValue properties;
339
340 wifi_service_->GetProperties(network_guid, &properties, &error_string);
341
342 if (!error_string.empty()) {
343 LOG(ERROR) << "Could not get network properties: " << error_string;
344 error = true;
345 }
346
347 if (!properties.GetString(onc::network_config::kName, &ssid)) {
348 LOG(ERROR) << "Could not get network SSID";
349 error = true;
350 }
351
352 if (!error) {
353 wifi_service_->GetKeyFromSystem(network_guid, &key, &error_string);
tbarzic 2014/05/15 20:50:07 I'm not sure this will work from browser process.
Noam Samuel 2014/05/16 17:56:02 This does work on OSX but not on Windows. There's
354
355 if (!error_string.empty()) {
356 LOG(ERROR) << "Could not get key from system: " << error_string;
357 error = true;
358 }
359 }
360
361 content::BrowserThread::PostTask(
362 content::BrowserThread::UI,
363 FROM_HERE,
364 base::Bind(post_callback_, base::Bind(callback, !error, ssid, key)));
365 }
366
367 void WifiServiceWrapper::GetSSIDListInternal(
368 std::vector<NetworkProperties>* ssid_list) {
369 base::ListValue visible_networks;
370
371 wifi_service_->GetVisibleNetworks(onc::network_type::kWiFi,
372 &visible_networks);
373
374 for (size_t i = 0; i < visible_networks.GetSize(); i++) {
375 const base::DictionaryValue* network_value = NULL;
376 NetworkProperties network_properties;
377 std::string connection_status;
378
379 if (!visible_networks.GetDictionary(i, &network_value) ||
380 !network_value->GetString(onc::network_config::kName,
381 &network_properties.ssid) ||
382 !network_value->GetString(onc::network_config::kGUID,
383 &network_properties.internal_id) ||
384 !network_value->GetString(onc::network_config::kConnectionState,
385 &connection_status)) {
386 NOTREACHED();
387 continue;
388 }
389
390 network_properties.connected =
391 (connection_status == onc::connection_state::kConnected);
392
393 ssid_list->push_back(network_properties);
394 }
395 }
396
397 std::string WifiServiceWrapper::GetConnectedGUID() {
398 std::vector<NetworkProperties> ssid_list;
399 GetSSIDListInternal(&ssid_list);
400
401 for (std::vector<NetworkProperties>::const_iterator i = ssid_list.begin();
402 i != ssid_list.end();
403 i++) {
stevenjb 2014/05/15 18:16:26 ++i (nit: for iterators, 'iter' or 'it' is more co
Noam Samuel 2014/05/20 21:19:53 Done.
404 if (i->connected) {
405 return i->internal_id;
406 }
407 }
408
409 return "";
410 }
411
412 bool WifiServiceWrapper::IsConnected(const std::string& network_guid) {
413 std::vector<NetworkProperties> ssid_list;
tbarzic 2014/05/15 20:50:07 how about: return !network_guid.empty() && network
Noam Samuel 2014/05/16 17:56:02 There's a slight neuance that I should maybe comme
414 GetSSIDListInternal(&ssid_list);
415
416 for (std::vector<NetworkProperties>::const_iterator i = ssid_list.begin();
417 i != ssid_list.end();
418 i++) {
stevenjb 2014/05/15 18:16:26 ++i
Noam Samuel 2014/05/20 21:19:53 Done.
419 if (i->connected && i->internal_id == network_guid) {
420 return true;
421 }
422 }
423
424 return false;
425 }
426
427 scoped_ptr<WifiManager> WifiManager::Create() {
428 return scoped_ptr<WifiManager>(new WifiManagerNonChromeos());
429 }
430
431 WifiManagerNonChromeos::WifiManagerNonChromeos()
432 : wifi_wrapper_(NULL), weak_factory_(this) {
433 }
434
435 WifiManagerNonChromeos::~WifiManagerNonChromeos() {
436 if (wifi_wrapper_) {
437 content::BrowserThread::DeleteSoon(
438 content::BrowserThread::FILE, FROM_HERE, wifi_wrapper_);
439 }
440 }
441
442 void WifiManagerNonChromeos::Start() {
443 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
444 task_runner_ = content::BrowserThread::GetMessageLoopProxyForThread(
445 content::BrowserThread::FILE);
446
447 wifi_wrapper_ = new WifiServiceWrapper(
stevenjb 2014/05/15 18:16:26 It is confusing that we allocate wifi_wrapper_ on
Noam Samuel 2014/05/20 21:19:53 Added comment.
448 base::Bind(&WifiManagerNonChromeos::PostClosure,
449 weak_factory_.GetWeakPtr()),
450 base::Bind(&WifiManagerNonChromeos::OnNetworkListChanged,
451 weak_factory_.GetWeakPtr()));
452
453 task_runner_->PostTask(
454 FROM_HERE,
455 base::Bind(&WifiServiceWrapper::Start, wifi_wrapper_->AsWeakPtr()));
456 }
457
458 void WifiManagerNonChromeos::GetSSIDList(const SSIDListCallback& callback) {
459 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
460 task_runner_->PostTask(FROM_HERE,
461 base::Bind(&WifiServiceWrapper::GetSSIDList,
462 wifi_wrapper_->AsWeakPtr(),
463 callback));
464 }
465
466 void WifiManagerNonChromeos::RequestScan(const base::Closure& callback) {
467 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
468 task_runner_->PostTask(FROM_HERE,
469 base::Bind(&WifiServiceWrapper::RequestScan,
470 wifi_wrapper_->AsWeakPtr(),
471 callback));
472 }
473
474 void WifiManagerNonChromeos::OnNetworkListChanged(
475 const std::vector<NetworkProperties>& ssid_list) {
476 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
477 FOR_EACH_OBSERVER(NetworkListObserverNonChromeos,
478 network_list_observers_,
479 OnNetworkListChanged(ssid_list));
480 }
481
482 void WifiManagerNonChromeos::PostClosure(const base::Closure& callback) {
483 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
484 callback.Run();
485 }
486
487 void WifiManagerNonChromeos::ConnectToNetwork(
488 const std::string& ssid,
489 const WifiCredentials& credentials,
490 const SuccessCallback& callback) {
491 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
492 task_runner_->PostTask(FROM_HERE,
493 base::Bind(&WifiServiceWrapper::ConnectToNetwork,
494 wifi_wrapper_->AsWeakPtr(),
495 ssid,
496 credentials.psk,
497 callback));
498 }
499
500 void WifiManagerNonChromeos::ConnectToNetworkByID(
501 const std::string& internal_id,
502 const SuccessCallback& callback) {
503 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
504 task_runner_->PostTask(FROM_HERE,
505 base::Bind(&WifiServiceWrapper::ConnectToNetworkByID,
506 wifi_wrapper_->AsWeakPtr(),
507 internal_id,
508 callback));
509 }
510
511 void WifiManagerNonChromeos::GetNetworkCredentials(
512 const std::string& internal_id,
513 const CredentialsCallback& callback) {
514 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
515 task_runner_->PostTask(FROM_HERE,
516 base::Bind(&WifiServiceWrapper::GetNetworkCredentials,
517 wifi_wrapper_->AsWeakPtr(),
518 internal_id,
519 callback));
520 }
521
522 scoped_ptr<NetworkListObserver>
523 WifiManagerNonChromeos::CreateNetworkListObserver(
524 const SSIDListCallback& callback) {
525 return scoped_ptr<NetworkListObserver>(
526 new NetworkListObserverNonChromeos(callback, weak_factory_.GetWeakPtr()));
527 }
528
529 void WifiManagerNonChromeos::AddObserver(
530 NetworkListObserverNonChromeos* observer) {
531 network_list_observers_.AddObserver(observer);
532 }
533
534 void WifiManagerNonChromeos::RemoveObserver(
535 NetworkListObserverNonChromeos* observer) {
536 network_list_observers_.RemoveObserver(observer);
537 }
538
539 } // namespace wifi
540
541 } // namespace local_discovery
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698