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"
30 #include "third_party/cros_system_api/dbus/service_constants.h"
32 using chromeos::DeviceState
;
33 using chromeos::NetworkHandler
;
34 using chromeos::NetworkStateHandler
;
35 using chromeos::NetworkTypePattern
;
36 using chromeos::ShillManagerClient
;
37 using extensions::NetworkingPrivateDelegate
;
39 namespace private_api
= extensions::api::networking_private
;
43 chromeos::NetworkStateHandler
* GetStateHandler() {
44 return NetworkHandler::Get()->network_state_handler();
47 chromeos::ManagedNetworkConfigurationHandler
* GetManagedConfigurationHandler() {
48 return NetworkHandler::Get()->managed_network_configuration_handler();
51 bool GetServicePathFromGuid(const std::string
& guid
,
52 std::string
* service_path
,
54 const chromeos::NetworkState
* network
=
55 GetStateHandler()->GetNetworkStateFromGuid(guid
);
57 *error
= extensions::networking_private::kErrorInvalidNetworkGuid
;
60 *service_path
= network
->path();
64 bool GetUserIdHash(content::BrowserContext
* browser_context
,
65 std::string
* user_hash
,
67 std::string context_user_hash
=
68 extensions::ExtensionsBrowserClient::Get()->GetUserIdHashFromContext(
71 // Currently Chrome OS only configures networks for the primary user.
72 // Configuration attempts from other browser contexts should fail.
73 if (context_user_hash
!= chromeos::LoginState::Get()->primary_user_hash()) {
74 // Disallow class requiring a user id hash from a non-primary user context
75 // to avoid complexities with the policy code.
76 LOG(ERROR
) << "networkingPrivate API call from non primary user: "
78 *error
= "Error.NonPrimaryUser";
81 *user_hash
= context_user_hash
;
85 void AppendDeviceState(
86 const std::string
& type
,
87 const DeviceState
* device
,
88 NetworkingPrivateDelegate::DeviceStateList
* device_state_list
) {
89 DCHECK(!type
.empty());
90 NetworkTypePattern pattern
=
91 chromeos::onc::NetworkTypePatternFromOncType(type
);
92 NetworkStateHandler::TechnologyState technology_state
=
93 GetStateHandler()->GetTechnologyState(pattern
);
94 private_api::DeviceStateType state
= private_api::DEVICE_STATE_TYPE_NONE
;
95 switch (technology_state
) {
96 case NetworkStateHandler::TECHNOLOGY_UNAVAILABLE
:
99 // If we have a DeviceState entry but the technology is not available,
100 // assume the technology is not initialized.
101 state
= private_api::DEVICE_STATE_TYPE_UNINITIALIZED
;
103 case NetworkStateHandler::TECHNOLOGY_AVAILABLE
:
104 state
= private_api::DEVICE_STATE_TYPE_DISABLED
;
106 case NetworkStateHandler::TECHNOLOGY_UNINITIALIZED
:
107 state
= private_api::DEVICE_STATE_TYPE_UNINITIALIZED
;
109 case NetworkStateHandler::TECHNOLOGY_ENABLING
:
110 state
= private_api::DEVICE_STATE_TYPE_ENABLING
;
112 case NetworkStateHandler::TECHNOLOGY_ENABLED
:
113 state
= private_api::DEVICE_STATE_TYPE_ENABLED
;
116 DCHECK_NE(private_api::DEVICE_STATE_TYPE_NONE
, state
);
117 scoped_ptr
<private_api::DeviceStateProperties
> properties(
118 new private_api::DeviceStateProperties
);
119 properties
->type
= private_api::ParseNetworkType(type
);
120 properties
->state
= state
;
121 if (device
&& state
== private_api::DEVICE_STATE_TYPE_ENABLED
)
122 properties
->scanning
.reset(new bool(device
->scanning()));
123 device_state_list
->push_back(properties
.Pass());
126 void NetworkHandlerDictionaryCallback(
127 const NetworkingPrivateDelegate::DictionaryCallback
& callback
,
128 const std::string
& service_path
,
129 const base::DictionaryValue
& dictionary
) {
130 scoped_ptr
<base::DictionaryValue
> dictionary_copy(dictionary
.DeepCopy());
131 callback
.Run(dictionary_copy
.Pass());
134 void NetworkHandlerFailureCallback(
135 const NetworkingPrivateDelegate::FailureCallback
& callback
,
136 const std::string
& error_name
,
137 scoped_ptr
<base::DictionaryValue
> error_data
) {
138 callback
.Run(error_name
);
141 void RequirePinSuccess(
142 const std::string
& device_path
,
143 const std::string
& current_pin
,
144 const std::string
& new_pin
,
145 const extensions::NetworkingPrivateChromeOS::VoidCallback
& success_callback
,
146 const extensions::NetworkingPrivateChromeOS::FailureCallback
&
148 // After RequirePin succeeds, call ChangePIN iff a different new_pin is
150 if (new_pin
.empty() || new_pin
== current_pin
) {
151 success_callback
.Run();
154 NetworkHandler::Get()->network_device_handler()->ChangePin(
155 device_path
, current_pin
, new_pin
, success_callback
,
156 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
161 ////////////////////////////////////////////////////////////////////////////////
163 namespace extensions
{
165 NetworkingPrivateChromeOS::NetworkingPrivateChromeOS(
166 content::BrowserContext
* browser_context
,
167 scoped_ptr
<VerifyDelegate
> verify_delegate
)
168 : NetworkingPrivateDelegate(verify_delegate
.Pass()),
169 browser_context_(browser_context
) {
172 NetworkingPrivateChromeOS::~NetworkingPrivateChromeOS() {
175 void NetworkingPrivateChromeOS::GetProperties(
176 const std::string
& guid
,
177 const DictionaryCallback
& success_callback
,
178 const FailureCallback
& failure_callback
) {
179 std::string service_path
, error
;
180 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
181 failure_callback
.Run(error
);
185 GetManagedConfigurationHandler()->GetProperties(
187 base::Bind(&NetworkHandlerDictionaryCallback
, success_callback
),
188 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
191 void NetworkingPrivateChromeOS::GetManagedProperties(
192 const std::string
& guid
,
193 const DictionaryCallback
& success_callback
,
194 const FailureCallback
& failure_callback
) {
195 std::string service_path
, error
;
196 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
197 failure_callback
.Run(error
);
201 std::string user_id_hash
;
202 if (!GetUserIdHash(browser_context_
, &user_id_hash
, &error
)) {
203 failure_callback
.Run(error
);
207 GetManagedConfigurationHandler()->GetManagedProperties(
208 user_id_hash
, service_path
,
209 base::Bind(&NetworkHandlerDictionaryCallback
, success_callback
),
210 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
213 void NetworkingPrivateChromeOS::GetState(
214 const std::string
& guid
,
215 const DictionaryCallback
& success_callback
,
216 const FailureCallback
& failure_callback
) {
217 std::string service_path
, error
;
218 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
219 failure_callback
.Run(error
);
223 const chromeos::NetworkState
* network_state
=
224 GetStateHandler()->GetNetworkStateFromServicePath(
225 service_path
, false /* configured_only */);
226 if (!network_state
) {
227 failure_callback
.Run(networking_private::kErrorNetworkUnavailable
);
231 scoped_ptr
<base::DictionaryValue
> network_properties
=
232 chromeos::network_util::TranslateNetworkStateToONC(network_state
);
234 success_callback
.Run(network_properties
.Pass());
237 void NetworkingPrivateChromeOS::SetProperties(
238 const std::string
& guid
,
239 scoped_ptr
<base::DictionaryValue
> properties
,
240 const VoidCallback
& success_callback
,
241 const FailureCallback
& failure_callback
) {
242 std::string service_path
, error
;
243 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
244 failure_callback
.Run(error
);
248 GetManagedConfigurationHandler()->SetProperties(
249 service_path
, *properties
, success_callback
,
250 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
253 void NetworkingPrivateChromeOS::CreateNetwork(
255 scoped_ptr
<base::DictionaryValue
> properties
,
256 const StringCallback
& success_callback
,
257 const FailureCallback
& failure_callback
) {
258 std::string user_id_hash
, error
;
259 // Do not allow configuring a non-shared network from a non-primary user.
260 if (!shared
&& !GetUserIdHash(browser_context_
, &user_id_hash
, &error
)) {
261 failure_callback
.Run(error
);
265 GetManagedConfigurationHandler()->CreateConfiguration(
266 user_id_hash
, *properties
, success_callback
,
267 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
270 void NetworkingPrivateChromeOS::ForgetNetwork(
271 const std::string
& guid
,
272 const VoidCallback
& success_callback
,
273 const FailureCallback
& failure_callback
) {
274 std::string service_path
, error
;
275 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
276 failure_callback
.Run(error
);
280 GetManagedConfigurationHandler()->RemoveConfiguration(
281 service_path
, success_callback
,
282 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
285 void NetworkingPrivateChromeOS::GetNetworks(
286 const std::string
& network_type
,
287 bool configured_only
,
290 const NetworkListCallback
& success_callback
,
291 const FailureCallback
& failure_callback
) {
292 NetworkTypePattern pattern
=
293 chromeos::onc::NetworkTypePatternFromOncType(network_type
);
294 scoped_ptr
<base::ListValue
> network_properties_list
=
295 chromeos::network_util::TranslateNetworkListToONC(
296 pattern
, configured_only
, visible_only
, limit
, false /* debugging */);
297 success_callback
.Run(network_properties_list
.Pass());
300 void NetworkingPrivateChromeOS::StartConnect(
301 const std::string
& guid
,
302 const VoidCallback
& success_callback
,
303 const FailureCallback
& failure_callback
) {
304 std::string service_path
, error
;
305 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
306 failure_callback
.Run(error
);
310 const bool check_error_state
= false;
311 NetworkHandler::Get()->network_connection_handler()->ConnectToNetwork(
312 service_path
, success_callback
,
313 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
),
317 void NetworkingPrivateChromeOS::StartDisconnect(
318 const std::string
& guid
,
319 const VoidCallback
& success_callback
,
320 const FailureCallback
& failure_callback
) {
321 std::string service_path
, error
;
322 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
323 failure_callback
.Run(error
);
327 NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork(
328 service_path
, success_callback
,
329 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
332 void NetworkingPrivateChromeOS::StartActivate(
333 const std::string
& guid
,
334 const std::string
& specified_carrier
,
335 const VoidCallback
& success_callback
,
336 const FailureCallback
& failure_callback
) {
337 const chromeos::NetworkState
* network
=
338 GetStateHandler()->GetNetworkStateFromGuid(guid
);
340 failure_callback
.Run(
341 extensions::networking_private::kErrorInvalidNetworkGuid
);
345 std::string
carrier(specified_carrier
);
346 if (carrier
.empty()) {
347 const chromeos::DeviceState
* device
=
348 GetStateHandler()->GetDeviceState(network
->device_path());
350 carrier
= device
->carrier();
352 if (carrier
!= shill::kCarrierSprint
) {
353 // Only Sprint is directly activated. For other carriers, show the
354 // account details page.
356 ui_delegate()->ShowAccountDetails(guid
);
357 success_callback
.Run();
361 if (!network
->RequiresActivation()) {
362 // If no activation is required, show the account details page.
364 ui_delegate()->ShowAccountDetails(guid
);
365 success_callback
.Run();
369 NetworkHandler::Get()->network_activation_handler()->Activate(
370 network
->path(), carrier
, success_callback
,
371 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
374 void NetworkingPrivateChromeOS::SetWifiTDLSEnabledState(
375 const std::string
& ip_or_mac_address
,
377 const StringCallback
& success_callback
,
378 const FailureCallback
& failure_callback
) {
379 NetworkHandler::Get()->network_device_handler()->SetWifiTDLSEnabled(
380 ip_or_mac_address
, enabled
, success_callback
,
381 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
384 void NetworkingPrivateChromeOS::GetWifiTDLSStatus(
385 const std::string
& ip_or_mac_address
,
386 const StringCallback
& success_callback
,
387 const FailureCallback
& failure_callback
) {
388 NetworkHandler::Get()->network_device_handler()->GetWifiTDLSStatus(
389 ip_or_mac_address
, success_callback
,
390 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
393 void NetworkingPrivateChromeOS::GetCaptivePortalStatus(
394 const std::string
& guid
,
395 const StringCallback
& success_callback
,
396 const FailureCallback
& failure_callback
) {
397 if (!chromeos::NetworkPortalDetector::IsInitialized()) {
398 failure_callback
.Run(networking_private::kErrorNotReady
);
402 chromeos::NetworkPortalDetector::CaptivePortalState state
=
403 chromeos::NetworkPortalDetector::Get()->GetCaptivePortalState(guid
);
404 success_callback
.Run(
405 chromeos::NetworkPortalDetector::CaptivePortalStatusString(state
.status
));
408 void NetworkingPrivateChromeOS::UnlockCellularSim(
409 const std::string
& guid
,
410 const std::string
& pin
,
411 const std::string
& puk
,
412 const VoidCallback
& success_callback
,
413 const FailureCallback
& failure_callback
) {
414 const chromeos::NetworkState
* network_state
=
415 GetStateHandler()->GetNetworkStateFromGuid(guid
);
416 if (!network_state
) {
417 failure_callback
.Run(networking_private::kErrorNetworkUnavailable
);
420 const chromeos::DeviceState
* device_state
=
421 GetStateHandler()->GetDeviceState(network_state
->device_path());
423 failure_callback
.Run(networking_private::kErrorNetworkUnavailable
);
426 std::string lock_type
= device_state
->sim_lock_type();
427 if (lock_type
.empty()) {
428 // Sim is already unlocked.
429 failure_callback
.Run(networking_private::kErrorInvalidNetworkOperation
);
433 // Unblock or unlock the SIM.
434 if (lock_type
== shill::kSIMLockPuk
) {
435 NetworkHandler::Get()->network_device_handler()->UnblockPin(
436 device_state
->path(), puk
, pin
, success_callback
,
437 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
439 NetworkHandler::Get()->network_device_handler()->EnterPin(
440 device_state
->path(), pin
, success_callback
,
441 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
445 void NetworkingPrivateChromeOS::SetCellularSimState(
446 const std::string
& guid
,
448 const std::string
& current_pin
,
449 const std::string
& new_pin
,
450 const VoidCallback
& success_callback
,
451 const FailureCallback
& failure_callback
) {
452 const chromeos::NetworkState
* network_state
=
453 GetStateHandler()->GetNetworkStateFromGuid(guid
);
454 if (!network_state
) {
455 failure_callback
.Run(networking_private::kErrorNetworkUnavailable
);
458 const chromeos::DeviceState
* device_state
=
459 GetStateHandler()->GetDeviceState(network_state
->device_path());
461 failure_callback
.Run(networking_private::kErrorNetworkUnavailable
);
464 if (!device_state
->sim_lock_type().empty()) {
465 // The SIM needs to be unlocked before the state can be changed.
466 failure_callback
.Run(networking_private::kErrorSimLocked
);
470 // Only set a new pin if require_pin is true.
471 std::string set_new_pin
= require_pin
? new_pin
: "";
472 NetworkHandler::Get()->network_device_handler()->RequirePin(
473 device_state
->path(), require_pin
, current_pin
,
474 base::Bind(&RequirePinSuccess
, device_state
->path(), current_pin
,
475 set_new_pin
, success_callback
, failure_callback
),
476 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
479 scoped_ptr
<base::ListValue
>
480 NetworkingPrivateChromeOS::GetEnabledNetworkTypes() {
481 chromeos::NetworkStateHandler
* state_handler
= GetStateHandler();
483 scoped_ptr
<base::ListValue
> network_list(new base::ListValue
);
485 if (state_handler
->IsTechnologyEnabled(NetworkTypePattern::Ethernet()))
486 network_list
->AppendString(::onc::network_type::kEthernet
);
487 if (state_handler
->IsTechnologyEnabled(NetworkTypePattern::WiFi()))
488 network_list
->AppendString(::onc::network_type::kWiFi
);
489 if (state_handler
->IsTechnologyEnabled(NetworkTypePattern::Wimax()))
490 network_list
->AppendString(::onc::network_type::kWimax
);
491 if (state_handler
->IsTechnologyEnabled(NetworkTypePattern::Cellular()))
492 network_list
->AppendString(::onc::network_type::kCellular
);
494 return network_list
.Pass();
497 scoped_ptr
<NetworkingPrivateDelegate::DeviceStateList
>
498 NetworkingPrivateChromeOS::GetDeviceStateList() {
499 std::set
<std::string
> technologies_found
;
500 NetworkStateHandler::DeviceStateList devices
;
501 NetworkHandler::Get()->network_state_handler()->GetDeviceList(&devices
);
503 scoped_ptr
<DeviceStateList
> device_state_list(new DeviceStateList
);
504 for (const DeviceState
* device
: devices
) {
505 std::string onc_type
=
506 chromeos::network_util::TranslateShillTypeToONC(device
->type());
507 AppendDeviceState(onc_type
, device
, device_state_list
.get());
508 technologies_found
.insert(onc_type
);
511 // For any technologies that we do not have a DeviceState entry for, append
512 // an entry if the technolog is available.
513 const char* technology_types
[] = {::onc::network_type::kEthernet
,
514 ::onc::network_type::kWiFi
,
515 ::onc::network_type::kWimax
,
516 ::onc::network_type::kCellular
};
517 for (const char* technology
: technology_types
) {
518 if (ContainsValue(technologies_found
, technology
))
520 AppendDeviceState(technology
, nullptr /* device */,
521 device_state_list
.get());
523 return device_state_list
.Pass();
526 bool NetworkingPrivateChromeOS::EnableNetworkType(const std::string
& type
) {
527 NetworkTypePattern pattern
=
528 chromeos::onc::NetworkTypePatternFromOncType(type
);
530 GetStateHandler()->SetTechnologyEnabled(
531 pattern
, true, chromeos::network_handler::ErrorCallback());
536 bool NetworkingPrivateChromeOS::DisableNetworkType(const std::string
& type
) {
537 NetworkTypePattern pattern
=
538 chromeos::onc::NetworkTypePatternFromOncType(type
);
540 GetStateHandler()->SetTechnologyEnabled(
541 pattern
, false, chromeos::network_handler::ErrorCallback());
546 bool NetworkingPrivateChromeOS::RequestScan() {
547 GetStateHandler()->RequestScan();
551 } // namespace extensions