Roll src/third_party/WebKit a3b4a2e:7441784 (svn 202551:202552)
[chromium-blink-merge.git] / extensions / browser / api / networking_private / networking_private_chromeos.cc
blob412bfc0506c6357efe19e9ac554fe5fd71e9ea20
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"
7 #include "base/bind.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;
48 namespace {
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,
60 std::string* error) {
61 const chromeos::NetworkState* network =
62 GetStateHandler()->GetNetworkStateFromGuid(guid);
63 if (!network) {
64 *error = extensions::networking_private::kErrorInvalidNetworkGuid;
65 return false;
67 *service_path = network->path();
68 return true;
71 bool GetPrimaryUserIdHash(content::BrowserContext* browser_context,
72 std::string* user_hash,
73 std::string* error) {
74 std::string context_user_hash =
75 extensions::ExtensionsBrowserClient::Get()->GetUserIdHashFromContext(
76 browser_context);
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: "
84 << context_user_hash;
85 if (error)
86 *error = "Error.NonPrimaryUser";
87 return false;
89 if (user_hash)
90 *user_hash = context_user_hash;
91 return true;
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:
106 if (!device)
107 return;
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;
111 break;
112 case NetworkStateHandler::TECHNOLOGY_AVAILABLE:
113 state = private_api::DEVICE_STATE_TYPE_DISABLED;
114 break;
115 case NetworkStateHandler::TECHNOLOGY_UNINITIALIZED:
116 state = private_api::DEVICE_STATE_TYPE_UNINITIALIZED;
117 break;
118 case NetworkStateHandler::TECHNOLOGY_ENABLING:
119 state = private_api::DEVICE_STATE_TYPE_ENABLING;
120 break;
121 case NetworkStateHandler::TECHNOLOGY_ENABLED:
122 state = private_api::DEVICE_STATE_TYPE_ENABLED;
123 break;
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&
153 failure_callback) {
154 // After RequirePin succeeds, call ChangePIN iff a different new_pin is
155 // provided.
156 if (new_pin.empty() || new_pin == current_pin) {
157 success_callback.Run();
158 return;
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) {
170 std::string result;
171 if (!dictionary.GetStringWithoutPathExpansion(key, &result)) {
172 const base::DictionaryValue* managed = nullptr;
173 if (dictionary.GetDictionaryWithoutPathExpansion(key, &managed)) {
174 managed->GetStringWithoutPathExpansion(::onc::kAugmentationActiveSetting,
175 &result);
178 return result;
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)
186 return nullptr;
187 base::DictionaryValue* vpn_dict = nullptr;
188 if (!dictionary->GetDictionary(::onc::network_config::kVPN, &vpn_dict))
189 return nullptr;
190 if (GetStringFromDictionary(*vpn_dict, ::onc::vpn::kType) !=
191 ::onc::vpn::kThirdPartyVpn) {
192 return nullptr;
194 base::DictionaryValue* third_party_vpn = nullptr;
195 vpn_dict->GetDictionary(::onc::vpn::kThirdPartyVpn, &third_party_vpn);
196 return third_party_vpn;
199 } // namespace
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);
222 return;
225 std::string user_id_hash;
226 if (!GetPrimaryUserIdHash(browser_context_, &user_id_hash, &error)) {
227 failure_callback.Run(error);
228 return;
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);
245 return;
248 std::string user_id_hash;
249 if (!GetPrimaryUserIdHash(browser_context_, &user_id_hash, &error)) {
250 failure_callback.Run(error);
251 return;
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);
268 return;
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);
276 return;
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);
294 return;
297 GetManagedConfigurationHandler()->SetProperties(
298 service_path, *properties, success_callback,
299 base::Bind(&NetworkHandlerFailureCallback, failure_callback));
302 void NetworkingPrivateChromeOS::CreateNetwork(
303 bool shared,
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.
309 if (!shared &&
310 !GetPrimaryUserIdHash(browser_context_, &user_id_hash, &error)) {
311 failure_callback.Run(error);
312 return;
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);
327 return;
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,
338 bool visible_only,
339 int limit,
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);
366 return;
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,
374 failure_callback),
375 check_error_state);
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);
385 return;
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);
400 if (!network) {
401 failure_callback.Run(
402 extensions::networking_private::kErrorInvalidNetworkGuid);
403 return;
406 std::string carrier(specified_carrier);
407 if (carrier.empty()) {
408 const chromeos::DeviceState* device =
409 GetStateHandler()->GetDeviceState(network->device_path());
410 if (device)
411 carrier = device->carrier();
413 if (carrier != shill::kCarrierSprint) {
414 // Only Sprint is directly activated. For other carriers, show the
415 // account details page.
416 if (ui_delegate())
417 ui_delegate()->ShowAccountDetails(guid);
418 success_callback.Run();
419 return;
422 if (!network->RequiresActivation()) {
423 // If no activation is required, show the account details page.
424 if (ui_delegate())
425 ui_delegate()->ShowAccountDetails(guid);
426 success_callback.Run();
427 return;
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,
437 bool enabled,
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);
460 return;
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);
479 return;
481 const chromeos::DeviceState* device_state =
482 GetStateHandler()->GetDeviceState(network_state->device_path());
483 if (!device_state) {
484 failure_callback.Run(networking_private::kErrorNetworkUnavailable);
485 return;
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);
491 return;
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));
499 } else {
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,
508 bool require_pin,
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);
517 return;
519 const chromeos::DeviceState* device_state =
520 GetStateHandler()->GetDeviceState(network_state->device_path());
521 if (!device_state) {
522 failure_callback.Run(networking_private::kErrorNetworkUnavailable);
523 return;
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);
528 return;
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))
580 continue;
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());
594 return true;
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());
604 return true;
607 bool NetworkingPrivateChromeOS::RequestScan() {
608 GetStateHandler()->RequestScan();
609 return true;
612 // Private methods
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)
629 return;
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());
641 break;
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();
657 return;
659 failure_callback.Run(error_name);
662 } // namespace extensions