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 "base/logging.h"
11 #include "base/values.h"
12 #include "chromeos/dbus/dbus_thread_manager.h"
13 #include "chromeos/dbus/shill_manager_client.h"
14 #include "chromeos/login/login_state.h"
15 #include "chromeos/network/device_state.h"
16 #include "chromeos/network/managed_network_configuration_handler.h"
17 #include "chromeos/network/network_activation_handler.h"
18 #include "chromeos/network/network_connection_handler.h"
19 #include "chromeos/network/network_device_handler.h"
20 #include "chromeos/network/network_event_log.h"
21 #include "chromeos/network/network_state.h"
22 #include "chromeos/network/network_state_handler.h"
23 #include "chromeos/network/network_util.h"
24 #include "chromeos/network/onc/onc_signature.h"
25 #include "chromeos/network/onc/onc_translator.h"
26 #include "chromeos/network/onc/onc_utils.h"
27 #include "chromeos/network/portal_detector/network_portal_detector.h"
28 #include "components/onc/onc_constants.h"
29 #include "content/public/browser/browser_context.h"
30 #include "extensions/browser/api/networking_private/networking_private_api.h"
31 #include "extensions/browser/extension_registry.h"
32 #include "extensions/browser/extensions_browser_client.h"
33 #include "extensions/common/extension.h"
34 #include "extensions/common/extension_set.h"
35 #include "extensions/common/permissions/api_permission.h"
36 #include "extensions/common/permissions/permissions_data.h"
37 #include "third_party/cros_system_api/dbus/service_constants.h"
39 using chromeos::DeviceState
;
40 using chromeos::NetworkHandler
;
41 using chromeos::NetworkStateHandler
;
42 using chromeos::NetworkTypePattern
;
43 using chromeos::ShillManagerClient
;
44 using extensions::NetworkingPrivateDelegate
;
46 namespace private_api
= extensions::api::networking_private
;
50 chromeos::NetworkStateHandler
* GetStateHandler() {
51 return NetworkHandler::Get()->network_state_handler();
54 chromeos::ManagedNetworkConfigurationHandler
* GetManagedConfigurationHandler() {
55 return NetworkHandler::Get()->managed_network_configuration_handler();
58 bool GetServicePathFromGuid(const std::string
& guid
,
59 std::string
* service_path
,
61 const chromeos::NetworkState
* network
=
62 GetStateHandler()->GetNetworkStateFromGuid(guid
);
64 *error
= extensions::networking_private::kErrorInvalidNetworkGuid
;
67 *service_path
= network
->path();
71 bool GetPrimaryUserIdHash(content::BrowserContext
* browser_context
,
72 std::string
* user_hash
,
74 std::string context_user_hash
=
75 extensions::ExtensionsBrowserClient::Get()->GetUserIdHashFromContext(
78 // Currently Chrome OS only configures networks for the primary user.
79 // Configuration attempts from other browser contexts should fail.
80 if (context_user_hash
!= chromeos::LoginState::Get()->primary_user_hash()) {
81 // Disallow class requiring a user id hash from a non-primary user context
82 // to avoid complexities with the policy code.
83 LOG(ERROR
) << "networkingPrivate API call from non primary user: "
86 *error
= "Error.NonPrimaryUser";
90 *user_hash
= context_user_hash
;
94 void AppendDeviceState(
95 const std::string
& type
,
96 const DeviceState
* device
,
97 NetworkingPrivateDelegate::DeviceStateList
* device_state_list
) {
98 DCHECK(!type
.empty());
99 NetworkTypePattern pattern
=
100 chromeos::onc::NetworkTypePatternFromOncType(type
);
101 NetworkStateHandler::TechnologyState technology_state
=
102 GetStateHandler()->GetTechnologyState(pattern
);
103 private_api::DeviceStateType state
= private_api::DEVICE_STATE_TYPE_NONE
;
104 switch (technology_state
) {
105 case NetworkStateHandler::TECHNOLOGY_UNAVAILABLE
:
108 // If we have a DeviceState entry but the technology is not available,
109 // assume the technology is not initialized.
110 state
= private_api::DEVICE_STATE_TYPE_UNINITIALIZED
;
112 case NetworkStateHandler::TECHNOLOGY_AVAILABLE
:
113 state
= private_api::DEVICE_STATE_TYPE_DISABLED
;
115 case NetworkStateHandler::TECHNOLOGY_UNINITIALIZED
:
116 state
= private_api::DEVICE_STATE_TYPE_UNINITIALIZED
;
118 case NetworkStateHandler::TECHNOLOGY_ENABLING
:
119 state
= private_api::DEVICE_STATE_TYPE_ENABLING
;
121 case NetworkStateHandler::TECHNOLOGY_ENABLED
:
122 state
= private_api::DEVICE_STATE_TYPE_ENABLED
;
125 DCHECK_NE(private_api::DEVICE_STATE_TYPE_NONE
, state
);
126 scoped_ptr
<private_api::DeviceStateProperties
> properties(
127 new private_api::DeviceStateProperties
);
128 properties
->type
= private_api::ParseNetworkType(type
);
129 properties
->state
= state
;
130 if (device
&& state
== private_api::DEVICE_STATE_TYPE_ENABLED
)
131 properties
->scanning
.reset(new bool(device
->scanning()));
132 if (device
&& type
== ::onc::network_config::kCellular
) {
133 properties
->sim_present
.reset(new bool(!device
->IsSimAbsent()));
134 if (!device
->sim_lock_type().empty())
135 properties
->sim_lock_type
.reset(new std::string(device
->sim_lock_type()));
137 device_state_list
->push_back(properties
.Pass());
140 void NetworkHandlerFailureCallback(
141 const NetworkingPrivateDelegate::FailureCallback
& callback
,
142 const std::string
& error_name
,
143 scoped_ptr
<base::DictionaryValue
> error_data
) {
144 callback
.Run(error_name
);
147 void RequirePinSuccess(
148 const std::string
& device_path
,
149 const std::string
& current_pin
,
150 const std::string
& new_pin
,
151 const extensions::NetworkingPrivateChromeOS::VoidCallback
& success_callback
,
152 const extensions::NetworkingPrivateChromeOS::FailureCallback
&
154 // After RequirePin succeeds, call ChangePIN iff a different new_pin is
156 if (new_pin
.empty() || new_pin
== current_pin
) {
157 success_callback
.Run();
160 NetworkHandler::Get()->network_device_handler()->ChangePin(
161 device_path
, current_pin
, new_pin
, success_callback
,
162 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
165 // Returns the string corresponding to |key|. If the property is a managed
166 // dictionary, returns the active value. If the property does not exist or
167 // has no active value, returns an empty string.
168 std::string
GetStringFromDictionary(const base::DictionaryValue
& dictionary
,
169 const std::string
& key
) {
171 if (!dictionary
.GetStringWithoutPathExpansion(key
, &result
)) {
172 const base::DictionaryValue
* managed
= nullptr;
173 if (dictionary
.GetDictionaryWithoutPathExpansion(key
, &managed
)) {
174 managed
->GetStringWithoutPathExpansion(::onc::kAugmentationActiveSetting
,
181 base::DictionaryValue
* GetThirdPartyVPNDictionary(
182 base::DictionaryValue
* dictionary
) {
183 const std::string type
=
184 GetStringFromDictionary(*dictionary
, ::onc::network_config::kType
);
185 if (type
!= ::onc::network_config::kVPN
)
187 base::DictionaryValue
* vpn_dict
= nullptr;
188 if (!dictionary
->GetDictionary(::onc::network_config::kVPN
, &vpn_dict
))
190 if (GetStringFromDictionary(*vpn_dict
, ::onc::vpn::kType
) !=
191 ::onc::vpn::kThirdPartyVpn
) {
194 base::DictionaryValue
* third_party_vpn
= nullptr;
195 vpn_dict
->GetDictionary(::onc::vpn::kThirdPartyVpn
, &third_party_vpn
);
196 return third_party_vpn
;
201 ////////////////////////////////////////////////////////////////////////////////
203 namespace extensions
{
205 NetworkingPrivateChromeOS::NetworkingPrivateChromeOS(
206 content::BrowserContext
* browser_context
,
207 scoped_ptr
<VerifyDelegate
> verify_delegate
)
208 : NetworkingPrivateDelegate(verify_delegate
.Pass()),
209 browser_context_(browser_context
),
210 weak_ptr_factory_(this) {}
212 NetworkingPrivateChromeOS::~NetworkingPrivateChromeOS() {
215 void NetworkingPrivateChromeOS::GetProperties(
216 const std::string
& guid
,
217 const DictionaryCallback
& success_callback
,
218 const FailureCallback
& failure_callback
) {
219 std::string service_path
, error
;
220 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
221 failure_callback
.Run(error
);
225 std::string user_id_hash
;
226 if (!GetPrimaryUserIdHash(browser_context_
, &user_id_hash
, &error
)) {
227 failure_callback
.Run(error
);
231 GetManagedConfigurationHandler()->GetProperties(
232 user_id_hash
, service_path
,
233 base::Bind(&NetworkingPrivateChromeOS::GetPropertiesCallback
,
234 weak_ptr_factory_
.GetWeakPtr(), success_callback
),
235 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
238 void NetworkingPrivateChromeOS::GetManagedProperties(
239 const std::string
& guid
,
240 const DictionaryCallback
& 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 std::string user_id_hash
;
249 if (!GetPrimaryUserIdHash(browser_context_
, &user_id_hash
, &error
)) {
250 failure_callback
.Run(error
);
254 GetManagedConfigurationHandler()->GetManagedProperties(
255 user_id_hash
, service_path
,
256 base::Bind(&NetworkingPrivateChromeOS::GetPropertiesCallback
,
257 weak_ptr_factory_
.GetWeakPtr(), success_callback
),
258 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
261 void NetworkingPrivateChromeOS::GetState(
262 const std::string
& guid
,
263 const DictionaryCallback
& success_callback
,
264 const FailureCallback
& failure_callback
) {
265 std::string service_path
, error
;
266 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
267 failure_callback
.Run(error
);
271 const chromeos::NetworkState
* network_state
=
272 GetStateHandler()->GetNetworkStateFromServicePath(
273 service_path
, false /* configured_only */);
274 if (!network_state
) {
275 failure_callback
.Run(networking_private::kErrorNetworkUnavailable
);
279 scoped_ptr
<base::DictionaryValue
> network_properties
=
280 chromeos::network_util::TranslateNetworkStateToONC(network_state
);
281 AppendThirdPartyProviderName(network_properties
.get());
283 success_callback
.Run(network_properties
.Pass());
286 void NetworkingPrivateChromeOS::SetProperties(
287 const std::string
& guid
,
288 scoped_ptr
<base::DictionaryValue
> properties
,
289 const VoidCallback
& success_callback
,
290 const FailureCallback
& failure_callback
) {
291 std::string service_path
, error
;
292 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
293 failure_callback
.Run(error
);
297 GetManagedConfigurationHandler()->SetProperties(
298 service_path
, *properties
, success_callback
,
299 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
302 void NetworkingPrivateChromeOS::CreateNetwork(
304 scoped_ptr
<base::DictionaryValue
> properties
,
305 const StringCallback
& success_callback
,
306 const FailureCallback
& failure_callback
) {
307 std::string user_id_hash
, error
;
308 // Do not allow configuring a non-shared network from a non-primary user.
310 !GetPrimaryUserIdHash(browser_context_
, &user_id_hash
, &error
)) {
311 failure_callback
.Run(error
);
315 GetManagedConfigurationHandler()->CreateConfiguration(
316 user_id_hash
, *properties
, success_callback
,
317 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
320 void NetworkingPrivateChromeOS::ForgetNetwork(
321 const std::string
& guid
,
322 const VoidCallback
& success_callback
,
323 const FailureCallback
& failure_callback
) {
324 std::string service_path
, error
;
325 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
326 failure_callback
.Run(error
);
330 GetManagedConfigurationHandler()->RemoveConfiguration(
331 service_path
, success_callback
,
332 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
335 void NetworkingPrivateChromeOS::GetNetworks(
336 const std::string
& network_type
,
337 bool configured_only
,
340 const NetworkListCallback
& success_callback
,
341 const FailureCallback
& failure_callback
) {
342 NetworkTypePattern pattern
=
343 chromeos::onc::NetworkTypePatternFromOncType(network_type
);
344 scoped_ptr
<base::ListValue
> network_properties_list
=
345 chromeos::network_util::TranslateNetworkListToONC(
346 pattern
, configured_only
, visible_only
, limit
);
348 for (base::Value
* value
: *network_properties_list
) {
349 base::DictionaryValue
* network_dict
= nullptr;
350 value
->GetAsDictionary(&network_dict
);
351 DCHECK(network_dict
);
352 if (GetThirdPartyVPNDictionary(network_dict
))
353 AppendThirdPartyProviderName(network_dict
);
356 success_callback
.Run(network_properties_list
.Pass());
359 void NetworkingPrivateChromeOS::StartConnect(
360 const std::string
& guid
,
361 const VoidCallback
& success_callback
,
362 const FailureCallback
& failure_callback
) {
363 std::string service_path
, error
;
364 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
365 failure_callback
.Run(error
);
369 const bool check_error_state
= false;
370 NetworkHandler::Get()->network_connection_handler()->ConnectToNetwork(
371 service_path
, success_callback
,
372 base::Bind(&NetworkingPrivateChromeOS::ConnectFailureCallback
,
373 weak_ptr_factory_
.GetWeakPtr(), guid
, success_callback
,
378 void NetworkingPrivateChromeOS::StartDisconnect(
379 const std::string
& guid
,
380 const VoidCallback
& success_callback
,
381 const FailureCallback
& failure_callback
) {
382 std::string service_path
, error
;
383 if (!GetServicePathFromGuid(guid
, &service_path
, &error
)) {
384 failure_callback
.Run(error
);
388 NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork(
389 service_path
, success_callback
,
390 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
393 void NetworkingPrivateChromeOS::StartActivate(
394 const std::string
& guid
,
395 const std::string
& specified_carrier
,
396 const VoidCallback
& success_callback
,
397 const FailureCallback
& failure_callback
) {
398 const chromeos::NetworkState
* network
=
399 GetStateHandler()->GetNetworkStateFromGuid(guid
);
401 failure_callback
.Run(
402 extensions::networking_private::kErrorInvalidNetworkGuid
);
406 std::string
carrier(specified_carrier
);
407 if (carrier
.empty()) {
408 const chromeos::DeviceState
* device
=
409 GetStateHandler()->GetDeviceState(network
->device_path());
411 carrier
= device
->carrier();
413 if (carrier
!= shill::kCarrierSprint
) {
414 // Only Sprint is directly activated. For other carriers, show the
415 // account details page.
417 ui_delegate()->ShowAccountDetails(guid
);
418 success_callback
.Run();
422 if (!network
->RequiresActivation()) {
423 // If no activation is required, show the account details page.
425 ui_delegate()->ShowAccountDetails(guid
);
426 success_callback
.Run();
430 NetworkHandler::Get()->network_activation_handler()->Activate(
431 network
->path(), carrier
, success_callback
,
432 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
435 void NetworkingPrivateChromeOS::SetWifiTDLSEnabledState(
436 const std::string
& ip_or_mac_address
,
438 const StringCallback
& success_callback
,
439 const FailureCallback
& failure_callback
) {
440 NetworkHandler::Get()->network_device_handler()->SetWifiTDLSEnabled(
441 ip_or_mac_address
, enabled
, success_callback
,
442 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
445 void NetworkingPrivateChromeOS::GetWifiTDLSStatus(
446 const std::string
& ip_or_mac_address
,
447 const StringCallback
& success_callback
,
448 const FailureCallback
& failure_callback
) {
449 NetworkHandler::Get()->network_device_handler()->GetWifiTDLSStatus(
450 ip_or_mac_address
, success_callback
,
451 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
454 void NetworkingPrivateChromeOS::GetCaptivePortalStatus(
455 const std::string
& guid
,
456 const StringCallback
& success_callback
,
457 const FailureCallback
& failure_callback
) {
458 if (!chromeos::NetworkPortalDetector::IsInitialized()) {
459 failure_callback
.Run(networking_private::kErrorNotReady
);
463 chromeos::NetworkPortalDetector::CaptivePortalState state
=
464 chromeos::NetworkPortalDetector::Get()->GetCaptivePortalState(guid
);
465 success_callback
.Run(
466 chromeos::NetworkPortalDetector::CaptivePortalStatusString(state
.status
));
469 void NetworkingPrivateChromeOS::UnlockCellularSim(
470 const std::string
& guid
,
471 const std::string
& pin
,
472 const std::string
& puk
,
473 const VoidCallback
& success_callback
,
474 const FailureCallback
& failure_callback
) {
475 const chromeos::NetworkState
* network_state
=
476 GetStateHandler()->GetNetworkStateFromGuid(guid
);
477 if (!network_state
) {
478 failure_callback
.Run(networking_private::kErrorNetworkUnavailable
);
481 const chromeos::DeviceState
* device_state
=
482 GetStateHandler()->GetDeviceState(network_state
->device_path());
484 failure_callback
.Run(networking_private::kErrorNetworkUnavailable
);
487 std::string lock_type
= device_state
->sim_lock_type();
488 if (lock_type
.empty()) {
489 // Sim is already unlocked.
490 failure_callback
.Run(networking_private::kErrorInvalidNetworkOperation
);
494 // Unblock or unlock the SIM.
495 if (lock_type
== shill::kSIMLockPuk
) {
496 NetworkHandler::Get()->network_device_handler()->UnblockPin(
497 device_state
->path(), puk
, pin
, success_callback
,
498 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
500 NetworkHandler::Get()->network_device_handler()->EnterPin(
501 device_state
->path(), pin
, success_callback
,
502 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
506 void NetworkingPrivateChromeOS::SetCellularSimState(
507 const std::string
& guid
,
509 const std::string
& current_pin
,
510 const std::string
& new_pin
,
511 const VoidCallback
& success_callback
,
512 const FailureCallback
& failure_callback
) {
513 const chromeos::NetworkState
* network_state
=
514 GetStateHandler()->GetNetworkStateFromGuid(guid
);
515 if (!network_state
) {
516 failure_callback
.Run(networking_private::kErrorNetworkUnavailable
);
519 const chromeos::DeviceState
* device_state
=
520 GetStateHandler()->GetDeviceState(network_state
->device_path());
522 failure_callback
.Run(networking_private::kErrorNetworkUnavailable
);
525 if (!device_state
->sim_lock_type().empty()) {
526 // The SIM needs to be unlocked before the state can be changed.
527 failure_callback
.Run(networking_private::kErrorSimLocked
);
531 // Only set a new pin if require_pin is true.
532 std::string set_new_pin
= require_pin
? new_pin
: "";
533 NetworkHandler::Get()->network_device_handler()->RequirePin(
534 device_state
->path(), require_pin
, current_pin
,
535 base::Bind(&RequirePinSuccess
, device_state
->path(), current_pin
,
536 set_new_pin
, success_callback
, failure_callback
),
537 base::Bind(&NetworkHandlerFailureCallback
, failure_callback
));
540 scoped_ptr
<base::ListValue
>
541 NetworkingPrivateChromeOS::GetEnabledNetworkTypes() {
542 chromeos::NetworkStateHandler
* state_handler
= GetStateHandler();
544 scoped_ptr
<base::ListValue
> network_list(new base::ListValue
);
546 if (state_handler
->IsTechnologyEnabled(NetworkTypePattern::Ethernet()))
547 network_list
->AppendString(::onc::network_type::kEthernet
);
548 if (state_handler
->IsTechnologyEnabled(NetworkTypePattern::WiFi()))
549 network_list
->AppendString(::onc::network_type::kWiFi
);
550 if (state_handler
->IsTechnologyEnabled(NetworkTypePattern::Wimax()))
551 network_list
->AppendString(::onc::network_type::kWimax
);
552 if (state_handler
->IsTechnologyEnabled(NetworkTypePattern::Cellular()))
553 network_list
->AppendString(::onc::network_type::kCellular
);
555 return network_list
.Pass();
558 scoped_ptr
<NetworkingPrivateDelegate::DeviceStateList
>
559 NetworkingPrivateChromeOS::GetDeviceStateList() {
560 std::set
<std::string
> technologies_found
;
561 NetworkStateHandler::DeviceStateList devices
;
562 NetworkHandler::Get()->network_state_handler()->GetDeviceList(&devices
);
564 scoped_ptr
<DeviceStateList
> device_state_list(new DeviceStateList
);
565 for (const DeviceState
* device
: devices
) {
566 std::string onc_type
=
567 chromeos::network_util::TranslateShillTypeToONC(device
->type());
568 AppendDeviceState(onc_type
, device
, device_state_list
.get());
569 technologies_found
.insert(onc_type
);
572 // For any technologies that we do not have a DeviceState entry for, append
573 // an entry if the technolog is available.
574 const char* technology_types
[] = {::onc::network_type::kEthernet
,
575 ::onc::network_type::kWiFi
,
576 ::onc::network_type::kWimax
,
577 ::onc::network_type::kCellular
};
578 for (const char* technology
: technology_types
) {
579 if (ContainsValue(technologies_found
, technology
))
581 AppendDeviceState(technology
, nullptr /* device */,
582 device_state_list
.get());
584 return device_state_list
.Pass();
587 bool NetworkingPrivateChromeOS::EnableNetworkType(const std::string
& type
) {
588 NetworkTypePattern pattern
=
589 chromeos::onc::NetworkTypePatternFromOncType(type
);
591 GetStateHandler()->SetTechnologyEnabled(
592 pattern
, true, chromeos::network_handler::ErrorCallback());
597 bool NetworkingPrivateChromeOS::DisableNetworkType(const std::string
& type
) {
598 NetworkTypePattern pattern
=
599 chromeos::onc::NetworkTypePatternFromOncType(type
);
601 GetStateHandler()->SetTechnologyEnabled(
602 pattern
, false, chromeos::network_handler::ErrorCallback());
607 bool NetworkingPrivateChromeOS::RequestScan() {
608 GetStateHandler()->RequestScan();
614 void NetworkingPrivateChromeOS::GetPropertiesCallback(
615 const DictionaryCallback
& callback
,
616 const std::string
& service_path
,
617 const base::DictionaryValue
& dictionary
) {
618 scoped_ptr
<base::DictionaryValue
> dictionary_copy(dictionary
.DeepCopy());
619 AppendThirdPartyProviderName(dictionary_copy
.get());
620 callback
.Run(dictionary_copy
.Pass());
623 // Populate ThirdPartyVPN.kProviderName for third-party VPNs.
624 void NetworkingPrivateChromeOS::AppendThirdPartyProviderName(
625 base::DictionaryValue
* dictionary
) {
626 base::DictionaryValue
* third_party_vpn
=
627 GetThirdPartyVPNDictionary(dictionary
);
628 if (!third_party_vpn
)
631 const std::string extension_id
= GetStringFromDictionary(
632 *third_party_vpn
, ::onc::third_party_vpn::kExtensionID
);
633 const ExtensionSet
& extensions
=
634 ExtensionRegistry::Get(browser_context_
)->enabled_extensions();
635 for (const auto& extension
: extensions
) {
636 if (extension
->permissions_data()->HasAPIPermission(
637 APIPermission::kVpnProvider
) &&
638 extension
->id() == extension_id
) {
639 third_party_vpn
->SetStringWithoutPathExpansion(
640 ::onc::third_party_vpn::kProviderName
, extension
->name());
646 void NetworkingPrivateChromeOS::ConnectFailureCallback(
647 const std::string
& guid
,
648 const VoidCallback
& success_callback
,
649 const FailureCallback
& failure_callback
,
650 const std::string
& error_name
,
651 scoped_ptr
<base::DictionaryValue
> error_data
) {
652 // TODO(stevenjb): Temporary workaround to show the configuration UI.
653 // Eventually the caller (e.g. Settings) should handle any failures and
654 // show its own configuration UI. crbug.com/380937.
655 if (ui_delegate()->HandleConnectFailed(guid
, error_name
)) {
656 success_callback
.Run();
659 failure_callback
.Run(error_name
);
662 } // namespace extensions