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.
5 #include "extensions/browser/api/networking_private/networking_private_chromeos.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "chromeos/dbus/dbus_thread_manager.h"
11 #include "chromeos/dbus/shill_manager_client.h"
12 #include "chromeos/login/login_state.h"
13 #include "chromeos/network/device_state.h"
14 #include "chromeos/network/managed_network_configuration_handler.h"
15 #include "chromeos/network/network_activation_handler.h"
16 #include "chromeos/network/network_connection_handler.h"
17 #include "chromeos/network/network_device_handler.h"
18 #include "chromeos/network/network_event_log.h"
19 #include "chromeos/network/network_state.h"
20 #include "chromeos/network/network_state_handler.h"
21 #include "chromeos/network/network_util.h"
22 #include "chromeos/network/onc/onc_signature.h"
23 #include "chromeos/network/onc/onc_translator.h"
24 #include "chromeos/network/onc/onc_utils.h"
25 #include "chromeos/network/portal_detector/network_portal_detector.h"
26 #include "components/onc/onc_constants.h"
27 #include "content/public/browser/browser_context.h"
28 #include "extensions/browser/api/networking_private/networking_private_api.h"
29 #include "extensions/browser/extensions_browser_client.h"
31 using chromeos::DeviceState
;
32 using chromeos::NetworkHandler
;
33 using chromeos::NetworkStateHandler
;
34 using chromeos::NetworkTypePattern
;
35 using chromeos::ShillManagerClient
;
36 using extensions::NetworkingPrivateDelegate
;
38 namespace private_api
= extensions::core_api::networking_private
;
42 chromeos::NetworkStateHandler
* GetStateHandler() {
43 return NetworkHandler::Get()->network_state_handler();
46 chromeos::ManagedNetworkConfigurationHandler
* GetManagedConfigurationHandler() {
47 return NetworkHandler::Get()->managed_network_configuration_handler();
50 bool GetServicePathFromGuid(const std::string
& guid
,
51 std::string
* service_path
,
53 const chromeos::NetworkState
* network
=
54 GetStateHandler()->GetNetworkStateFromGuid(guid
);
56 *error
= extensions::networking_private::kErrorInvalidNetworkGuid
;
59 *service_path
= network
->path();
63 bool GetUserIdHash(content::BrowserContext
* browser_context
,
64 std::string
* user_hash
,
66 std::string context_user_hash
=
67 extensions::ExtensionsBrowserClient::Get()->GetUserIdHashFromContext(
70 // Currently Chrome OS only configures networks for the primary user.
71 // Configuration attempts from other browser contexts should fail.
72 if (context_user_hash
!= chromeos::LoginState::Get()->primary_user_hash()) {
73 // Disallow class requiring a user id hash from a non-primary user context
74 // to avoid complexities with the policy code.
75 LOG(ERROR
) << "networkingPrivate API call from non primary user: "
77 *error
= "Error.NonPrimaryUser";
80 *user_hash
= context_user_hash
;
84 void AppendDeviceState(
85 const std::string
& type
,
86 const DeviceState
* device
,
87 NetworkingPrivateDelegate::DeviceStateList
* device_state_list
) {
88 DCHECK(!type
.empty());
89 NetworkTypePattern pattern
=
90 chromeos::onc::NetworkTypePatternFromOncType(type
);
91 NetworkStateHandler::TechnologyState technology_state
=
92 GetStateHandler()->GetTechnologyState(pattern
);
93 private_api::DeviceStateType state
= private_api::DEVICE_STATE_TYPE_NONE
;
94 switch (technology_state
) {
95 case NetworkStateHandler::TECHNOLOGY_UNAVAILABLE
:
98 // If we have a DeviceState entry but the technology is not available,
99 // assume the technology is not initialized.
100 state
= private_api::DEVICE_STATE_TYPE_UNINITIALIZED
;
102 case NetworkStateHandler::TECHNOLOGY_AVAILABLE
:
103 state
= private_api::DEVICE_STATE_TYPE_DISABLED
;
105 case NetworkStateHandler::TECHNOLOGY_UNINITIALIZED
:
106 state
= private_api::DEVICE_STATE_TYPE_UNINITIALIZED
;
108 case NetworkStateHandler::TECHNOLOGY_ENABLING
:
109 state
= private_api::DEVICE_STATE_TYPE_ENABLING
;
111 case NetworkStateHandler::TECHNOLOGY_ENABLED
:
112 state
= private_api::DEVICE_STATE_TYPE_ENABLED
;
115 DCHECK_NE(private_api::DEVICE_STATE_TYPE_NONE
, state
);
116 scoped_ptr
<private_api::DeviceStateProperties
> properties(
117 new private_api::DeviceStateProperties
);
118 properties
->type
= private_api::ParseNetworkType(type
);
119 properties
->state
= state
;
120 if (device
&& state
== private_api::DEVICE_STATE_TYPE_ENABLED
)
121 properties
->scanning
.reset(new bool(device
->scanning()));
122 device_state_list
->push_back(properties
.Pass());
125 void NetworkHandlerDictionaryCallback(
126 const NetworkingPrivateDelegate::DictionaryCallback
& callback
,
127 const std::string
& service_path
,
128 const base::DictionaryValue
& dictionary
) {
129 scoped_ptr
<base::DictionaryValue
> dictionary_copy(dictionary
.DeepCopy());
130 callback
.Run(dictionary_copy
.Pass());
133 void NetworkHandlerFailureCallback(
134 const NetworkingPrivateDelegate::FailureCallback
& callback
,
135 const std::string
& error_name
,
136 scoped_ptr
<base::DictionaryValue
> error_data
) {
137 callback
.Run(error_name
);
142 ////////////////////////////////////////////////////////////////////////////////
144 namespace extensions
{
146 NetworkingPrivateChromeOS::NetworkingPrivateChromeOS(
147 content::BrowserContext
* browser_context
,
148 scoped_ptr
<VerifyDelegate
> verify_delegate
)
149 : NetworkingPrivateDelegate(verify_delegate
.Pass()),
150 browser_context_(browser_context
) {
153 NetworkingPrivateChromeOS::~NetworkingPrivateChromeOS() {
156 void NetworkingPrivateChromeOS::GetProperties(
157 const std::string
& guid
,
158 const DictionaryCallback
& success_callback
,
159 const FailureCallback
& failure_callback
) {
160 std::string service_path
, error
;
161 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
162 failure_callback
.Run(error
);
166 GetManagedConfigurationHandler()->GetProperties(
168 base::Bind(&NetworkHandlerDictionaryCallback
, success_callback
),
169 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
172 void NetworkingPrivateChromeOS::GetManagedProperties(
173 const std::string
& guid
,
174 const DictionaryCallback
& success_callback
,
175 const FailureCallback
& failure_callback
) {
176 std::string service_path
, error
;
177 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
178 failure_callback
.Run(error
);
182 std::string user_id_hash
;
183 if (!GetUserIdHash(browser_context_
, &user_id_hash
, &error
)) {
184 failure_callback
.Run(error
);
188 GetManagedConfigurationHandler()->GetManagedProperties(
189 user_id_hash
, service_path
,
190 base::Bind(&NetworkHandlerDictionaryCallback
, success_callback
),
191 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
194 void NetworkingPrivateChromeOS::GetState(
195 const std::string
& guid
,
196 const DictionaryCallback
& success_callback
,
197 const FailureCallback
& failure_callback
) {
198 std::string service_path
, error
;
199 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
200 failure_callback
.Run(error
);
204 const chromeos::NetworkState
* network_state
=
205 GetStateHandler()->GetNetworkStateFromServicePath(
206 service_path
, false /* configured_only */);
207 if (!network_state
) {
208 failure_callback
.Run(networking_private::kErrorNetworkUnavailable
);
212 scoped_ptr
<base::DictionaryValue
> network_properties
=
213 chromeos::network_util::TranslateNetworkStateToONC(network_state
);
215 success_callback
.Run(network_properties
.Pass());
218 void NetworkingPrivateChromeOS::SetProperties(
219 const std::string
& guid
,
220 scoped_ptr
<base::DictionaryValue
> properties
,
221 const VoidCallback
& success_callback
,
222 const FailureCallback
& failure_callback
) {
223 std::string service_path
, error
;
224 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
225 failure_callback
.Run(error
);
229 GetManagedConfigurationHandler()->SetProperties(
230 service_path
, *properties
, success_callback
,
231 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
234 void NetworkingPrivateChromeOS::CreateNetwork(
236 scoped_ptr
<base::DictionaryValue
> properties
,
237 const StringCallback
& success_callback
,
238 const FailureCallback
& failure_callback
) {
239 std::string user_id_hash
, error
;
240 // Do not allow configuring a non-shared network from a non-primary user.
241 if (!shared
&& !GetUserIdHash(browser_context_
, &user_id_hash
, &error
)) {
242 failure_callback
.Run(error
);
246 GetManagedConfigurationHandler()->CreateConfiguration(
247 user_id_hash
, *properties
, success_callback
,
248 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
251 void NetworkingPrivateChromeOS::ForgetNetwork(
252 const std::string
& guid
,
253 const VoidCallback
& success_callback
,
254 const FailureCallback
& failure_callback
) {
255 std::string service_path
, error
;
256 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
257 failure_callback
.Run(error
);
261 GetManagedConfigurationHandler()->RemoveConfiguration(
262 service_path
, success_callback
,
263 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
266 void NetworkingPrivateChromeOS::GetNetworks(
267 const std::string
& network_type
,
268 bool configured_only
,
271 const NetworkListCallback
& success_callback
,
272 const FailureCallback
& failure_callback
) {
273 NetworkTypePattern pattern
=
274 chromeos::onc::NetworkTypePatternFromOncType(network_type
);
275 scoped_ptr
<base::ListValue
> network_properties_list
=
276 chromeos::network_util::TranslateNetworkListToONC(
277 pattern
, configured_only
, visible_only
, limit
, false /* debugging */);
278 success_callback
.Run(network_properties_list
.Pass());
281 void NetworkingPrivateChromeOS::StartConnect(
282 const std::string
& guid
,
283 const VoidCallback
& success_callback
,
284 const FailureCallback
& failure_callback
) {
285 std::string service_path
, error
;
286 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
287 failure_callback
.Run(error
);
291 const bool check_error_state
= false;
292 NetworkHandler::Get()->network_connection_handler()->ConnectToNetwork(
293 service_path
, success_callback
,
294 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
),
298 void NetworkingPrivateChromeOS::StartDisconnect(
299 const std::string
& guid
,
300 const VoidCallback
& success_callback
,
301 const FailureCallback
& failure_callback
) {
302 std::string service_path
, error
;
303 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
304 failure_callback
.Run(error
);
308 NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork(
309 service_path
, success_callback
,
310 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
313 void NetworkingPrivateChromeOS::StartActivate(
314 const std::string
& guid
,
315 const std::string
& carrier
,
316 const VoidCallback
& success_callback
,
317 const FailureCallback
& failure_callback
) {
318 std::string service_path
, error
;
319 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
320 failure_callback
.Run(error
);
324 NetworkHandler::Get()->network_activation_handler()->Activate(
325 service_path
, carrier
, success_callback
,
326 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
329 void NetworkingPrivateChromeOS::SetWifiTDLSEnabledState(
330 const std::string
& ip_or_mac_address
,
332 const StringCallback
& success_callback
,
333 const FailureCallback
& failure_callback
) {
334 NetworkHandler::Get()->network_device_handler()->SetWifiTDLSEnabled(
335 ip_or_mac_address
, enabled
, success_callback
,
336 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
339 void NetworkingPrivateChromeOS::GetWifiTDLSStatus(
340 const std::string
& ip_or_mac_address
,
341 const StringCallback
& success_callback
,
342 const FailureCallback
& failure_callback
) {
343 NetworkHandler::Get()->network_device_handler()->GetWifiTDLSStatus(
344 ip_or_mac_address
, success_callback
,
345 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
348 void NetworkingPrivateChromeOS::GetCaptivePortalStatus(
349 const std::string
& guid
,
350 const StringCallback
& success_callback
,
351 const FailureCallback
& failure_callback
) {
352 if (!chromeos::NetworkPortalDetector::IsInitialized()) {
353 failure_callback
.Run(networking_private::kErrorNotReady
);
357 chromeos::NetworkPortalDetector::CaptivePortalState state
=
358 chromeos::NetworkPortalDetector::Get()->GetCaptivePortalState(guid
);
359 success_callback
.Run(
360 chromeos::NetworkPortalDetector::CaptivePortalStatusString(state
.status
));
363 scoped_ptr
<base::ListValue
>
364 NetworkingPrivateChromeOS::GetEnabledNetworkTypes() {
365 chromeos::NetworkStateHandler
* state_handler
= GetStateHandler();
367 scoped_ptr
<base::ListValue
> network_list(new base::ListValue
);
369 if (state_handler
->IsTechnologyEnabled(NetworkTypePattern::Ethernet()))
370 network_list
->AppendString(::onc::network_type::kEthernet
);
371 if (state_handler
->IsTechnologyEnabled(NetworkTypePattern::WiFi()))
372 network_list
->AppendString(::onc::network_type::kWiFi
);
373 if (state_handler
->IsTechnologyEnabled(NetworkTypePattern::Wimax()))
374 network_list
->AppendString(::onc::network_type::kWimax
);
375 if (state_handler
->IsTechnologyEnabled(NetworkTypePattern::Cellular()))
376 network_list
->AppendString(::onc::network_type::kCellular
);
378 return network_list
.Pass();
381 scoped_ptr
<NetworkingPrivateDelegate::DeviceStateList
>
382 NetworkingPrivateChromeOS::GetDeviceStateList() {
383 std::set
<std::string
> technologies_found
;
384 NetworkStateHandler::DeviceStateList devices
;
385 NetworkHandler::Get()->network_state_handler()->GetDeviceList(&devices
);
387 scoped_ptr
<DeviceStateList
> device_state_list(new DeviceStateList
);
388 for (const DeviceState
* device
: devices
) {
389 std::string onc_type
=
390 chromeos::network_util::TranslateShillTypeToONC(device
->type());
391 AppendDeviceState(onc_type
, device
, device_state_list
.get());
392 technologies_found
.insert(onc_type
);
395 // For any technologies that we do not have a DeviceState entry for, append
396 // an entry if the technolog is available.
397 const char* technology_types
[] = {::onc::network_type::kEthernet
,
398 ::onc::network_type::kWiFi
,
399 ::onc::network_type::kWimax
,
400 ::onc::network_type::kCellular
};
401 for (const char* technology
: technology_types
) {
402 if (ContainsValue(technologies_found
, technology
))
404 AppendDeviceState(technology
, nullptr /* device */,
405 device_state_list
.get());
407 return device_state_list
.Pass();
410 bool NetworkingPrivateChromeOS::EnableNetworkType(const std::string
& type
) {
411 NetworkTypePattern pattern
=
412 chromeos::onc::NetworkTypePatternFromOncType(type
);
414 GetStateHandler()->SetTechnologyEnabled(
415 pattern
, true, chromeos::network_handler::ErrorCallback());
420 bool NetworkingPrivateChromeOS::DisableNetworkType(const std::string
& type
) {
421 NetworkTypePattern pattern
=
422 chromeos::onc::NetworkTypePatternFromOncType(type
);
424 GetStateHandler()->SetTechnologyEnabled(
425 pattern
, false, chromeos::network_handler::ErrorCallback());
430 bool NetworkingPrivateChromeOS::RequestScan() {
431 GetStateHandler()->RequestScan();
435 } // namespace extensions