1 // Copyright 2013 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.
5 #include "extensions/browser/api/networking_private/networking_private_service_client.h"
7 #include "base/base64.h"
9 #include "base/sequenced_task_runner.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "base/threading/worker_pool.h"
12 #include "components/onc/onc_constants.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "extensions/browser/api/networking_private/networking_private_api.h"
15 #include "extensions/browser/api/networking_private/networking_private_delegate_observer.h"
17 using content::BrowserThread
;
18 using wifi::WiFiService
;
20 namespace extensions
{
24 const char kNetworkingPrivateSequenceTokenName
[] = "NetworkingPrivate";
26 // Deletes WiFiService object on the worker thread.
27 void ShutdownWifiServiceOnWorkerThread(scoped_ptr
<WiFiService
> wifi_service
) {
28 DCHECK(wifi_service
.get());
33 NetworkingPrivateServiceClient::ServiceCallbacks::ServiceCallbacks() {
36 NetworkingPrivateServiceClient::ServiceCallbacks::~ServiceCallbacks() {
39 NetworkingPrivateServiceClient::NetworkingPrivateServiceClient(
40 scoped_ptr
<WiFiService
> wifi_service
,
41 scoped_ptr
<VerifyDelegate
> verify_delegate
)
42 : NetworkingPrivateDelegate(verify_delegate
.Pass()),
43 wifi_service_(wifi_service
.Pass()),
45 sequence_token_
= BrowserThread::GetBlockingPool()->GetNamedSequenceToken(
46 kNetworkingPrivateSequenceTokenName
);
48 BrowserThread::GetBlockingPool()
49 ->GetSequencedTaskRunnerWithShutdownBehavior(
50 sequence_token_
, base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN
);
51 task_runner_
->PostTask(
53 base::Bind(&WiFiService::Initialize
,
54 base::Unretained(wifi_service_
.get()), task_runner_
));
55 task_runner_
->PostTask(
58 &WiFiService::SetEventObservers
,
59 base::Unretained(wifi_service_
.get()),
60 base::ThreadTaskRunnerHandle::Get(),
62 &NetworkingPrivateServiceClient::OnNetworksChangedEventOnUIThread
,
63 weak_factory_
.GetWeakPtr()),
64 base::Bind(&NetworkingPrivateServiceClient::
65 OnNetworkListChangedEventOnUIThread
,
66 weak_factory_
.GetWeakPtr())));
67 net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
70 NetworkingPrivateServiceClient::~NetworkingPrivateServiceClient() {
71 // Verify that wifi_service was passed to ShutdownWifiServiceOnWorkerThread to
72 // be deleted after completion of all posted tasks.
73 DCHECK(!wifi_service_
.get());
76 void NetworkingPrivateServiceClient::Shutdown() {
77 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
78 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
79 // Clear callbacks map to release callbacks from UI thread.
80 callbacks_map_
.Clear();
81 // Post ShutdownWifiServiceOnWorkerThread task to delete services when all
82 // posted tasks are done.
83 task_runner_
->PostTask(FROM_HERE
,
84 base::Bind(&ShutdownWifiServiceOnWorkerThread
,
85 base::Passed(&wifi_service_
)));
88 void NetworkingPrivateServiceClient::AddObserver(
89 NetworkingPrivateDelegateObserver
* observer
) {
90 network_events_observers_
.AddObserver(observer
);
93 void NetworkingPrivateServiceClient::RemoveObserver(
94 NetworkingPrivateDelegateObserver
* observer
) {
95 network_events_observers_
.RemoveObserver(observer
);
98 void NetworkingPrivateServiceClient::OnNetworkChanged(
99 net::NetworkChangeNotifier::ConnectionType type
) {
100 task_runner_
->PostTask(FROM_HERE
,
101 base::Bind(&WiFiService::RequestConnectedNetworkUpdate
,
102 base::Unretained(wifi_service_
.get())));
105 NetworkingPrivateServiceClient::ServiceCallbacks
*
106 NetworkingPrivateServiceClient::AddServiceCallbacks() {
107 ServiceCallbacks
* service_callbacks
= new ServiceCallbacks();
108 service_callbacks
->id
= callbacks_map_
.Add(service_callbacks
);
109 return service_callbacks
;
112 void NetworkingPrivateServiceClient::RemoveServiceCallbacks(
113 ServiceCallbacksID callback_id
) {
114 callbacks_map_
.Remove(callback_id
);
117 // NetworkingPrivateServiceClient implementation
119 void NetworkingPrivateServiceClient::GetProperties(
120 const std::string
& guid
,
121 const DictionaryCallback
& success_callback
,
122 const FailureCallback
& failure_callback
) {
123 ServiceCallbacks
* service_callbacks
= AddServiceCallbacks();
124 service_callbacks
->failure_callback
= failure_callback
;
125 service_callbacks
->get_properties_callback
= success_callback
;
127 scoped_ptr
<base::DictionaryValue
> properties(new base::DictionaryValue
);
128 std::string
* error
= new std::string
;
130 base::DictionaryValue
* properties_ptr
= properties
.get();
131 task_runner_
->PostTaskAndReply(
132 FROM_HERE
, base::Bind(&WiFiService::GetProperties
,
133 base::Unretained(wifi_service_
.get()), guid
,
134 properties_ptr
, error
),
135 base::Bind(&NetworkingPrivateServiceClient::AfterGetProperties
,
136 weak_factory_
.GetWeakPtr(), service_callbacks
->id
, guid
,
137 base::Passed(&properties
), base::Owned(error
)));
140 void NetworkingPrivateServiceClient::GetManagedProperties(
141 const std::string
& guid
,
142 const DictionaryCallback
& success_callback
,
143 const FailureCallback
& failure_callback
) {
144 ServiceCallbacks
* service_callbacks
= AddServiceCallbacks();
145 service_callbacks
->failure_callback
= failure_callback
;
146 service_callbacks
->get_properties_callback
= success_callback
;
148 scoped_ptr
<base::DictionaryValue
> properties(new base::DictionaryValue
);
149 std::string
* error
= new std::string
;
151 base::DictionaryValue
* properties_ptr
= properties
.get();
152 task_runner_
->PostTaskAndReply(
153 FROM_HERE
, base::Bind(&WiFiService::GetManagedProperties
,
154 base::Unretained(wifi_service_
.get()), guid
,
155 properties_ptr
, error
),
156 base::Bind(&NetworkingPrivateServiceClient::AfterGetProperties
,
157 weak_factory_
.GetWeakPtr(), service_callbacks
->id
, guid
,
158 base::Passed(&properties
), base::Owned(error
)));
161 void NetworkingPrivateServiceClient::GetState(
162 const std::string
& guid
,
163 const DictionaryCallback
& success_callback
,
164 const FailureCallback
& failure_callback
) {
165 ServiceCallbacks
* service_callbacks
= AddServiceCallbacks();
166 service_callbacks
->failure_callback
= failure_callback
;
167 service_callbacks
->get_properties_callback
= success_callback
;
169 scoped_ptr
<base::DictionaryValue
> properties(new base::DictionaryValue
);
170 std::string
* error
= new std::string
;
172 base::DictionaryValue
* properties_ptr
= properties
.get();
173 task_runner_
->PostTaskAndReply(
175 base::Bind(&WiFiService::GetState
, base::Unretained(wifi_service_
.get()),
176 guid
, properties_ptr
, error
),
177 base::Bind(&NetworkingPrivateServiceClient::AfterGetProperties
,
178 weak_factory_
.GetWeakPtr(), service_callbacks
->id
, guid
,
179 base::Passed(&properties
), base::Owned(error
)));
182 void NetworkingPrivateServiceClient::SetProperties(
183 const std::string
& guid
,
184 scoped_ptr
<base::DictionaryValue
> properties
,
185 const VoidCallback
& success_callback
,
186 const FailureCallback
& failure_callback
) {
187 ServiceCallbacks
* service_callbacks
= AddServiceCallbacks();
188 service_callbacks
->failure_callback
= failure_callback
;
189 service_callbacks
->set_properties_callback
= success_callback
;
191 std::string
* error
= new std::string
;
193 task_runner_
->PostTaskAndReply(
194 FROM_HERE
, base::Bind(&WiFiService::SetProperties
,
195 base::Unretained(wifi_service_
.get()), guid
,
196 base::Passed(&properties
), error
),
197 base::Bind(&NetworkingPrivateServiceClient::AfterSetProperties
,
198 weak_factory_
.GetWeakPtr(), service_callbacks
->id
,
199 base::Owned(error
)));
202 void NetworkingPrivateServiceClient::CreateNetwork(
204 scoped_ptr
<base::DictionaryValue
> properties
,
205 const StringCallback
& success_callback
,
206 const FailureCallback
& failure_callback
) {
207 ServiceCallbacks
* service_callbacks
= AddServiceCallbacks();
208 service_callbacks
->failure_callback
= failure_callback
;
209 service_callbacks
->create_network_callback
= success_callback
;
211 std::string
* network_guid
= new std::string
;
212 std::string
* error
= new std::string
;
214 task_runner_
->PostTaskAndReply(
215 FROM_HERE
, base::Bind(&WiFiService::CreateNetwork
,
216 base::Unretained(wifi_service_
.get()), shared
,
217 base::Passed(&properties
), network_guid
, error
),
218 base::Bind(&NetworkingPrivateServiceClient::AfterCreateNetwork
,
219 weak_factory_
.GetWeakPtr(), service_callbacks
->id
,
220 base::Owned(network_guid
), base::Owned(error
)));
223 void NetworkingPrivateServiceClient::ForgetNetwork(
224 const std::string
& guid
,
225 const VoidCallback
& success_callback
,
226 const FailureCallback
& failure_callback
) {
227 // TODO(mef): Implement for Win/Mac
228 failure_callback
.Run(networking_private::kErrorNotSupported
);
231 void NetworkingPrivateServiceClient::GetNetworks(
232 const std::string
& network_type
,
233 bool configured_only
,
236 const NetworkListCallback
& success_callback
,
237 const FailureCallback
& failure_callback
) {
238 ServiceCallbacks
* service_callbacks
= AddServiceCallbacks();
239 service_callbacks
->failure_callback
= failure_callback
;
240 service_callbacks
->get_visible_networks_callback
= success_callback
;
242 scoped_ptr
<base::ListValue
> networks(new base::ListValue
);
244 // TODO(stevenjb/mef): Apply filters (configured, visible, limit).
246 base::ListValue
* networks_ptr
= networks
.get();
247 task_runner_
->PostTaskAndReply(
248 FROM_HERE
, base::Bind(&WiFiService::GetVisibleNetworks
,
249 base::Unretained(wifi_service_
.get()), network_type
,
250 networks_ptr
, false),
251 base::Bind(&NetworkingPrivateServiceClient::AfterGetVisibleNetworks
,
252 weak_factory_
.GetWeakPtr(), service_callbacks
->id
,
253 base::Passed(&networks
)));
256 void NetworkingPrivateServiceClient::StartConnect(
257 const std::string
& guid
,
258 const VoidCallback
& success_callback
,
259 const FailureCallback
& failure_callback
) {
260 ServiceCallbacks
* service_callbacks
= AddServiceCallbacks();
261 service_callbacks
->failure_callback
= failure_callback
;
262 service_callbacks
->start_connect_callback
= success_callback
;
264 std::string
* error
= new std::string
;
266 task_runner_
->PostTaskAndReply(
267 FROM_HERE
, base::Bind(&WiFiService::StartConnect
,
268 base::Unretained(wifi_service_
.get()), guid
, error
),
269 base::Bind(&NetworkingPrivateServiceClient::AfterStartConnect
,
270 weak_factory_
.GetWeakPtr(), service_callbacks
->id
,
271 base::Owned(error
)));
274 void NetworkingPrivateServiceClient::StartDisconnect(
275 const std::string
& guid
,
276 const VoidCallback
& success_callback
,
277 const FailureCallback
& failure_callback
) {
278 ServiceCallbacks
* service_callbacks
= AddServiceCallbacks();
279 service_callbacks
->failure_callback
= failure_callback
;
280 service_callbacks
->start_disconnect_callback
= success_callback
;
282 std::string
* error
= new std::string
;
284 task_runner_
->PostTaskAndReply(
285 FROM_HERE
, base::Bind(&WiFiService::StartDisconnect
,
286 base::Unretained(wifi_service_
.get()), guid
, error
),
287 base::Bind(&NetworkingPrivateServiceClient::AfterStartDisconnect
,
288 weak_factory_
.GetWeakPtr(), service_callbacks
->id
,
289 base::Owned(error
)));
292 void NetworkingPrivateServiceClient::SetWifiTDLSEnabledState(
293 const std::string
& ip_or_mac_address
,
295 const StringCallback
& success_callback
,
296 const FailureCallback
& failure_callback
) {
297 failure_callback
.Run(networking_private::kErrorNotSupported
);
300 void NetworkingPrivateServiceClient::GetWifiTDLSStatus(
301 const std::string
& ip_or_mac_address
,
302 const StringCallback
& success_callback
,
303 const FailureCallback
& failure_callback
) {
304 failure_callback
.Run(networking_private::kErrorNotSupported
);
307 void NetworkingPrivateServiceClient::GetCaptivePortalStatus(
308 const std::string
& guid
,
309 const StringCallback
& success_callback
,
310 const FailureCallback
& failure_callback
) {
311 failure_callback
.Run(networking_private::kErrorNotSupported
);
314 scoped_ptr
<base::ListValue
>
315 NetworkingPrivateServiceClient::GetEnabledNetworkTypes() {
316 scoped_ptr
<base::ListValue
> network_list
;
317 network_list
->AppendString(::onc::network_type::kWiFi
);
318 return network_list
.Pass();
321 scoped_ptr
<NetworkingPrivateDelegate::DeviceStateList
>
322 NetworkingPrivateServiceClient::GetDeviceStateList() {
323 scoped_ptr
<DeviceStateList
> device_state_list(new DeviceStateList
);
324 scoped_ptr
<core_api::networking_private::DeviceStateProperties
> properties(
325 new core_api::networking_private::DeviceStateProperties
);
326 properties
->type
= core_api::networking_private::NETWORK_TYPE_WIFI
;
327 properties
->state
= core_api::networking_private::DEVICE_STATE_TYPE_ENABLED
;
328 device_state_list
->push_back(properties
.Pass());
329 return device_state_list
.Pass();
332 bool NetworkingPrivateServiceClient::EnableNetworkType(
333 const std::string
& type
) {
337 bool NetworkingPrivateServiceClient::DisableNetworkType(
338 const std::string
& type
) {
342 bool NetworkingPrivateServiceClient::RequestScan() {
343 task_runner_
->PostTask(FROM_HERE
,
344 base::Bind(&WiFiService::RequestNetworkScan
,
345 base::Unretained(wifi_service_
.get())));
349 ////////////////////////////////////////////////////////////////////////////////
351 void NetworkingPrivateServiceClient::AfterGetProperties(
352 ServiceCallbacksID callback_id
,
353 const std::string
& network_guid
,
354 scoped_ptr
<base::DictionaryValue
> properties
,
355 const std::string
* error
) {
356 ServiceCallbacks
* service_callbacks
= callbacks_map_
.Lookup(callback_id
);
357 DCHECK(service_callbacks
);
358 if (!error
->empty()) {
359 DCHECK(!service_callbacks
->failure_callback
.is_null());
360 service_callbacks
->failure_callback
.Run(*error
);
362 DCHECK(!service_callbacks
->get_properties_callback
.is_null());
363 service_callbacks
->get_properties_callback
.Run(properties
.Pass());
365 RemoveServiceCallbacks(callback_id
);
368 void NetworkingPrivateServiceClient::AfterGetVisibleNetworks(
369 ServiceCallbacksID callback_id
,
370 scoped_ptr
<base::ListValue
> networks
) {
371 ServiceCallbacks
* service_callbacks
= callbacks_map_
.Lookup(callback_id
);
372 DCHECK(service_callbacks
);
373 DCHECK(!service_callbacks
->get_visible_networks_callback
.is_null());
374 service_callbacks
->get_visible_networks_callback
.Run(networks
.Pass());
375 RemoveServiceCallbacks(callback_id
);
378 void NetworkingPrivateServiceClient::AfterSetProperties(
379 ServiceCallbacksID callback_id
,
380 const std::string
* error
) {
381 ServiceCallbacks
* service_callbacks
= callbacks_map_
.Lookup(callback_id
);
382 DCHECK(service_callbacks
);
383 if (!error
->empty()) {
384 DCHECK(!service_callbacks
->failure_callback
.is_null());
385 service_callbacks
->failure_callback
.Run(*error
);
387 DCHECK(!service_callbacks
->set_properties_callback
.is_null());
388 service_callbacks
->set_properties_callback
.Run();
390 RemoveServiceCallbacks(callback_id
);
393 void NetworkingPrivateServiceClient::AfterCreateNetwork(
394 ServiceCallbacksID callback_id
,
395 const std::string
* network_guid
,
396 const std::string
* error
) {
397 ServiceCallbacks
* service_callbacks
= callbacks_map_
.Lookup(callback_id
);
398 DCHECK(service_callbacks
);
399 if (!error
->empty()) {
400 DCHECK(!service_callbacks
->failure_callback
.is_null());
401 service_callbacks
->failure_callback
.Run(*error
);
403 DCHECK(!service_callbacks
->create_network_callback
.is_null());
404 service_callbacks
->create_network_callback
.Run(*network_guid
);
406 RemoveServiceCallbacks(callback_id
);
409 void NetworkingPrivateServiceClient::AfterStartConnect(
410 ServiceCallbacksID callback_id
,
411 const std::string
* error
) {
412 ServiceCallbacks
* service_callbacks
= callbacks_map_
.Lookup(callback_id
);
413 DCHECK(service_callbacks
);
414 if (!error
->empty()) {
415 DCHECK(!service_callbacks
->failure_callback
.is_null());
416 service_callbacks
->failure_callback
.Run(*error
);
418 DCHECK(!service_callbacks
->start_connect_callback
.is_null());
419 service_callbacks
->start_connect_callback
.Run();
421 RemoveServiceCallbacks(callback_id
);
424 void NetworkingPrivateServiceClient::AfterStartDisconnect(
425 ServiceCallbacksID callback_id
,
426 const std::string
* error
) {
427 ServiceCallbacks
* service_callbacks
= callbacks_map_
.Lookup(callback_id
);
428 DCHECK(service_callbacks
);
429 if (!error
->empty()) {
430 DCHECK(!service_callbacks
->failure_callback
.is_null());
431 service_callbacks
->failure_callback
.Run(*error
);
433 DCHECK(!service_callbacks
->start_disconnect_callback
.is_null());
434 service_callbacks
->start_disconnect_callback
.Run();
436 RemoveServiceCallbacks(callback_id
);
439 void NetworkingPrivateServiceClient::OnNetworksChangedEventOnUIThread(
440 const std::vector
<std::string
>& network_guids
) {
441 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
442 FOR_EACH_OBSERVER(NetworkingPrivateDelegateObserver
,
443 network_events_observers_
,
444 OnNetworksChangedEvent(network_guids
));
447 void NetworkingPrivateServiceClient::OnNetworkListChangedEventOnUIThread(
448 const std::vector
<std::string
>& network_guids
) {
449 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
450 FOR_EACH_OBSERVER(NetworkingPrivateDelegateObserver
,
451 network_events_observers_
,
452 OnNetworkListChangedEvent(network_guids
));
455 } // namespace extensions