make use of media_use_ffmpeg in BUILD.gn
[chromium-blink-merge.git] / extensions / browser / api / networking_private / networking_private_chromeos.cc
blobb8c18e46dac84b9f6be71d1b8e17a092c6898531
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),
170 weak_ptr_factory_(this) {}
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);
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(&NetworkingPrivateChromeOS::ConnectFailureCallback,
314 weak_ptr_factory_.GetWeakPtr(), guid, success_callback,
315 failure_callback),
316 check_error_state);
319 void NetworkingPrivateChromeOS::ConnectFailureCallback(
320 const std::string& guid,
321 const VoidCallback& success_callback,
322 const FailureCallback& failure_callback,
323 const std::string& error_name,
324 scoped_ptr<base::DictionaryValue> error_data) {
325 // TODO(stevenjb): Temporary workaround to show the configuration UI.
326 // Eventually the caller (e.g. Settings) should handle any failures and
327 // show its own configuration UI. crbug.com/380937.
328 if (ui_delegate()->HandleConnectFailed(guid, error_name)) {
329 success_callback.Run();
330 return;
332 failure_callback.Run(error_name);
335 void NetworkingPrivateChromeOS::StartDisconnect(
336 const std::string& guid,
337 const VoidCallback& success_callback,
338 const FailureCallback& failure_callback) {
339 std::string service_path, error;
340 if (!GetServicePathFromGuid(guid, &service_path, &error)) {
341 failure_callback.Run(error);
342 return;
345 NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork(
346 service_path, success_callback,
347 base::Bind(&NetworkHandlerFailureCallback, failure_callback));
350 void NetworkingPrivateChromeOS::StartActivate(
351 const std::string& guid,
352 const std::string& specified_carrier,
353 const VoidCallback& success_callback,
354 const FailureCallback& failure_callback) {
355 const chromeos::NetworkState* network =
356 GetStateHandler()->GetNetworkStateFromGuid(guid);
357 if (!network) {
358 failure_callback.Run(
359 extensions::networking_private::kErrorInvalidNetworkGuid);
360 return;
363 std::string carrier(specified_carrier);
364 if (carrier.empty()) {
365 const chromeos::DeviceState* device =
366 GetStateHandler()->GetDeviceState(network->device_path());
367 if (device)
368 carrier = device->carrier();
370 if (carrier != shill::kCarrierSprint) {
371 // Only Sprint is directly activated. For other carriers, show the
372 // account details page.
373 if (ui_delegate())
374 ui_delegate()->ShowAccountDetails(guid);
375 success_callback.Run();
376 return;
379 if (!network->RequiresActivation()) {
380 // If no activation is required, show the account details page.
381 if (ui_delegate())
382 ui_delegate()->ShowAccountDetails(guid);
383 success_callback.Run();
384 return;
387 NetworkHandler::Get()->network_activation_handler()->Activate(
388 network->path(), carrier, success_callback,
389 base::Bind(&NetworkHandlerFailureCallback, failure_callback));
392 void NetworkingPrivateChromeOS::SetWifiTDLSEnabledState(
393 const std::string& ip_or_mac_address,
394 bool enabled,
395 const StringCallback& success_callback,
396 const FailureCallback& failure_callback) {
397 NetworkHandler::Get()->network_device_handler()->SetWifiTDLSEnabled(
398 ip_or_mac_address, enabled, success_callback,
399 base::Bind(&NetworkHandlerFailureCallback, failure_callback));
402 void NetworkingPrivateChromeOS::GetWifiTDLSStatus(
403 const std::string& ip_or_mac_address,
404 const StringCallback& success_callback,
405 const FailureCallback& failure_callback) {
406 NetworkHandler::Get()->network_device_handler()->GetWifiTDLSStatus(
407 ip_or_mac_address, success_callback,
408 base::Bind(&NetworkHandlerFailureCallback, failure_callback));
411 void NetworkingPrivateChromeOS::GetCaptivePortalStatus(
412 const std::string& guid,
413 const StringCallback& success_callback,
414 const FailureCallback& failure_callback) {
415 if (!chromeos::NetworkPortalDetector::IsInitialized()) {
416 failure_callback.Run(networking_private::kErrorNotReady);
417 return;
420 chromeos::NetworkPortalDetector::CaptivePortalState state =
421 chromeos::NetworkPortalDetector::Get()->GetCaptivePortalState(guid);
422 success_callback.Run(
423 chromeos::NetworkPortalDetector::CaptivePortalStatusString(state.status));
426 void NetworkingPrivateChromeOS::UnlockCellularSim(
427 const std::string& guid,
428 const std::string& pin,
429 const std::string& puk,
430 const VoidCallback& success_callback,
431 const FailureCallback& failure_callback) {
432 const chromeos::NetworkState* network_state =
433 GetStateHandler()->GetNetworkStateFromGuid(guid);
434 if (!network_state) {
435 failure_callback.Run(networking_private::kErrorNetworkUnavailable);
436 return;
438 const chromeos::DeviceState* device_state =
439 GetStateHandler()->GetDeviceState(network_state->device_path());
440 if (!device_state) {
441 failure_callback.Run(networking_private::kErrorNetworkUnavailable);
442 return;
444 std::string lock_type = device_state->sim_lock_type();
445 if (lock_type.empty()) {
446 // Sim is already unlocked.
447 failure_callback.Run(networking_private::kErrorInvalidNetworkOperation);
448 return;
451 // Unblock or unlock the SIM.
452 if (lock_type == shill::kSIMLockPuk) {
453 NetworkHandler::Get()->network_device_handler()->UnblockPin(
454 device_state->path(), puk, pin, success_callback,
455 base::Bind(&NetworkHandlerFailureCallback, failure_callback));
456 } else {
457 NetworkHandler::Get()->network_device_handler()->EnterPin(
458 device_state->path(), pin, success_callback,
459 base::Bind(&NetworkHandlerFailureCallback, failure_callback));
463 void NetworkingPrivateChromeOS::SetCellularSimState(
464 const std::string& guid,
465 bool require_pin,
466 const std::string& current_pin,
467 const std::string& new_pin,
468 const VoidCallback& success_callback,
469 const FailureCallback& failure_callback) {
470 const chromeos::NetworkState* network_state =
471 GetStateHandler()->GetNetworkStateFromGuid(guid);
472 if (!network_state) {
473 failure_callback.Run(networking_private::kErrorNetworkUnavailable);
474 return;
476 const chromeos::DeviceState* device_state =
477 GetStateHandler()->GetDeviceState(network_state->device_path());
478 if (!device_state) {
479 failure_callback.Run(networking_private::kErrorNetworkUnavailable);
480 return;
482 if (!device_state->sim_lock_type().empty()) {
483 // The SIM needs to be unlocked before the state can be changed.
484 failure_callback.Run(networking_private::kErrorSimLocked);
485 return;
488 // Only set a new pin if require_pin is true.
489 std::string set_new_pin = require_pin ? new_pin : "";
490 NetworkHandler::Get()->network_device_handler()->RequirePin(
491 device_state->path(), require_pin, current_pin,
492 base::Bind(&RequirePinSuccess, device_state->path(), current_pin,
493 set_new_pin, success_callback, failure_callback),
494 base::Bind(&NetworkHandlerFailureCallback, failure_callback));
497 scoped_ptr<base::ListValue>
498 NetworkingPrivateChromeOS::GetEnabledNetworkTypes() {
499 chromeos::NetworkStateHandler* state_handler = GetStateHandler();
501 scoped_ptr<base::ListValue> network_list(new base::ListValue);
503 if (state_handler->IsTechnologyEnabled(NetworkTypePattern::Ethernet()))
504 network_list->AppendString(::onc::network_type::kEthernet);
505 if (state_handler->IsTechnologyEnabled(NetworkTypePattern::WiFi()))
506 network_list->AppendString(::onc::network_type::kWiFi);
507 if (state_handler->IsTechnologyEnabled(NetworkTypePattern::Wimax()))
508 network_list->AppendString(::onc::network_type::kWimax);
509 if (state_handler->IsTechnologyEnabled(NetworkTypePattern::Cellular()))
510 network_list->AppendString(::onc::network_type::kCellular);
512 return network_list.Pass();
515 scoped_ptr<NetworkingPrivateDelegate::DeviceStateList>
516 NetworkingPrivateChromeOS::GetDeviceStateList() {
517 std::set<std::string> technologies_found;
518 NetworkStateHandler::DeviceStateList devices;
519 NetworkHandler::Get()->network_state_handler()->GetDeviceList(&devices);
521 scoped_ptr<DeviceStateList> device_state_list(new DeviceStateList);
522 for (const DeviceState* device : devices) {
523 std::string onc_type =
524 chromeos::network_util::TranslateShillTypeToONC(device->type());
525 AppendDeviceState(onc_type, device, device_state_list.get());
526 technologies_found.insert(onc_type);
529 // For any technologies that we do not have a DeviceState entry for, append
530 // an entry if the technolog is available.
531 const char* technology_types[] = {::onc::network_type::kEthernet,
532 ::onc::network_type::kWiFi,
533 ::onc::network_type::kWimax,
534 ::onc::network_type::kCellular};
535 for (const char* technology : technology_types) {
536 if (ContainsValue(technologies_found, technology))
537 continue;
538 AppendDeviceState(technology, nullptr /* device */,
539 device_state_list.get());
541 return device_state_list.Pass();
544 bool NetworkingPrivateChromeOS::EnableNetworkType(const std::string& type) {
545 NetworkTypePattern pattern =
546 chromeos::onc::NetworkTypePatternFromOncType(type);
548 GetStateHandler()->SetTechnologyEnabled(
549 pattern, true, chromeos::network_handler::ErrorCallback());
551 return true;
554 bool NetworkingPrivateChromeOS::DisableNetworkType(const std::string& type) {
555 NetworkTypePattern pattern =
556 chromeos::onc::NetworkTypePatternFromOncType(type);
558 GetStateHandler()->SetTechnologyEnabled(
559 pattern, false, chromeos::network_handler::ErrorCallback());
561 return true;
564 bool NetworkingPrivateChromeOS::RequestScan() {
565 GetStateHandler()->RequestScan();
566 return true;
569 } // namespace extensions