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 if (device
&& type
== ::onc::network_config::kCellular
) {
124 properties
->sim_present
.reset(new bool(!device
->IsSimAbsent()));
125 if (!device
->sim_lock_type().empty())
126 properties
->sim_lock_type
.reset(new std::string(device
->sim_lock_type()));
128 device_state_list
->push_back(properties
.Pass());
131 void NetworkHandlerDictionaryCallback(
132 const NetworkingPrivateDelegate::DictionaryCallback
& callback
,
133 const std::string
& service_path
,
134 const base::DictionaryValue
& dictionary
) {
135 scoped_ptr
<base::DictionaryValue
> dictionary_copy(dictionary
.DeepCopy());
136 callback
.Run(dictionary_copy
.Pass());
139 void NetworkHandlerFailureCallback(
140 const NetworkingPrivateDelegate::FailureCallback
& callback
,
141 const std::string
& error_name
,
142 scoped_ptr
<base::DictionaryValue
> error_data
) {
143 callback
.Run(error_name
);
146 void RequirePinSuccess(
147 const std::string
& device_path
,
148 const std::string
& current_pin
,
149 const std::string
& new_pin
,
150 const extensions::NetworkingPrivateChromeOS::VoidCallback
& success_callback
,
151 const extensions::NetworkingPrivateChromeOS::FailureCallback
&
153 // After RequirePin succeeds, call ChangePIN iff a different new_pin is
155 if (new_pin
.empty() || new_pin
== current_pin
) {
156 success_callback
.Run();
159 NetworkHandler::Get()->network_device_handler()->ChangePin(
160 device_path
, current_pin
, new_pin
, success_callback
,
161 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
166 ////////////////////////////////////////////////////////////////////////////////
168 namespace extensions
{
170 NetworkingPrivateChromeOS::NetworkingPrivateChromeOS(
171 content::BrowserContext
* browser_context
,
172 scoped_ptr
<VerifyDelegate
> verify_delegate
)
173 : NetworkingPrivateDelegate(verify_delegate
.Pass()),
174 browser_context_(browser_context
),
175 weak_ptr_factory_(this) {}
177 NetworkingPrivateChromeOS::~NetworkingPrivateChromeOS() {
180 void NetworkingPrivateChromeOS::GetProperties(
181 const std::string
& guid
,
182 const DictionaryCallback
& success_callback
,
183 const FailureCallback
& failure_callback
) {
184 std::string service_path
, error
;
185 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
186 failure_callback
.Run(error
);
190 std::string user_id_hash
;
191 if (!GetUserIdHash(browser_context_
, &user_id_hash
, &error
)) {
192 failure_callback
.Run(error
);
196 GetManagedConfigurationHandler()->GetProperties(
197 user_id_hash
, service_path
,
198 base::Bind(&NetworkHandlerDictionaryCallback
, success_callback
),
199 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
202 void NetworkingPrivateChromeOS::GetManagedProperties(
203 const std::string
& guid
,
204 const DictionaryCallback
& success_callback
,
205 const FailureCallback
& failure_callback
) {
206 std::string service_path
, error
;
207 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
208 failure_callback
.Run(error
);
212 std::string user_id_hash
;
213 if (!GetUserIdHash(browser_context_
, &user_id_hash
, &error
)) {
214 failure_callback
.Run(error
);
218 GetManagedConfigurationHandler()->GetManagedProperties(
219 user_id_hash
, service_path
,
220 base::Bind(&NetworkHandlerDictionaryCallback
, success_callback
),
221 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
224 void NetworkingPrivateChromeOS::GetState(
225 const std::string
& guid
,
226 const DictionaryCallback
& success_callback
,
227 const FailureCallback
& failure_callback
) {
228 std::string service_path
, error
;
229 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
230 failure_callback
.Run(error
);
234 const chromeos::NetworkState
* network_state
=
235 GetStateHandler()->GetNetworkStateFromServicePath(
236 service_path
, false /* configured_only */);
237 if (!network_state
) {
238 failure_callback
.Run(networking_private::kErrorNetworkUnavailable
);
242 scoped_ptr
<base::DictionaryValue
> network_properties
=
243 chromeos::network_util::TranslateNetworkStateToONC(network_state
);
245 success_callback
.Run(network_properties
.Pass());
248 void NetworkingPrivateChromeOS::SetProperties(
249 const std::string
& guid
,
250 scoped_ptr
<base::DictionaryValue
> properties
,
251 const VoidCallback
& success_callback
,
252 const FailureCallback
& failure_callback
) {
253 std::string service_path
, error
;
254 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
255 failure_callback
.Run(error
);
259 GetManagedConfigurationHandler()->SetProperties(
260 service_path
, *properties
, success_callback
,
261 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
264 void NetworkingPrivateChromeOS::CreateNetwork(
266 scoped_ptr
<base::DictionaryValue
> properties
,
267 const StringCallback
& success_callback
,
268 const FailureCallback
& failure_callback
) {
269 std::string user_id_hash
, error
;
270 // Do not allow configuring a non-shared network from a non-primary user.
271 if (!shared
&& !GetUserIdHash(browser_context_
, &user_id_hash
, &error
)) {
272 failure_callback
.Run(error
);
276 GetManagedConfigurationHandler()->CreateConfiguration(
277 user_id_hash
, *properties
, success_callback
,
278 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
281 void NetworkingPrivateChromeOS::ForgetNetwork(
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 GetManagedConfigurationHandler()->RemoveConfiguration(
292 service_path
, success_callback
,
293 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
296 void NetworkingPrivateChromeOS::GetNetworks(
297 const std::string
& network_type
,
298 bool configured_only
,
301 const NetworkListCallback
& success_callback
,
302 const FailureCallback
& failure_callback
) {
303 NetworkTypePattern pattern
=
304 chromeos::onc::NetworkTypePatternFromOncType(network_type
);
305 scoped_ptr
<base::ListValue
> network_properties_list
=
306 chromeos::network_util::TranslateNetworkListToONC(
307 pattern
, configured_only
, visible_only
, limit
);
308 success_callback
.Run(network_properties_list
.Pass());
311 void NetworkingPrivateChromeOS::StartConnect(
312 const std::string
& guid
,
313 const VoidCallback
& success_callback
,
314 const FailureCallback
& failure_callback
) {
315 std::string service_path
, error
;
316 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
317 failure_callback
.Run(error
);
321 const bool check_error_state
= false;
322 NetworkHandler::Get()->network_connection_handler()->ConnectToNetwork(
323 service_path
, success_callback
,
324 base::Bind(&NetworkingPrivateChromeOS::ConnectFailureCallback
,
325 weak_ptr_factory_
.GetWeakPtr(), guid
, success_callback
,
330 void NetworkingPrivateChromeOS::ConnectFailureCallback(
331 const std::string
& guid
,
332 const VoidCallback
& success_callback
,
333 const FailureCallback
& failure_callback
,
334 const std::string
& error_name
,
335 scoped_ptr
<base::DictionaryValue
> error_data
) {
336 // TODO(stevenjb): Temporary workaround to show the configuration UI.
337 // Eventually the caller (e.g. Settings) should handle any failures and
338 // show its own configuration UI. crbug.com/380937.
339 if (ui_delegate()->HandleConnectFailed(guid
, error_name
)) {
340 success_callback
.Run();
343 failure_callback
.Run(error_name
);
346 void NetworkingPrivateChromeOS::StartDisconnect(
347 const std::string
& guid
,
348 const VoidCallback
& success_callback
,
349 const FailureCallback
& failure_callback
) {
350 std::string service_path
, error
;
351 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
352 failure_callback
.Run(error
);
356 NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork(
357 service_path
, success_callback
,
358 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
361 void NetworkingPrivateChromeOS::StartActivate(
362 const std::string
& guid
,
363 const std::string
& specified_carrier
,
364 const VoidCallback
& success_callback
,
365 const FailureCallback
& failure_callback
) {
366 const chromeos::NetworkState
* network
=
367 GetStateHandler()->GetNetworkStateFromGuid(guid
);
369 failure_callback
.Run(
370 extensions::networking_private::kErrorInvalidNetworkGuid
);
374 std::string
carrier(specified_carrier
);
375 if (carrier
.empty()) {
376 const chromeos::DeviceState
* device
=
377 GetStateHandler()->GetDeviceState(network
->device_path());
379 carrier
= device
->carrier();
381 if (carrier
!= shill::kCarrierSprint
) {
382 // Only Sprint is directly activated. For other carriers, show the
383 // account details page.
385 ui_delegate()->ShowAccountDetails(guid
);
386 success_callback
.Run();
390 if (!network
->RequiresActivation()) {
391 // If no activation is required, show the account details page.
393 ui_delegate()->ShowAccountDetails(guid
);
394 success_callback
.Run();
398 NetworkHandler::Get()->network_activation_handler()->Activate(
399 network
->path(), carrier
, success_callback
,
400 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
403 void NetworkingPrivateChromeOS::SetWifiTDLSEnabledState(
404 const std::string
& ip_or_mac_address
,
406 const StringCallback
& success_callback
,
407 const FailureCallback
& failure_callback
) {
408 NetworkHandler::Get()->network_device_handler()->SetWifiTDLSEnabled(
409 ip_or_mac_address
, enabled
, success_callback
,
410 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
413 void NetworkingPrivateChromeOS::GetWifiTDLSStatus(
414 const std::string
& ip_or_mac_address
,
415 const StringCallback
& success_callback
,
416 const FailureCallback
& failure_callback
) {
417 NetworkHandler::Get()->network_device_handler()->GetWifiTDLSStatus(
418 ip_or_mac_address
, success_callback
,
419 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
422 void NetworkingPrivateChromeOS::GetCaptivePortalStatus(
423 const std::string
& guid
,
424 const StringCallback
& success_callback
,
425 const FailureCallback
& failure_callback
) {
426 if (!chromeos::NetworkPortalDetector::IsInitialized()) {
427 failure_callback
.Run(networking_private::kErrorNotReady
);
431 chromeos::NetworkPortalDetector::CaptivePortalState state
=
432 chromeos::NetworkPortalDetector::Get()->GetCaptivePortalState(guid
);
433 success_callback
.Run(
434 chromeos::NetworkPortalDetector::CaptivePortalStatusString(state
.status
));
437 void NetworkingPrivateChromeOS::UnlockCellularSim(
438 const std::string
& guid
,
439 const std::string
& pin
,
440 const std::string
& puk
,
441 const VoidCallback
& success_callback
,
442 const FailureCallback
& failure_callback
) {
443 const chromeos::NetworkState
* network_state
=
444 GetStateHandler()->GetNetworkStateFromGuid(guid
);
445 if (!network_state
) {
446 failure_callback
.Run(networking_private::kErrorNetworkUnavailable
);
449 const chromeos::DeviceState
* device_state
=
450 GetStateHandler()->GetDeviceState(network_state
->device_path());
452 failure_callback
.Run(networking_private::kErrorNetworkUnavailable
);
455 std::string lock_type
= device_state
->sim_lock_type();
456 if (lock_type
.empty()) {
457 // Sim is already unlocked.
458 failure_callback
.Run(networking_private::kErrorInvalidNetworkOperation
);
462 // Unblock or unlock the SIM.
463 if (lock_type
== shill::kSIMLockPuk
) {
464 NetworkHandler::Get()->network_device_handler()->UnblockPin(
465 device_state
->path(), puk
, pin
, success_callback
,
466 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
468 NetworkHandler::Get()->network_device_handler()->EnterPin(
469 device_state
->path(), pin
, success_callback
,
470 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
474 void NetworkingPrivateChromeOS::SetCellularSimState(
475 const std::string
& guid
,
477 const std::string
& current_pin
,
478 const std::string
& new_pin
,
479 const VoidCallback
& success_callback
,
480 const FailureCallback
& failure_callback
) {
481 const chromeos::NetworkState
* network_state
=
482 GetStateHandler()->GetNetworkStateFromGuid(guid
);
483 if (!network_state
) {
484 failure_callback
.Run(networking_private::kErrorNetworkUnavailable
);
487 const chromeos::DeviceState
* device_state
=
488 GetStateHandler()->GetDeviceState(network_state
->device_path());
490 failure_callback
.Run(networking_private::kErrorNetworkUnavailable
);
493 if (!device_state
->sim_lock_type().empty()) {
494 // The SIM needs to be unlocked before the state can be changed.
495 failure_callback
.Run(networking_private::kErrorSimLocked
);
499 // Only set a new pin if require_pin is true.
500 std::string set_new_pin
= require_pin
? new_pin
: "";
501 NetworkHandler::Get()->network_device_handler()->RequirePin(
502 device_state
->path(), require_pin
, current_pin
,
503 base::Bind(&RequirePinSuccess
, device_state
->path(), current_pin
,
504 set_new_pin
, success_callback
, failure_callback
),
505 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
508 scoped_ptr
<base::ListValue
>
509 NetworkingPrivateChromeOS::GetEnabledNetworkTypes() {
510 chromeos::NetworkStateHandler
* state_handler
= GetStateHandler();
512 scoped_ptr
<base::ListValue
> network_list(new base::ListValue
);
514 if (state_handler
->IsTechnologyEnabled(NetworkTypePattern::Ethernet()))
515 network_list
->AppendString(::onc::network_type::kEthernet
);
516 if (state_handler
->IsTechnologyEnabled(NetworkTypePattern::WiFi()))
517 network_list
->AppendString(::onc::network_type::kWiFi
);
518 if (state_handler
->IsTechnologyEnabled(NetworkTypePattern::Wimax()))
519 network_list
->AppendString(::onc::network_type::kWimax
);
520 if (state_handler
->IsTechnologyEnabled(NetworkTypePattern::Cellular()))
521 network_list
->AppendString(::onc::network_type::kCellular
);
523 return network_list
.Pass();
526 scoped_ptr
<NetworkingPrivateDelegate::DeviceStateList
>
527 NetworkingPrivateChromeOS::GetDeviceStateList() {
528 std::set
<std::string
> technologies_found
;
529 NetworkStateHandler::DeviceStateList devices
;
530 NetworkHandler::Get()->network_state_handler()->GetDeviceList(&devices
);
532 scoped_ptr
<DeviceStateList
> device_state_list(new DeviceStateList
);
533 for (const DeviceState
* device
: devices
) {
534 std::string onc_type
=
535 chromeos::network_util::TranslateShillTypeToONC(device
->type());
536 AppendDeviceState(onc_type
, device
, device_state_list
.get());
537 technologies_found
.insert(onc_type
);
540 // For any technologies that we do not have a DeviceState entry for, append
541 // an entry if the technolog is available.
542 const char* technology_types
[] = {::onc::network_type::kEthernet
,
543 ::onc::network_type::kWiFi
,
544 ::onc::network_type::kWimax
,
545 ::onc::network_type::kCellular
};
546 for (const char* technology
: technology_types
) {
547 if (ContainsValue(technologies_found
, technology
))
549 AppendDeviceState(technology
, nullptr /* device */,
550 device_state_list
.get());
552 return device_state_list
.Pass();
555 bool NetworkingPrivateChromeOS::EnableNetworkType(const std::string
& type
) {
556 NetworkTypePattern pattern
=
557 chromeos::onc::NetworkTypePatternFromOncType(type
);
559 GetStateHandler()->SetTechnologyEnabled(
560 pattern
, true, chromeos::network_handler::ErrorCallback());
565 bool NetworkingPrivateChromeOS::DisableNetworkType(const std::string
& type
) {
566 NetworkTypePattern pattern
=
567 chromeos::onc::NetworkTypePatternFromOncType(type
);
569 GetStateHandler()->SetTechnologyEnabled(
570 pattern
, false, chromeos::network_handler::ErrorCallback());
575 bool NetworkingPrivateChromeOS::RequestScan() {
576 GetStateHandler()->RequestScan();
580 } // namespace extensions