Add ICU message format support
[chromium-blink-merge.git] / extensions / browser / api / networking_private / networking_private_chromeos.cc
blob83db6529f8fb88a56b1f64320e97677ab70478ff
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 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&
147 failure_callback) {
148 // After RequirePin succeeds, call ChangePIN iff a different new_pin is
149 // provided.
150 if (new_pin.empty() || new_pin == current_pin) {
151 success_callback.Run();
152 return;
154 NetworkHandler::Get()->network_device_handler()->ChangePin(
155 device_path, current_pin, new_pin, success_callback,
156 base::Bind(&NetworkHandlerFailureCallback, failure_callback));
159 } // namespace
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);
182 return;
185 GetManagedConfigurationHandler()->GetProperties(
186 service_path,
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);
198 return;
201 std::string user_id_hash;
202 if (!GetUserIdHash(browser_context_, &user_id_hash, &error)) {
203 failure_callback.Run(error);
204 return;
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);
220 return;
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);
228 return;
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);
245 return;
248 GetManagedConfigurationHandler()->SetProperties(
249 service_path, *properties, success_callback,
250 base::Bind(&NetworkHandlerFailureCallback, failure_callback));
253 void NetworkingPrivateChromeOS::CreateNetwork(
254 bool shared,
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);
262 return;
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);
277 return;
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,
288 bool visible_only,
289 int limit,
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);
307 return;
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),
314 check_error_state);
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);
324 return;
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);
339 if (!network) {
340 failure_callback.Run(
341 extensions::networking_private::kErrorInvalidNetworkGuid);
342 return;
345 std::string carrier(specified_carrier);
346 if (carrier.empty()) {
347 const chromeos::DeviceState* device =
348 GetStateHandler()->GetDeviceState(network->device_path());
349 if (device)
350 carrier = device->carrier();
352 if (carrier != shill::kCarrierSprint) {
353 // Only Sprint is directly activated. For other carriers, show the
354 // account details page.
355 if (ui_delegate())
356 ui_delegate()->ShowAccountDetails(guid);
357 success_callback.Run();
358 return;
361 if (!network->RequiresActivation()) {
362 // If no activation is required, show the account details page.
363 if (ui_delegate())
364 ui_delegate()->ShowAccountDetails(guid);
365 success_callback.Run();
366 return;
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,
376 bool enabled,
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);
399 return;
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);
418 return;
420 const chromeos::DeviceState* device_state =
421 GetStateHandler()->GetDeviceState(network_state->device_path());
422 if (!device_state) {
423 failure_callback.Run(networking_private::kErrorNetworkUnavailable);
424 return;
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);
430 return;
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));
438 } else {
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,
447 bool require_pin,
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);
456 return;
458 const chromeos::DeviceState* device_state =
459 GetStateHandler()->GetDeviceState(network_state->device_path());
460 if (!device_state) {
461 failure_callback.Run(networking_private::kErrorNetworkUnavailable);
462 return;
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);
467 return;
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))
519 continue;
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());
533 return true;
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());
543 return true;
546 bool NetworkingPrivateChromeOS::RequestScan() {
547 GetStateHandler()->RequestScan();
548 return true;
551 } // namespace extensions