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

Side by Side Diff: chrome/browser/local_discovery/wifi/wifi_service_client.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/threading/sequenced_worker_pool.h"
6 #include "base/threading/thread.h"
7 #include "chrome/browser/local_discovery/wifi/wifi_service_client.h"
8 #include "components/onc/onc_constants.h"
9 #include "components/wifi/wifi_service.h"
10 #include "content/public/browser/browser_thread.h"
11
12 using wifi::WiFiService;
13
14 namespace local_discovery {
15
16 namespace wifi {
17
18 namespace {
19
20 scoped_ptr<base::DictionaryValue> MakeProperties(const std::string& ssid,
21 const std::string& password) {
22 scoped_ptr<base::DictionaryValue> properties(new base::DictionaryValue);
23
24 properties->SetString(onc::network_config::kType, onc::network_type::kWiFi);
25 base::DictionaryValue* wifi = new base::DictionaryValue;
26 properties->Set(onc::network_config::kWiFi, wifi);
27
28 wifi->SetString(onc::wifi::kSSID, ssid);
29 wifi->SetString(onc::wifi::kPassphrase, password);
30
31 return properties.Pass();
32 }
33
34 } // namespace
35
36 class WifiServiceContainer {
tbarzic 2014/05/08 21:54:06 the name is somewhat confusing. It sounds more lik
Noam Samuel 2014/05/12 23:54:12 Renamed WifiServiceWrapper
37 public:
38 explicit WifiServiceContainer(
39 const base::WeakPtr<WifiServiceClient> service_client)
40 : service_client_(service_client), weak_factory_(this) {}
stevenjb 2014/05/09 18:46:15 One arg per line
Noam Samuel 2014/05/12 23:54:12 Done.
41
42 ~WifiServiceContainer() {}
43
44 void Start() {
45 wifi_service_.reset(WiFiService::Create());
46
47 wifi_service_->Initialize(base::MessageLoopProxy::current());
48
49 wifi_service_->SetEventObservers(
50 base::MessageLoopProxy::current(),
51 base::Bind(&WifiServiceContainer::OnNetworksChangedEvent,
stevenjb 2014/05/09 18:46:15 OnNetworksChangedEvent is a no-op, so why pass it
Noam Samuel 2014/05/12 23:54:12 Done.
52 base::Unretained(this)),
53 base::Bind(&WifiServiceContainer::OnNetworkListChangedEvent,
54 base::Unretained(this)));
stevenjb 2014/05/09 18:46:15 Rather than using Unretained (which implies that t
Noam Samuel 2014/05/12 23:54:12 OnNetworkListChangedEvent does have class dependen
stevenjb 2014/05/13 00:18:06 My bad, I didn't read OnNetworkListChangedEvent cl
55 }
56
57 void GetSSIDList(const WifiClient::SSIDListCallback& callback) {
stevenjb 2014/05/09 18:46:15 For a complex implementation like this it is nicer
Noam Samuel 2014/05/12 23:54:12 Done.
58 base::ListValue visible_networks;
59
60 wifi_service_->GetVisibleNetworks(onc::network_type::kWiFi,
61 &visible_networks);
62
63 std::vector<NetworkProperties> network_property_list;
64
65 for (size_t i = 0; i < visible_networks.GetSize(); i++) {
66 const base::DictionaryValue* network_value = NULL;
67 NetworkProperties network_properties;
68 std::string connection_status;
69
70 if (!visible_networks.GetDictionary(i, &network_value) ||
71 !network_value->GetString(onc::network_config::kName,
72 &network_properties.ssid) ||
73 !network_value->GetString(onc::network_config::kGUID,
74 &network_properties.internal_id) ||
75 !network_value->GetString(onc::network_config::kConnectionState,
76 &connection_status)) {
77 NOTREACHED();
78 continue;
79 }
80
81 network_properties.connected =
82 (connection_status == onc::connection_state::kConnected);
83
84 network_property_list.push_back(network_properties);
85 }
86
87 content::BrowserThread::PostTask(
88 content::BrowserThread::UI,
89 FROM_HERE,
90 base::Bind(&WifiServiceClient::PostClosure,
91 service_client_,
92 base::Bind(callback, network_property_list)));
93 }
94
95 void ConnectToNetwork(const std::string& ssid,
96 const std::string& internal_id,
97 const std::string& password,
98 const WifiClient::SuccessCallback& callback) {
99 scoped_ptr<base::DictionaryValue> properties =
100 MakeProperties(ssid, password);
101 std::string network_guid;
102 bool error = false;
103 std::string error_string;
104
105 if (!internal_id.empty()) {
106 network_guid = internal_id;
107 wifi_service_->SetProperties(
108 network_guid, properties.Pass(), &error_string);
109
110 if (!error_string.empty()) {
111 LOG(ERROR) << "Could not set properties on network: " << error_string;
112 error = true;
113 }
114 } else {
115 wifi_service_->CreateNetwork(
116 false, properties.Pass(), &network_guid, &error_string);
117
118 if (!error_string.empty()) {
119 LOG(ERROR) << "Could not create network: " << error_string;
120 error = true;
121 }
122 }
123
124 if (!error) {
125 wifi_service_->StartConnect(network_guid, &error_string);
126
127 if (!error_string.empty()) {
128 LOG(ERROR) << "Could not connect to network: " << error_string;
129 error = true;
130 }
131 }
132
133 content::BrowserThread::PostTask(content::BrowserThread::UI,
tbarzic 2014/05/08 21:54:06 just a warning: StartConnect succeeding does not n
Noam Samuel 2014/05/12 23:54:12 Could you expand on that? Will the network either
stevenjb 2014/05/13 00:18:06 I'm less familiar with WifiService, but connecting
Noam Samuel 2014/05/13 23:51:55 Refactored the code to be asynchronous and use a t
134 FROM_HERE,
135 base::Bind(&WifiServiceClient::PostClosure,
136 service_client_,
137 base::Bind(callback, !error)));
138 }
139
140 void OnNetworksChangedEvent(const std::vector<std::string>& network_guids) {}
141
142 void OnNetworkListChangedEvent(
143 const std::vector<std::string>& network_guids) {
144 content::BrowserThread::PostTask(
145 content::BrowserThread::UI,
146 FROM_HERE,
147 base::Bind(&WifiServiceClient::OnNetworkListChanged, service_client_));
148 }
149
150 base::WeakPtr<WifiServiceContainer> AsWeakPtr() {
151 return weak_factory_.GetWeakPtr();
152 }
153
154 void RequestScan() { wifi_service_->RequestNetworkScan(); }
155
156 void ConnectToNetworkByID(const std::string& network_guid,
157 const WifiClient::SuccessCallback& callback) {
158 std::string error_string;
159 bool error = false;
160
161 wifi_service_->StartConnect(network_guid, &error_string);
162
163 if (!error_string.empty()) {
164 LOG(ERROR) << "Could not connect to network by ID: " << error_string;
165 error = true;
166 }
167
168 content::BrowserThread::PostTask(content::BrowserThread::UI,
169 FROM_HERE,
170 base::Bind(&WifiServiceClient::PostClosure,
171 service_client_,
172 base::Bind(callback, !error)));
stevenjb 2014/05/09 18:46:15 It would be nice to share the common code between
Noam Samuel 2014/05/12 23:54:12 Done.
173 }
174
175 void GetNetworkCredentials(const std::string& network_guid,
176 const WifiClient::CredentialsCallback& callback) {
177 std::string error_string;
178 bool error = false;
179 std::string ssid;
180 std::string key;
181
182 base::DictionaryValue properties;
183
184 wifi_service_->GetProperties(network_guid, &properties, &error_string);
185
186 if (!error_string.empty()) {
187 LOG(ERROR) << "Could not get network properties: " << error_string;
188 error = true;
189 }
190
191 if (!properties.GetString(onc::network_config::kName, &ssid)) {
192 LOG(ERROR) << "Could not get network SSID";
193 error = true;
194 }
195
196 if (!error) {
197 wifi_service_->GetKeyFromSystem(network_guid, &key, &error_string);
198
199 if (!error_string.empty()) {
200 LOG(ERROR) << "Could not get key from system: " << error_string;
201 error = true;
202 }
203 }
204
205 content::BrowserThread::PostTask(
206 content::BrowserThread::UI,
207 FROM_HERE,
208 base::Bind(&WifiServiceClient::PostClosure,
tbarzic 2014/05/08 21:54:06 I think it would make more sense to do this bindin
Noam Samuel 2014/05/12 23:54:12 Done.
209 service_client_,
210 base::Bind(callback, !error, ssid, key)));
211 }
212
213 private:
214 scoped_ptr<WiFiService> wifi_service_;
215 base::WeakPtr<WifiServiceClient> service_client_;
216 base::WeakPtrFactory<WifiServiceContainer> weak_factory_;
217 };
218
219 scoped_ptr<WifiClient> WifiClient::Create() {
220 return scoped_ptr<WifiClient>(new WifiServiceClient());
221 }
222
223 WifiServiceClient::WifiServiceClient() : weak_factory_(this) {
224 }
225
226 WifiServiceClient::~WifiServiceClient() {
227 }
228
229 void WifiServiceClient::Start() {
230 task_runner_ = content::BrowserThread::GetMessageLoopProxyForThread(
231 content::BrowserThread::FILE);
232
233 scoped_ptr<WifiServiceContainer, ThreadSpecificDeleter<WifiServiceContainer> >
234 wifi_container(new WifiServiceContainer(weak_factory_.GetWeakPtr()),
235 ThreadSpecificDeleter<WifiServiceContainer>(task_runner_));
236 wifi_container_.swap(wifi_container);
Vitaly Buka (NO REVIEWS) 2014/05/05 22:05:58 why do you need swap here? why not just wifi_cont
Noam Samuel 2014/05/12 23:54:12 It was in order to have a stateful deleter with a
237
238 task_runner_->PostTask(
239 FROM_HERE,
240 base::Bind(&WifiServiceContainer::Start, wifi_container_->AsWeakPtr()));
tbarzic 2014/05/08 21:54:06 AsWeakPtr is no particularly useful here: AsWeakPt
Noam Samuel 2014/05/12 23:54:12 Are you sure about this? https://code.google.com/p
tbarzic 2014/05/15 20:50:07 yeah, looks like I was wrong about what's allowed.
241 }
242
243 void WifiServiceClient::GetSSIDList(const SSIDListCallback& callback) {
244 task_runner_->PostTask(FROM_HERE,
245 base::Bind(&WifiServiceContainer::GetSSIDList,
246 wifi_container_->AsWeakPtr(),
247 callback));
248 }
249
250 void WifiServiceClient::RequestScan(const SuccessCallback& callback) {
251 scan_callbacks_.push_back(callback);
tbarzic 2014/05/08 21:54:06 I wouldn't rely on RequestScan causing OnNetworkLi
Noam Samuel 2014/05/12 23:54:12 Thanks, changed the model a bit to add observers i
252 task_runner_->PostTask(FROM_HERE,
253 base::Bind(&WifiServiceContainer::RequestScan,
254 wifi_container_->AsWeakPtr()));
255 }
256
257 void WifiServiceClient::OnNetworkListChanged() {
258 std::vector<SuccessCallback> scan_callbacks;
259 scan_callbacks.swap(scan_callbacks_);
260
261 for (std::vector<SuccessCallback>::iterator i = scan_callbacks.begin();
262 i != scan_callbacks.end();
263 i++) {
264 i->Run(true);
265 }
266 }
267
268 void WifiServiceClient::PostClosure(const base::Closure& callback) {
269 callback.Run();
Vitaly Buka (NO REVIEWS) 2014/05/05 22:05:58 Thread checks around would be useful for understan
stevenjb 2014/05/09 18:46:15 No need for this to be a member function (unless t
Noam Samuel 2014/05/12 23:54:12 Done.
Noam Samuel 2014/05/12 23:54:12 This needs to be a member function because we use
270 }
271
272 void WifiServiceClient::ConnectToNetwork(const std::string& ssid,
273 const std::string& internal_id,
274 const std::string& password,
275 const SuccessCallback& callback) {
276 task_runner_->PostTask(FROM_HERE,
277 base::Bind(&WifiServiceContainer::ConnectToNetwork,
278 wifi_container_->AsWeakPtr(),
279 ssid,
280 internal_id,
281 password,
282 callback));
283 }
284
285 void WifiServiceClient::ConnectToNetworkByID(const std::string& internal_id,
286 const SuccessCallback& callback) {
287 task_runner_->PostTask(FROM_HERE,
288 base::Bind(&WifiServiceContainer::ConnectToNetworkByID,
289 wifi_container_->AsWeakPtr(),
290 internal_id,
291 callback));
292 }
293
294 void WifiServiceClient::GetNetworkCredentials(
295 const std::string& internal_id,
296 const CredentialsCallback& callback) {
297 task_runner_->PostTask(
298 FROM_HERE,
299 base::Bind(&WifiServiceContainer::GetNetworkCredentials,
300 wifi_container_->AsWeakPtr(),
301 internal_id,
302 callback));
303 }
304
305 } // namespace wifi
306
307 } // namespace local_discovery
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698