1 // Copyright (c) 2012 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. 4 5 #include "chrome/browser/ui/webui/options/chromeos/internet_options_handler.h" 6 7 #include <ctype.h> 8 9 #include <map> 10 #include <string> 11 #include <vector> 12 13 #include "ash/system/chromeos/network/network_connect.h" 14 #include "base/basictypes.h" 15 #include "base/bind.h" 16 #include "base/bind_helpers.h" 17 #include "base/command_line.h" 18 #include "base/strings/utf_string_conversions.h" 19 #include "base/values.h" 20 #include "chrome/browser/browser_process.h" 21 #include "chrome/browser/chromeos/mobile_config.h" 22 #include "chrome/browser/chromeos/net/onc_utils.h" 23 #include "chrome/browser/chromeos/options/network_config_view.h" 24 #include "chrome/browser/chromeos/options/network_property_ui_data.h" 25 #include "chrome/browser/chromeos/settings/cros_settings.h" 26 #include "chrome/browser/chromeos/sim_dialog_delegate.h" 27 #include "chrome/browser/chromeos/ui/choose_mobile_network_dialog.h" 28 #include "chrome/browser/chromeos/ui/mobile_config_ui.h" 29 #include "chrome/browser/chromeos/ui_proxy_config_service.h" 30 #include "chrome/browser/profiles/profile.h" 31 #include "chrome/browser/ui/webui/chromeos/mobile_setup_dialog.h" 32 #include "chrome/browser/ui/webui/options/chromeos/internet_options_handler_strings.h" 33 #include "chromeos/chromeos_switches.h" 34 #include "chromeos/login/login_state.h" 35 #include "chromeos/network/device_state.h" 36 #include "chromeos/network/managed_network_configuration_handler.h" 37 #include "chromeos/network/network_configuration_handler.h" 38 #include "chromeos/network/network_connection_handler.h" 39 #include "chromeos/network/network_device_handler.h" 40 #include "chromeos/network/network_event_log.h" 41 #include "chromeos/network/network_ip_config.h" 42 #include "chromeos/network/network_profile.h" 43 #include "chromeos/network/network_profile_handler.h" 44 #include "chromeos/network/network_state.h" 45 #include "chromeos/network/network_state_handler.h" 46 #include "chromeos/network/network_util.h" 47 #include "chromeos/network/onc/onc_signature.h" 48 #include "chromeos/network/onc/onc_translation_tables.h" 49 #include "chromeos/network/onc/onc_translator.h" 50 #include "chromeos/network/onc/onc_utils.h" 51 #include "components/onc/onc_constants.h" 52 #include "content/public/browser/web_contents.h" 53 #include "content/public/browser/web_ui.h" 54 #include "grit/ui_chromeos_resources.h" 55 #include "third_party/cros_system_api/dbus/service_constants.h" 56 #include "ui/base/resource/resource_bundle.h" 57 #include "ui/base/webui/web_ui_util.h" 58 #include "ui/chromeos/network/network_icon.h" 59 #include "ui/gfx/image/image_skia.h" 60 61 namespace chromeos { 62 namespace options { 63 64 namespace { 65 66 // Keys for the network description dictionary passed to the web ui. Make sure 67 // to keep the strings in sync with what the JavaScript side uses. 68 const char kNetworkInfoKeyIconURL[] = "iconURL"; 69 const char kNetworkInfoKeyPolicyManaged[] = "policyManaged"; 70 71 // These are types of name server selections from the web ui. 72 const char kNameServerTypeAutomatic[] = "automatic"; 73 const char kNameServerTypeGoogle[] = "google"; 74 75 // Google public name servers (DNS). 76 const char kGoogleNameServers[] = "8.8.4.4,8.8.8.8"; 77 78 // Functions we call in JavaScript. 79 const char kRefreshNetworkDataFunction[] = 80 "options.network.NetworkList.refreshNetworkData"; 81 const char kSetDefaultNetworkIconsFunction[] = 82 "options.network.NetworkList.setDefaultNetworkIcons"; 83 const char kSendNetworkDetailsFunction[] = 84 "options.internet.DetailsInternetPage.sendNetworkDetails"; 85 const char kShowDetailedInfoFunction[] = 86 "options.internet.DetailsInternetPage.showDetailedInfo"; 87 const char kUpdateConnectionDataFunction[] = 88 "options.internet.DetailsInternetPage.updateConnectionData"; 89 const char kUpdateCarrierFunction[] = 90 "options.internet.DetailsInternetPage.updateCarrier"; 91 92 // These are used to register message handlers with JavaScript. 93 const char kNetworkCommandMessage[] = "networkCommand"; 94 const char kSetApnMessage[] = "setApn"; 95 const char kSetAutoConnectMessage[] = "setAutoConnect"; 96 const char kSetCarrierMessage[] = "setCarrier"; 97 const char kSetIPConfigMessage[] = "setIPConfig"; 98 const char kSetPreferNetworkMessage[] = "setPreferNetwork"; 99 const char kSetServerHostname[] = "setServerHostname"; 100 const char kShowMorePlanInfoMessage[] = "showMorePlanInfo"; 101 const char kSimOperationMessage[] = "simOperation"; 102 103 // TODO(stevenjb): Replace these with the matching networkingPrivate methods. 104 // crbug.com/279351. 105 const char kDisableNetworkTypeMessage[] = "disableNetworkType"; 106 const char kEnableNetworkTypeMessage[] = "enableNetworkType"; 107 const char kGetManagedPropertiesMessage[] = "getManagedProperties"; 108 const char kRequestNetworkScanMessage[] = "requestNetworkScan"; 109 const char kStartConnectMessage[] = "startConnect"; 110 const char kStartDisconnectMessage[] = "startDisconnect"; 111 112 // These are strings used to communicate with JavaScript. 113 const char kTagActivate[] = "activate"; 114 const char kTagAddConnection[] = "add"; 115 const char kTagCarrierSelectFlag[] = "showCarrierSelect"; 116 const char kTagCellularAvailable[] = "cellularAvailable"; 117 const char kTagCellularEnabled[] = "cellularEnabled"; 118 const char kTagCellularSimAbsent[] = "cellularSimAbsent"; 119 const char kTagCellularSimLockType[] = "cellularSimLockType"; 120 const char kTagCellularSupportsScan[] = "cellularSupportsScan"; 121 const char kTagConfigure[] = "configure"; 122 const char kTagForget[] = "forget"; 123 const char kTagRememberedList[] = "rememberedList"; 124 const char kTagShowDetails[] = "showDetails"; 125 const char kTagShowViewAccountButton[] = "showViewAccountButton"; 126 const char kTagSimOpChangePin[] = "changePin"; 127 const char kTagSimOpConfigure[] = "configure"; 128 const char kTagSimOpSetLocked[] = "setLocked"; 129 const char kTagSimOpSetUnlocked[] = "setUnlocked"; 130 const char kTagSimOpUnlock[] = "unlock"; 131 const char kTagTrue[] = "true"; 132 const char kTagVpnList[] = "vpnList"; 133 const char kTagWifiAvailable[] = "wifiAvailable"; 134 const char kTagWifiEnabled[] = "wifiEnabled"; 135 const char kTagWimaxAvailable[] = "wimaxAvailable"; 136 const char kTagWimaxEnabled[] = "wimaxEnabled"; 137 const char kTagWiredList[] = "wiredList"; 138 const char kTagWirelessList[] = "wirelessList"; 139 140 // Pseudo-ONC chrome specific properties appended to the ONC dictionary. 141 const char kTagErrorMessage[] = "errorMessage"; 142 const char kNetworkInfoKeyServicePath[] = "servicePath"; 143 const char kNetworkInfoKeyGUID[] = "GUID"; 144 145 const int kPreferredPriority = 1; 146 147 void ShillError(const std::string& function, 148 const std::string& error_name, 149 scoped_ptr<base::DictionaryValue> error_data) { 150 // UpdateConnectionData may send requests for stale services; ignore 151 // these errors. 152 if (function == "UpdateConnectionData" && 153 error_name == network_handler::kDBusFailedError) 154 return; 155 NET_LOG_ERROR("Shill Error from InternetOptionsHandler: " + error_name, 156 function); 157 } 158 159 const NetworkState* GetNetworkState(const std::string& service_path) { 160 return NetworkHandler::Get()->network_state_handler()-> 161 GetNetworkState(service_path); 162 } 163 164 void SetNetworkProperty(const std::string& service_path, 165 const std::string& property, 166 base::Value* value) { 167 NET_LOG_EVENT("SetNetworkProperty: " + property, service_path); 168 base::DictionaryValue properties; 169 properties.SetWithoutPathExpansion(property, value); 170 NetworkHandler::Get()->network_configuration_handler()->SetProperties( 171 service_path, properties, 172 base::Bind(&base::DoNothing), 173 base::Bind(&ShillError, "SetNetworkProperty")); 174 } 175 176 // Builds a dictionary with network information and an icon used for the 177 // NetworkList on the settings page. Ownership of the returned pointer is 178 // transferred to the caller. 179 base::DictionaryValue* BuildNetworkDictionary( 180 const NetworkState* network, 181 float icon_scale_factor, 182 const PrefService* profile_prefs) { 183 scoped_ptr<base::DictionaryValue> network_info = 184 network_util::TranslateNetworkStateToONC(network); 185 186 bool has_policy = onc::HasPolicyForNetwork( 187 profile_prefs, g_browser_process->local_state(), *network); 188 network_info->SetBoolean(kNetworkInfoKeyPolicyManaged, has_policy); 189 190 std::string icon_url = ui::network_icon::GetImageUrlForNetwork( 191 network, ui::network_icon::ICON_TYPE_LIST, icon_scale_factor); 192 193 network_info->SetString(kNetworkInfoKeyIconURL, icon_url); 194 network_info->SetString(kNetworkInfoKeyServicePath, network->path()); 195 196 return network_info.release(); 197 } 198 199 bool ShowViewAccountButton(const NetworkState* cellular) { 200 if (cellular->activation_state() != shill::kActivationStateActivating && 201 cellular->activation_state() != shill::kActivationStateActivated) 202 return false; 203 204 const DeviceState* device = 205 NetworkHandler::Get()->network_state_handler()->GetDeviceState( 206 cellular->device_path()); 207 208 // If no online payment URL was provided by shill, Check to see if the 209 // MobileConfig carrier indicates that "View Account" should be shown. 210 if (cellular->payment_url().empty()) { 211 if (!device || !MobileConfig::GetInstance()->IsReady()) 212 return false; 213 const MobileConfig::Carrier* carrier = 214 MobileConfig::GetInstance()->GetCarrier(device->home_provider_id()); 215 if (!carrier || !carrier->show_portal_button()) 216 return false; 217 } 218 219 if (!cellular->IsConnectedState()) { 220 // Disconnected LTE networks should show the button if we are online and 221 // the device's MDN is set. This is to enable users to update their plan 222 // if they are out of credits. 223 if (!NetworkHandler::Get()->network_state_handler()->DefaultNetwork()) 224 return false; 225 const std::string& technology = cellular->network_technology(); 226 if (technology != shill::kNetworkTechnologyLte && 227 technology != shill::kNetworkTechnologyLteAdvanced) 228 return false; 229 std::string mdn; 230 if (device) { 231 device->properties().GetStringWithoutPathExpansion(shill::kMdnProperty, 232 &mdn); 233 } 234 if (mdn.empty()) 235 return false; 236 } 237 238 return true; 239 } 240 241 scoped_ptr<base::DictionaryValue> PopulateConnectionDetails( 242 const NetworkState* network, 243 const base::DictionaryValue& onc_properties) { 244 scoped_ptr<base::DictionaryValue> dictionary(onc_properties.DeepCopy()); 245 246 // Append Service Path for now. 247 dictionary->SetString(kNetworkInfoKeyServicePath, network->path()); 248 // Append a Chrome specific translated error message. 249 dictionary->SetString( 250 kTagErrorMessage, 251 ash::network_connect::ErrorString(network->error(), network->path())); 252 253 return dictionary.Pass(); 254 } 255 256 // Helper methods for SetIPConfigProperties 257 bool AppendPropertyKeyIfPresent(const std::string& key, 258 const base::DictionaryValue& old_properties, 259 std::vector<std::string>* property_keys) { 260 if (old_properties.HasKey(key)) { 261 property_keys->push_back(key); 262 return true; 263 } 264 return false; 265 } 266 267 bool AddStringPropertyIfChanged(const std::string& key, 268 const std::string& new_value, 269 const base::DictionaryValue& old_properties, 270 base::DictionaryValue* new_properties) { 271 std::string old_value; 272 if (!old_properties.GetStringWithoutPathExpansion(key, &old_value) || 273 new_value != old_value) { 274 new_properties->SetStringWithoutPathExpansion(key, new_value); 275 return true; 276 } 277 return false; 278 } 279 280 bool AddIntegerPropertyIfChanged(const std::string& key, 281 int new_value, 282 const base::DictionaryValue& old_properties, 283 base::DictionaryValue* new_properties) { 284 int old_value; 285 if (!old_properties.GetIntegerWithoutPathExpansion(key, &old_value) || 286 new_value != old_value) { 287 new_properties->SetIntegerWithoutPathExpansion(key, new_value); 288 return true; 289 } 290 return false; 291 } 292 293 } // namespace 294 295 InternetOptionsHandler::InternetOptionsHandler() 296 : weak_factory_(this) { 297 NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE); 298 } 299 300 InternetOptionsHandler::~InternetOptionsHandler() { 301 if (NetworkHandler::IsInitialized()) { 302 NetworkHandler::Get()->network_state_handler()->RemoveObserver( 303 this, FROM_HERE); 304 } 305 } 306 307 void InternetOptionsHandler::GetLocalizedValues( 308 base::DictionaryValue* localized_strings) { 309 DCHECK(localized_strings); 310 internet_options_strings::RegisterLocalizedStrings(localized_strings); 311 312 // TODO(stevenjb): Find a better way to populate initial data before 313 // InitializePage() gets called. 314 std::string owner; 315 chromeos::CrosSettings::Get()->GetString(chromeos::kDeviceOwner, &owner); 316 localized_strings->SetString("ownerUserId", base::UTF8ToUTF16(owner)); 317 bool logged_in_as_owner = LoginState::Get()->GetLoggedInUserType() == 318 LoginState::LOGGED_IN_USER_OWNER; 319 localized_strings->SetBoolean("loggedInAsOwner", logged_in_as_owner); 320 321 base::DictionaryValue* network_dictionary = new base::DictionaryValue; 322 FillNetworkInfo(network_dictionary); 323 localized_strings->Set("networkData", network_dictionary); 324 } 325 326 void InternetOptionsHandler::InitializePage() { 327 base::DictionaryValue dictionary; 328 dictionary.SetString(::onc::network_type::kCellular, 329 GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_BARS_DARK)); 330 dictionary.SetString(::onc::network_type::kWiFi, 331 GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_ARCS_DARK)); 332 dictionary.SetString(::onc::network_type::kVPN, 333 GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_VPN)); 334 web_ui()->CallJavascriptFunction(kSetDefaultNetworkIconsFunction, 335 dictionary); 336 NetworkHandler::Get()->network_state_handler()->RequestScan(); 337 RefreshNetworkData(); 338 } 339 340 void InternetOptionsHandler::RegisterMessages() { 341 // Setup handlers specific to this panel. 342 web_ui()->RegisterMessageCallback(kNetworkCommandMessage, 343 base::Bind(&InternetOptionsHandler::NetworkCommandCallback, 344 base::Unretained(this))); 345 web_ui()->RegisterMessageCallback(kSetPreferNetworkMessage, 346 base::Bind(&InternetOptionsHandler::SetPreferNetworkCallback, 347 base::Unretained(this))); 348 web_ui()->RegisterMessageCallback(kSetAutoConnectMessage, 349 base::Bind(&InternetOptionsHandler::SetAutoConnectCallback, 350 base::Unretained(this))); 351 web_ui()->RegisterMessageCallback(kSetIPConfigMessage, 352 base::Bind(&InternetOptionsHandler::SetIPConfigCallback, 353 base::Unretained(this))); 354 web_ui()->RegisterMessageCallback(kShowMorePlanInfoMessage, 355 base::Bind(&InternetOptionsHandler::ShowMorePlanInfoCallback, 356 base::Unretained(this))); 357 web_ui()->RegisterMessageCallback(kSetApnMessage, 358 base::Bind(&InternetOptionsHandler::SetApnCallback, 359 base::Unretained(this))); 360 web_ui()->RegisterMessageCallback(kSetCarrierMessage, 361 base::Bind(&InternetOptionsHandler::SetCarrierCallback, 362 base::Unretained(this))); 363 web_ui()->RegisterMessageCallback(kSimOperationMessage, 364 base::Bind(&InternetOptionsHandler::SimOperationCallback, 365 base::Unretained(this))); 366 web_ui()->RegisterMessageCallback(kSetServerHostname, 367 base::Bind(&InternetOptionsHandler::SetServerHostnameCallback, 368 base::Unretained(this))); 369 370 // networkingPrivate methods 371 web_ui()->RegisterMessageCallback(kDisableNetworkTypeMessage, 372 base::Bind(&InternetOptionsHandler::DisableNetworkTypeCallback, 373 base::Unretained(this))); 374 web_ui()->RegisterMessageCallback(kEnableNetworkTypeMessage, 375 base::Bind(&InternetOptionsHandler::EnableNetworkTypeCallback, 376 base::Unretained(this))); 377 web_ui()->RegisterMessageCallback(kGetManagedPropertiesMessage, 378 base::Bind(&InternetOptionsHandler::GetManagedPropertiesCallback, 379 base::Unretained(this))); 380 web_ui()->RegisterMessageCallback(kRequestNetworkScanMessage, 381 base::Bind(&InternetOptionsHandler::RequestNetworkScanCallback, 382 base::Unretained(this))); 383 web_ui()->RegisterMessageCallback(kStartConnectMessage, 384 base::Bind(&InternetOptionsHandler::StartConnectCallback, 385 base::Unretained(this))); 386 web_ui()->RegisterMessageCallback(kStartDisconnectMessage, 387 base::Bind(&InternetOptionsHandler::StartDisconnectCallback, 388 base::Unretained(this))); 389 } 390 391 void InternetOptionsHandler::ShowMorePlanInfoCallback( 392 const base::ListValue* args) { 393 if (!web_ui()) 394 return; 395 std::string service_path; 396 if (args->GetSize() != 1 || !args->GetString(0, &service_path)) { 397 NOTREACHED(); 398 return; 399 } 400 ash::network_connect::ShowMobileSetup(service_path); 401 } 402 403 void InternetOptionsHandler::SetApnCallback(const base::ListValue* args) { 404 std::string service_path; 405 if (!args->GetString(0, &service_path)) { 406 NOTREACHED(); 407 return; 408 } 409 NetworkHandler::Get()->network_configuration_handler()->GetProperties( 410 service_path, 411 base::Bind(&InternetOptionsHandler::SetApnProperties, 412 weak_factory_.GetWeakPtr(), base::Owned(args->DeepCopy())), 413 base::Bind(&ShillError, "SetApnCallback")); 414 } 415 416 void InternetOptionsHandler::SetApnProperties( 417 const base::ListValue* args, 418 const std::string& service_path, 419 const base::DictionaryValue& shill_properties) { 420 std::string apn, username, password; 421 if (!args->GetString(1, &apn) || 422 !args->GetString(2, &username) || 423 !args->GetString(3, &password)) { 424 NOTREACHED(); 425 return; 426 } 427 NET_LOG_EVENT("SetApnCallback", service_path); 428 429 if (apn.empty()) { 430 std::vector<std::string> properties_to_clear; 431 properties_to_clear.push_back(shill::kCellularApnProperty); 432 NetworkHandler::Get()->network_configuration_handler()->ClearProperties( 433 service_path, properties_to_clear, 434 base::Bind(&base::DoNothing), 435 base::Bind(&ShillError, "ClearCellularApnProperties")); 436 return; 437 } 438 439 const base::DictionaryValue* shill_apn_dict = NULL; 440 std::string network_id; 441 if (shill_properties.GetDictionaryWithoutPathExpansion( 442 shill::kCellularApnProperty, &shill_apn_dict)) { 443 shill_apn_dict->GetStringWithoutPathExpansion( 444 shill::kApnNetworkIdProperty, &network_id); 445 } 446 base::DictionaryValue properties; 447 base::DictionaryValue* apn_dict = new base::DictionaryValue; 448 apn_dict->SetStringWithoutPathExpansion(shill::kApnProperty, apn); 449 apn_dict->SetStringWithoutPathExpansion(shill::kApnNetworkIdProperty, 450 network_id); 451 apn_dict->SetStringWithoutPathExpansion(shill::kApnUsernameProperty, 452 username); 453 apn_dict->SetStringWithoutPathExpansion(shill::kApnPasswordProperty, 454 password); 455 properties.SetWithoutPathExpansion(shill::kCellularApnProperty, apn_dict); 456 NetworkHandler::Get()->network_configuration_handler()->SetProperties( 457 service_path, properties, 458 base::Bind(&base::DoNothing), 459 base::Bind(&ShillError, "SetApnProperties")); 460 } 461 462 void InternetOptionsHandler::CarrierStatusCallback() { 463 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); 464 const DeviceState* device = 465 handler->GetDeviceStateByType(NetworkTypePattern::Cellular()); 466 if (device && (device->carrier() == shill::kCarrierSprint)) { 467 const NetworkState* network = 468 handler->FirstNetworkByType(NetworkTypePattern::Cellular()); 469 if (network && network->path() == details_path_) { 470 ash::network_connect::ActivateCellular(network->path()); 471 UpdateConnectionData(network->path()); 472 } 473 } 474 UpdateCarrier(); 475 } 476 477 void InternetOptionsHandler::SetCarrierCallback(const base::ListValue* args) { 478 std::string service_path; 479 std::string carrier; 480 if (args->GetSize() != 2 || 481 !args->GetString(0, &service_path) || 482 !args->GetString(1, &carrier)) { 483 NOTREACHED(); 484 return; 485 } 486 const DeviceState* device = NetworkHandler::Get()->network_state_handler()-> 487 GetDeviceStateByType(NetworkTypePattern::Cellular()); 488 if (!device) { 489 LOG(WARNING) << "SetCarrierCallback with no cellular device."; 490 return; 491 } 492 NetworkHandler::Get()->network_device_handler()->SetCarrier( 493 device->path(), 494 carrier, 495 base::Bind(&InternetOptionsHandler::CarrierStatusCallback, 496 weak_factory_.GetWeakPtr()), 497 base::Bind(&ShillError, "SetCarrierCallback")); 498 } 499 500 void InternetOptionsHandler::SimOperationCallback(const base::ListValue* args) { 501 std::string operation; 502 if (args->GetSize() != 1 || !args->GetString(0, &operation)) { 503 NOTREACHED(); 504 return; 505 } 506 if (operation == kTagSimOpConfigure) { 507 mobile_config_ui::DisplayConfigDialog(); 508 return; 509 } 510 // 1. Bring up SIM unlock dialog, pass new RequirePin setting in URL. 511 // 2. Dialog will ask for current PIN in any case. 512 // 3. If card is locked it will first call PIN unlock operation 513 // 4. Then it will call Set RequirePin, passing the same PIN. 514 // 5. The dialog may change device properties, in which case 515 // DevicePropertiesUpdated() will get called which will update the UI. 516 SimDialogDelegate::SimDialogMode mode; 517 if (operation == kTagSimOpSetLocked) { 518 mode = SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON; 519 } else if (operation == kTagSimOpSetUnlocked) { 520 mode = SimDialogDelegate::SIM_DIALOG_SET_LOCK_OFF; 521 } else if (operation == kTagSimOpUnlock) { 522 mode = SimDialogDelegate::SIM_DIALOG_UNLOCK; 523 } else if (operation == kTagSimOpChangePin) { 524 mode = SimDialogDelegate::SIM_DIALOG_CHANGE_PIN; 525 } else { 526 NOTREACHED(); 527 return; 528 } 529 SimDialogDelegate::ShowDialog(GetNativeWindow(), mode); 530 } 531 532 //////////////////////////////////////////////////////////////////////////////// 533 // networkingPrivate implementation methods. TODO(stevenjb): Use the 534 // networkingPrivate API directly in the settings JS and deprecate these 535 // methods. crbug.com/279351. 536 537 void InternetOptionsHandler::DisableNetworkTypeCallback( 538 const base::ListValue* args) { 539 std::string type; 540 if (!args->GetString(0, &type)) { 541 NOTREACHED(); 542 return; 543 } 544 NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled( 545 chromeos::onc::NetworkTypePatternFromOncType(type), false, 546 base::Bind(&ShillError, "DisableNetworkType")); 547 } 548 549 void InternetOptionsHandler::EnableNetworkTypeCallback( 550 const base::ListValue* args) { 551 std::string type; 552 if (!args->GetString(0, &type)) { 553 NOTREACHED(); 554 return; 555 } 556 NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled( 557 chromeos::onc::NetworkTypePatternFromOncType(type), true, 558 base::Bind(&ShillError, "EnableNetworkType")); 559 } 560 561 void InternetOptionsHandler::GetManagedPropertiesCallback( 562 const base::ListValue* args) { 563 std::string service_path; 564 if (!args->GetString(0, &service_path)) { 565 NOTREACHED(); 566 return; 567 } 568 NetworkHandler::Get()->managed_network_configuration_handler() 569 ->GetManagedProperties( 570 LoginState::Get()->primary_user_hash(), 571 service_path, 572 base::Bind( 573 &InternetOptionsHandler::PopulateDictionaryDetailsCallback, 574 weak_factory_.GetWeakPtr()), 575 base::Bind(&ShillError, "GetManagedProperties")); 576 } 577 578 void InternetOptionsHandler::RequestNetworkScanCallback( 579 const base::ListValue* args) { 580 NetworkHandler::Get()->network_state_handler()->RequestScan(); 581 } 582 583 void InternetOptionsHandler::StartConnectCallback(const base::ListValue* args) { 584 std::string service_path; 585 if (!args->GetString(0, &service_path)) { 586 NOTREACHED(); 587 return; 588 } 589 ash::network_connect::ConnectToNetwork(service_path); 590 } 591 592 void InternetOptionsHandler::StartDisconnectCallback( 593 const base::ListValue* args) { 594 std::string service_path; 595 if (!args->GetString(0, &service_path)) { 596 NOTREACHED(); 597 return; 598 } 599 NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork( 600 service_path, 601 base::Bind(&base::DoNothing), 602 base::Bind(&ShillError, "StartDisconnectCallback")); 603 } 604 605 //////////////////////////////////////////////////////////////////////////////// 606 607 std::string InternetOptionsHandler::GetIconDataUrl(int resource_id) const { 608 gfx::ImageSkia* icon = 609 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id); 610 gfx::ImageSkiaRep image_rep = icon->GetRepresentation( 611 web_ui()->GetDeviceScaleFactor()); 612 return webui::GetBitmapDataUrl(image_rep.sk_bitmap()); 613 } 614 615 void InternetOptionsHandler::RefreshNetworkData() { 616 base::DictionaryValue dictionary; 617 FillNetworkInfo(&dictionary); 618 web_ui()->CallJavascriptFunction(kRefreshNetworkDataFunction, dictionary); 619 } 620 621 void InternetOptionsHandler::UpdateConnectionData( 622 const std::string& service_path) { 623 NetworkHandler::Get() 624 ->managed_network_configuration_handler() 625 ->GetManagedProperties( 626 LoginState::Get()->primary_user_hash(), 627 service_path, 628 base::Bind(&InternetOptionsHandler::UpdateConnectionDataCallback, 629 weak_factory_.GetWeakPtr()), 630 base::Bind(&ShillError, "UpdateConnectionData")); 631 } 632 633 void InternetOptionsHandler::UpdateConnectionDataCallback( 634 const std::string& service_path, 635 const base::DictionaryValue& onc_properties) { 636 const NetworkState* network = GetNetworkState(service_path); 637 if (!network) 638 return; 639 scoped_ptr<base::DictionaryValue> dictionary = 640 PopulateConnectionDetails(network, onc_properties); 641 web_ui()->CallJavascriptFunction(kUpdateConnectionDataFunction, *dictionary); 642 } 643 644 void InternetOptionsHandler::UpdateCarrier() { 645 web_ui()->CallJavascriptFunction(kUpdateCarrierFunction); 646 } 647 648 void InternetOptionsHandler::DeviceListChanged() { 649 if (!web_ui()) 650 return; 651 RefreshNetworkData(); 652 } 653 654 void InternetOptionsHandler::NetworkListChanged() { 655 if (!web_ui()) 656 return; 657 RefreshNetworkData(); 658 } 659 660 void InternetOptionsHandler::NetworkConnectionStateChanged( 661 const NetworkState* network) { 662 if (!web_ui()) 663 return; 664 if (network->path() == details_path_) 665 UpdateConnectionData(network->path()); 666 } 667 668 void InternetOptionsHandler::NetworkPropertiesUpdated( 669 const NetworkState* network) { 670 if (!web_ui()) 671 return; 672 RefreshNetworkData(); 673 if (network->path() == details_path_) 674 UpdateConnectionData(network->path()); 675 } 676 677 void InternetOptionsHandler::DevicePropertiesUpdated( 678 const DeviceState* device) { 679 if (!web_ui()) 680 return; 681 if (device->type() != shill::kTypeCellular) 682 return; 683 const NetworkState* network = 684 NetworkHandler::Get()->network_state_handler()->FirstNetworkByType( 685 NetworkTypePattern::Cellular()); 686 if (network && network->path() == details_path_) 687 UpdateConnectionData(network->path()); 688 } 689 690 void InternetOptionsHandler::SetServerHostnameCallback( 691 const base::ListValue* args) { 692 std::string service_path, server_hostname; 693 if (args->GetSize() < 2 || 694 !args->GetString(0, &service_path) || 695 !args->GetString(1, &server_hostname)) { 696 NOTREACHED(); 697 return; 698 } 699 SetNetworkProperty(service_path, 700 shill::kProviderHostProperty, 701 new base::StringValue(server_hostname)); 702 } 703 704 void InternetOptionsHandler::SetPreferNetworkCallback( 705 const base::ListValue* args) { 706 std::string service_path, prefer_network_str; 707 if (args->GetSize() < 2 || 708 !args->GetString(0, &service_path) || 709 !args->GetString(1, &prefer_network_str)) { 710 NOTREACHED(); 711 return; 712 } 713 int priority = (prefer_network_str == kTagTrue) ? kPreferredPriority : 0; 714 SetNetworkProperty(service_path, 715 shill::kPriorityProperty, 716 new base::FundamentalValue(priority)); 717 } 718 719 void InternetOptionsHandler::SetAutoConnectCallback( 720 const base::ListValue* args) { 721 std::string service_path, auto_connect_str; 722 if (args->GetSize() < 2 || 723 !args->GetString(0, &service_path) || 724 !args->GetString(1, &auto_connect_str)) { 725 NOTREACHED(); 726 return; 727 } 728 bool auto_connect = auto_connect_str == kTagTrue; 729 SetNetworkProperty(service_path, 730 shill::kAutoConnectProperty, 731 new base::FundamentalValue(auto_connect)); 732 } 733 734 void InternetOptionsHandler::SetIPConfigCallback(const base::ListValue* args) { 735 std::string service_path; 736 if (!args->GetString(0, &service_path)) { 737 NOTREACHED(); 738 return; 739 } 740 NetworkHandler::Get()->network_configuration_handler()->GetProperties( 741 service_path, 742 base::Bind(&InternetOptionsHandler::SetIPConfigProperties, 743 weak_factory_.GetWeakPtr(), base::Owned(args->DeepCopy())), 744 base::Bind(&ShillError, "SetIPConfigCallback")); 745 } 746 747 void InternetOptionsHandler::SetIPConfigProperties( 748 const base::ListValue* args, 749 const std::string& service_path, 750 const base::DictionaryValue& shill_properties) { 751 std::string address, netmask, gateway, name_server_type, name_servers; 752 bool dhcp_for_ip; 753 if (!args->GetBoolean(1, &dhcp_for_ip) || 754 !args->GetString(2, &address) || 755 !args->GetString(3, &netmask) || 756 !args->GetString(4, &gateway) || 757 !args->GetString(5, &name_server_type) || 758 !args->GetString(6, &name_servers)) { 759 NOTREACHED(); 760 return; 761 } 762 NET_LOG_USER("SetIPConfigProperties: " + name_server_type, service_path); 763 764 std::vector<std::string> properties_to_clear; 765 base::DictionaryValue properties_to_set; 766 767 if (dhcp_for_ip) { 768 AppendPropertyKeyIfPresent(shill::kStaticIPAddressProperty, 769 shill_properties, 770 &properties_to_clear); 771 AppendPropertyKeyIfPresent(shill::kStaticIPPrefixlenProperty, 772 shill_properties, 773 &properties_to_clear); 774 AppendPropertyKeyIfPresent(shill::kStaticIPGatewayProperty, 775 shill_properties, 776 &properties_to_clear); 777 } else { 778 AddStringPropertyIfChanged(shill::kStaticIPAddressProperty, 779 address, 780 shill_properties, 781 &properties_to_set); 782 int prefixlen = network_util::NetmaskToPrefixLength(netmask); 783 if (prefixlen < 0) { 784 LOG(ERROR) << "Invalid prefix length for: " << service_path 785 << " with netmask " << netmask; 786 prefixlen = 0; 787 } 788 AddIntegerPropertyIfChanged(shill::kStaticIPPrefixlenProperty, 789 prefixlen, 790 shill_properties, 791 &properties_to_set); 792 AddStringPropertyIfChanged(shill::kStaticIPGatewayProperty, 793 gateway, 794 shill_properties, 795 &properties_to_set); 796 } 797 798 if (name_server_type == kNameServerTypeAutomatic) { 799 AppendPropertyKeyIfPresent(shill::kStaticIPNameServersProperty, 800 shill_properties, 801 &properties_to_clear); 802 } else { 803 if (name_server_type == kNameServerTypeGoogle) 804 name_servers = kGoogleNameServers; 805 AddStringPropertyIfChanged(shill::kStaticIPNameServersProperty, 806 name_servers, 807 shill_properties, 808 &properties_to_set); 809 } 810 811 if (!properties_to_clear.empty()) { 812 NetworkHandler::Get()->network_configuration_handler()->ClearProperties( 813 service_path, 814 properties_to_clear, 815 base::Bind(&base::DoNothing), 816 base::Bind(&ShillError, "ClearIPConfigProperties")); 817 } 818 if (!properties_to_set.empty()) { 819 NetworkHandler::Get()->network_configuration_handler()->SetProperties( 820 service_path, 821 properties_to_set, 822 base::Bind(&base::DoNothing), 823 base::Bind(&ShillError, "SetIPConfigProperties")); 824 } 825 std::string device_path; 826 shill_properties.GetStringWithoutPathExpansion(shill::kDeviceProperty, 827 &device_path); 828 if (!device_path.empty()) { 829 NetworkHandler::Get()->network_device_handler()->RequestRefreshIPConfigs( 830 device_path, 831 base::Bind(&base::DoNothing), 832 base::Bind(&ShillError, "RequestRefreshIPConfigs")); 833 } 834 } 835 836 void InternetOptionsHandler::PopulateDictionaryDetailsCallback( 837 const std::string& service_path, 838 const base::DictionaryValue& onc_properties) { 839 const NetworkState* network = GetNetworkState(service_path); 840 if (!network) { 841 LOG(ERROR) << "Network properties not found: " << service_path; 842 return; 843 } 844 scoped_ptr<base::DictionaryValue> dictionary = 845 PopulateConnectionDetails(network, onc_properties); 846 847 // Show details dialog 848 web_ui()->CallJavascriptFunction(kSendNetworkDetailsFunction, *dictionary); 849 } 850 851 gfx::NativeWindow InternetOptionsHandler::GetNativeWindow() const { 852 return web_ui()->GetWebContents()->GetTopLevelNativeWindow(); 853 } 854 855 float InternetOptionsHandler::GetScaleFactor() const { 856 return web_ui()->GetDeviceScaleFactor(); 857 } 858 859 const PrefService* InternetOptionsHandler::GetPrefs() const { 860 return Profile::FromWebUI(web_ui())->GetPrefs(); 861 } 862 863 void InternetOptionsHandler::NetworkCommandCallback( 864 const base::ListValue* args) { 865 std::string onc_type; 866 std::string service_path; 867 std::string command; 868 if (args->GetSize() != 3 || 869 !args->GetString(0, &onc_type) || 870 !args->GetString(1, &service_path) || 871 !args->GetString(2, &command)) { 872 NOTREACHED(); 873 return; 874 } 875 std::string type; // Shill type 876 if (!onc_type.empty()) { 877 type = network_util::TranslateONCTypeToShill(onc_type); 878 if (type.empty()) 879 LOG(ERROR) << "Unable to translate ONC type: " << onc_type; 880 } 881 // Process commands that do not require an existing network. 882 if (command == kTagAddConnection) { 883 AddConnection(type); 884 } else if (command == kTagForget) { 885 NetworkHandler::Get()->network_configuration_handler()-> 886 RemoveConfiguration( 887 service_path, 888 base::Bind(&base::DoNothing), 889 base::Bind(&ShillError, "NetworkCommand: " + command)); 890 } else if (command == kTagShowDetails) { 891 SendShowDetailedInfo(service_path); 892 } else if (command == kTagConfigure) { 893 NetworkConfigView::Show(service_path, GetNativeWindow()); 894 } else if (command == kTagActivate && type == shill::kTypeCellular) { 895 ash::network_connect::ActivateCellular(service_path); 896 // Activation may update network properties (e.g. ActivationState), so 897 // request them here in case they change. 898 UpdateConnectionData(service_path); 899 } else { 900 LOG(ERROR) << "Unknown internet options command: " << command; 901 NOTREACHED(); 902 } 903 } 904 905 void InternetOptionsHandler::AddConnection(const std::string& type) { 906 if (type == shill::kTypeWifi) { 907 NetworkConfigView::ShowForType(shill::kTypeWifi, GetNativeWindow()); 908 } else if (type == shill::kTypeVPN) { 909 NetworkConfigView::ShowForType(shill::kTypeVPN, GetNativeWindow()); 910 } else if (type == shill::kTypeCellular) { 911 ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow()); 912 } else { 913 LOG(ERROR) << "Unsupported type for AddConnection"; 914 } 915 } 916 917 void InternetOptionsHandler::SendShowDetailedInfo( 918 const std::string& service_path) { 919 details_path_ = service_path; 920 921 scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue); 922 const NetworkState* network = GetNetworkState(service_path); 923 if (network) { 924 dictionary->SetString(kNetworkInfoKeyServicePath, service_path); 925 dictionary->SetString(kNetworkInfoKeyGUID, network->guid()); 926 if (network->type() == shill::kTypeCellular) { 927 dictionary->SetBoolean( 928 kTagCarrierSelectFlag, 929 CommandLine::ForCurrentProcess() 930 ->HasSwitch(chromeos::switches::kEnableCarrierSwitching)); 931 dictionary->SetBoolean(kTagShowViewAccountButton, 932 ShowViewAccountButton(network)); 933 } 934 } 935 web_ui()->CallJavascriptFunction(kShowDetailedInfoFunction, *dictionary); 936 } 937 938 base::ListValue* InternetOptionsHandler::GetWiredList() { 939 base::ListValue* list = new base::ListValue(); 940 const NetworkState* network = NetworkHandler::Get()->network_state_handler()-> 941 FirstNetworkByType(NetworkTypePattern::Ethernet()); 942 if (!network) 943 return list; 944 list->Append(BuildNetworkDictionary(network, GetScaleFactor(), GetPrefs())); 945 return list; 946 } 947 948 base::ListValue* InternetOptionsHandler::GetWirelessList() { 949 base::ListValue* list = new base::ListValue(); 950 951 NetworkStateHandler::NetworkStateList networks; 952 NetworkHandler::Get()->network_state_handler()->GetVisibleNetworkListByType( 953 NetworkTypePattern::Wireless(), &networks); 954 for (NetworkStateHandler::NetworkStateList::const_iterator iter = 955 networks.begin(); iter != networks.end(); ++iter) { 956 list->Append(BuildNetworkDictionary(*iter, GetScaleFactor(), GetPrefs())); 957 } 958 959 return list; 960 } 961 962 base::ListValue* InternetOptionsHandler::GetVPNList() { 963 base::ListValue* list = new base::ListValue(); 964 965 NetworkStateHandler::NetworkStateList networks; 966 NetworkHandler::Get()->network_state_handler()->GetVisibleNetworkListByType( 967 NetworkTypePattern::VPN(), &networks); 968 for (NetworkStateHandler::NetworkStateList::const_iterator iter = 969 networks.begin(); iter != networks.end(); ++iter) { 970 list->Append(BuildNetworkDictionary(*iter, GetScaleFactor(), GetPrefs())); 971 } 972 973 return list; 974 } 975 976 base::ListValue* InternetOptionsHandler::GetRememberedList() { 977 base::ListValue* list = new base::ListValue(); 978 979 NetworkStateHandler::NetworkStateList networks; 980 NetworkHandler::Get()->network_state_handler()->GetNetworkListByType( 981 NetworkTypePattern::Default(), 982 true /* configured_only */, 983 false /* visible_only */, 984 0 /* no limit */, 985 &networks); 986 for (NetworkStateHandler::NetworkStateList::const_iterator iter = 987 networks.begin(); iter != networks.end(); ++iter) { 988 const NetworkState* network = *iter; 989 if (network->type() != shill::kTypeWifi && 990 network->type() != shill::kTypeVPN) 991 continue; 992 list->Append( 993 BuildNetworkDictionary(network, 994 web_ui()->GetDeviceScaleFactor(), 995 Profile::FromWebUI(web_ui())->GetPrefs())); 996 } 997 998 return list; 999 } 1000 1001 void InternetOptionsHandler::FillNetworkInfo( 1002 base::DictionaryValue* dictionary) { 1003 NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); 1004 dictionary->Set(kTagWiredList, GetWiredList()); 1005 dictionary->Set(kTagWirelessList, GetWirelessList()); 1006 dictionary->Set(kTagVpnList, GetVPNList()); 1007 dictionary->Set(kTagRememberedList, GetRememberedList()); 1008 1009 dictionary->SetBoolean( 1010 kTagWifiAvailable, 1011 handler->IsTechnologyAvailable(NetworkTypePattern::WiFi())); 1012 dictionary->SetBoolean( 1013 kTagWifiEnabled, 1014 handler->IsTechnologyEnabled(NetworkTypePattern::WiFi())); 1015 1016 const DeviceState* cellular = 1017 handler->GetDeviceStateByType(NetworkTypePattern::Mobile()); 1018 dictionary->SetBoolean( 1019 kTagCellularAvailable, 1020 handler->IsTechnologyAvailable(NetworkTypePattern::Mobile())); 1021 dictionary->SetBoolean( 1022 kTagCellularEnabled, 1023 handler->IsTechnologyEnabled(NetworkTypePattern::Mobile())); 1024 dictionary->SetBoolean(kTagCellularSupportsScan, 1025 cellular && cellular->support_network_scan()); 1026 dictionary->SetBoolean(kTagCellularSimAbsent, 1027 cellular && cellular->IsSimAbsent()); 1028 dictionary->SetString(kTagCellularSimLockType, 1029 cellular ? cellular->sim_lock_type() : ""); 1030 1031 dictionary->SetBoolean( 1032 kTagWimaxAvailable, 1033 handler->IsTechnologyAvailable(NetworkTypePattern::Wimax())); 1034 dictionary->SetBoolean( 1035 kTagWimaxEnabled, 1036 handler->IsTechnologyEnabled(NetworkTypePattern::Wimax())); 1037 } 1038 1039 } // namespace options 1040 } // namespace chromeos 1041