Home | History | Annotate | Download | only in chromeos
      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