Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / extensions / browser / api / networking_private / networking_private_chromeos.cc
blob76f504c7401830de917b20b1fde962530df37f99
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 "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;
41 namespace {
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,
53 std::string* error) {
54 const chromeos::NetworkState* network =
55 GetStateHandler()->GetNetworkStateFromGuid(guid);
56 if (!network) {
57 *error = extensions::networking_private::kErrorInvalidNetworkGuid;
58 return false;
60 *service_path = network->path();
61 return true;
64 bool GetUserIdHash(content::BrowserContext* browser_context,
65 std::string* user_hash,
66 std::string* error) {
67 std::string context_user_hash =
68 extensions::ExtensionsBrowserClient::Get()->GetUserIdHashFromContext(
69 browser_context);
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: "
77 << context_user_hash;
78 *error = "Error.NonPrimaryUser";
79 return false;
81 *user_hash = context_user_hash;
82 return true;
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:
97 if (!device)
98 return;
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;
102 break;
103 case NetworkStateHandler::TECHNOLOGY_AVAILABLE:
104 state = private_api::DEVICE_STATE_TYPE_DISABLED;
105 break;
106 case NetworkStateHandler::TECHNOLOGY_UNINITIALIZED:
107 state = private_api::DEVICE_STATE_TYPE_UNINITIALIZED;
108 break;
109 case NetworkStateHandler::TECHNOLOGY_ENABLING:
110 state = private_api::DEVICE_STATE_TYPE_ENABLING;
111 break;
112 case NetworkStateHandler::TECHNOLOGY_ENABLED:
113 state = private_api::DEVICE_STATE_TYPE_ENABLED;
114 break;
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&
152 failure_callback) {
153 // After RequirePin succeeds, call ChangePIN iff a different new_pin is
154 // provided.
155 if (new_pin.empty() || new_pin == current_pin) {
156 success_callback.Run();
157 return;
159 NetworkHandler::Get()->network_device_handler()->ChangePin(
160 device_path, current_pin, new_pin, success_callback,
161 base::Bind(&NetworkHandlerFailureCallback, failure_callback));
164 } // namespace
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);
187 return;
190 std::string user_id_hash;
191 if (!GetUserIdHash(browser_context_, &user_id_hash, &error)) {
192 failure_callback.Run(error);
193 return;
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);
209 return;
212 std::string user_id_hash;
213 if (!GetUserIdHash(browser_context_, &user_id_hash, &error)) {
214 failure_callback.Run(error);
215 return;
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);
231 return;
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);
239 return;
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);
256 return;
259 GetManagedConfigurationHandler()->SetProperties(
260 service_path, *properties, success_callback,
261 base::Bind(&NetworkHandlerFailureCallback, failure_callback));
264 void NetworkingPrivateChromeOS::CreateNetwork(
265 bool shared,
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);
273 return;
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);
288 return;
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,
299 bool visible_only,
300 int limit,
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);
318 return;
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,
326 failure_callback),
327 check_error_state);
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();
341 return;
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);
353 return;
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);
368 if (!network) {
369 failure_callback.Run(
370 extensions::networking_private::kErrorInvalidNetworkGuid);
371 return;
374 std::string carrier(specified_carrier);
375 if (carrier.empty()) {
376 const chromeos::DeviceState* device =
377 GetStateHandler()->GetDeviceState(network->device_path());
378 if (device)
379 carrier = device->carrier();
381 if (carrier != shill::kCarrierSprint) {
382 // Only Sprint is directly activated. For other carriers, show the
383 // account details page.
384 if (ui_delegate())
385 ui_delegate()->ShowAccountDetails(guid);
386 success_callback.Run();
387 return;
390 if (!network->RequiresActivation()) {
391 // If no activation is required, show the account details page.
392 if (ui_delegate())
393 ui_delegate()->ShowAccountDetails(guid);
394 success_callback.Run();
395 return;
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,
405 bool enabled,
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);
428 return;
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);
447 return;
449 const chromeos::DeviceState* device_state =
450 GetStateHandler()->GetDeviceState(network_state->device_path());
451 if (!device_state) {
452 failure_callback.Run(networking_private::kErrorNetworkUnavailable);
453 return;
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);
459 return;
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));
467 } else {
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,
476 bool require_pin,
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);
485 return;
487 const chromeos::DeviceState* device_state =
488 GetStateHandler()->GetDeviceState(network_state->device_path());
489 if (!device_state) {
490 failure_callback.Run(networking_private::kErrorNetworkUnavailable);
491 return;
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);
496 return;
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))
548 continue;
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());
562 return true;
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());
572 return true;
575 bool NetworkingPrivateChromeOS::RequestScan() {
576 GetStateHandler()->RequestScan();
577 return true;
580 } // namespace extensions