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/shell.h"
     14 #include "ash/shell_delegate.h"
     15 #include "ash/system/chromeos/network/network_connect.h"
     16 #include "ash/system/chromeos/network/network_icon.h"
     17 #include "base/base64.h"
     18 #include "base/basictypes.h"
     19 #include "base/bind.h"
     20 #include "base/bind_helpers.h"
     21 #include "base/command_line.h"
     22 #include "base/i18n/time_formatting.h"
     23 #include "base/json/json_writer.h"
     24 #include "base/strings/string16.h"
     25 #include "base/strings/string_number_conversions.h"
     26 #include "base/strings/stringprintf.h"
     27 #include "base/strings/utf_string_conversions.h"
     28 #include "base/time/time.h"
     29 #include "base/values.h"
     30 #include "chrome/browser/browser_process.h"
     31 #include "chrome/browser/chrome_notification_types.h"
     32 #include "chrome/browser/chromeos/choose_mobile_network_dialog.h"
     33 #include "chrome/browser/chromeos/cros/network_library.h"
     34 #include "chrome/browser/chromeos/cros/network_property_ui_data.h"
     35 #include "chrome/browser/chromeos/enrollment_dialog_view.h"
     36 #include "chrome/browser/chromeos/login/user.h"
     37 #include "chrome/browser/chromeos/login/user_manager.h"
     38 #include "chrome/browser/chromeos/mobile_config.h"
     39 #include "chrome/browser/chromeos/options/network_config_view.h"
     40 #include "chrome/browser/chromeos/options/network_connect.h"
     41 #include "chrome/browser/chromeos/settings/cros_settings.h"
     42 #include "chrome/browser/chromeos/sim_dialog_delegate.h"
     43 #include "chrome/browser/chromeos/ui_proxy_config_service.h"
     44 #include "chrome/browser/profiles/profile_manager.h"
     45 #include "chrome/browser/ui/browser.h"
     46 #include "chrome/browser/ui/browser_finder.h"
     47 #include "chrome/browser/ui/browser_window.h"
     48 #include "chrome/browser/ui/host_desktop.h"
     49 #include "chrome/browser/ui/singleton_tabs.h"
     50 #include "chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h"
     51 #include "chromeos/chromeos_switches.h"
     52 #include "chromeos/network/device_state.h"
     53 #include "chromeos/network/favorite_state.h"
     54 #include "chromeos/network/managed_network_configuration_handler.h"
     55 #include "chromeos/network/network_configuration_handler.h"
     56 #include "chromeos/network/network_connection_handler.h"
     57 #include "chromeos/network/network_device_handler.h"
     58 #include "chromeos/network/network_event_log.h"
     59 #include "chromeos/network/network_ip_config.h"
     60 #include "chromeos/network/network_profile.h"
     61 #include "chromeos/network/network_profile_handler.h"
     62 #include "chromeos/network/network_state.h"
     63 #include "chromeos/network/network_state_handler.h"
     64 #include "chromeos/network/network_ui_data.h"
     65 #include "chromeos/network/network_util.h"
     66 #include "chromeos/network/onc/onc_constants.h"
     67 #include "content/public/browser/notification_service.h"
     68 #include "content/public/browser/web_contents.h"
     69 #include "content/public/browser/web_contents_view.h"
     70 #include "content/public/browser/web_ui.h"
     71 #include "grit/ash_resources.h"
     72 #include "grit/ash_strings.h"
     73 #include "grit/chromium_strings.h"
     74 #include "grit/generated_resources.h"
     75 #include "grit/locale_settings.h"
     76 #include "grit/theme_resources.h"
     77 #include "third_party/cros_system_api/dbus/service_constants.h"
     78 #include "ui/base/l10n/l10n_util.h"
     79 #include "ui/base/layout.h"
     80 #include "ui/base/resource/resource_bundle.h"
     81 #include "ui/gfx/display.h"
     82 #include "ui/gfx/image/image_skia.h"
     83 #include "ui/gfx/screen.h"
     84 #include "ui/views/widget/widget.h"
     85 #include "ui/webui/web_ui_util.h"
     86 
     87 namespace chromeos {
     88 namespace options {
     89 
     90 namespace {
     91 
     92 // Keys for the network description dictionary passed to the web ui. Make sure
     93 // to keep the strings in sync with what the JavaScript side uses.
     94 const char kNetworkInfoKeyActivationState[] = "activationState";
     95 const char kNetworkInfoKeyConnectable[] = "connectable";
     96 const char kNetworkInfoKeyConnected[] = "connected";
     97 const char kNetworkInfoKeyConnecting[] = "connecting";
     98 const char kNetworkInfoKeyIconURL[] = "iconURL";
     99 const char kNetworkInfoKeyNetworkName[] = "networkName";
    100 const char kNetworkInfoKeyNetworkStatus[] = "networkStatus";
    101 const char kNetworkInfoKeyNetworkType[] = "networkType";
    102 const char kNetworkInfoKeyRemembered[] = "remembered";
    103 const char kNetworkInfoKeyServicePath[] = "servicePath";
    104 const char kNetworkInfoKeyPolicyManaged[] = "policyManaged";
    105 
    106 // These are keys for getting IP information from the web ui.
    107 const char kIpConfigAddress[] = "address";
    108 const char kIpConfigPrefixLength[] = "prefixLength";
    109 const char kIpConfigNetmask[] = "netmask";
    110 const char kIpConfigGateway[] = "gateway";
    111 const char kIpConfigNameServers[] = "nameServers";
    112 const char kIpConfigAutoConfig[] = "ipAutoConfig";
    113 const char kIpConfigWebProxyAutoDiscoveryUrl[] = "webProxyAutoDiscoveryUrl";
    114 
    115 // These are types of name server selections from the web ui.
    116 const char kNameServerTypeAutomatic[] = "automatic";
    117 const char kNameServerTypeGoogle[] = "google";
    118 const char kNameServerTypeUser[] = "user";
    119 
    120 // These are dictionary names used to send data to the web ui.
    121 const char kDictionaryIpConfig[] = "ipconfig";
    122 const char kDictionaryStaticIp[] = "staticIP";
    123 const char kDictionarySavedIp[] = "savedIP";
    124 
    125 // Google public name servers (DNS).
    126 const char kGoogleNameServers[] = "8.8.4.4,8.8.8.8";
    127 
    128 // Functions we call in JavaScript.
    129 const char kRefreshNetworkDataFunction[] =
    130     "options.network.NetworkList.refreshNetworkData";
    131 const char kSetDefaultNetworkIconsFunction[] =
    132     "options.network.NetworkList.setDefaultNetworkIcons";
    133 const char kShowDetailedInfoFunction[] =
    134     "options.internet.DetailsInternetPage.showDetailedInfo";
    135 const char kUpdateConnectionDataFunction[] =
    136     "options.internet.DetailsInternetPage.updateConnectionData";
    137 const char kUpdateCarrierFunction[] =
    138     "options.internet.DetailsInternetPage.updateCarrier";
    139 const char kUpdateLoggedInUserTypeFunction[] =
    140     "options.network.NetworkList.updateLoggedInUserType";
    141 const char kUpdateSecurityTabFunction[] =
    142     "options.internet.DetailsInternetPage.updateSecurityTab";
    143 
    144 // These are used to register message handlers with JavaScript.
    145 const char kBuyDataPlanMessage[] = "buyDataPlan";
    146 const char kChangePinMessage[] = "changePin";
    147 const char kDisableCellularMessage[] = "disableCellular";
    148 const char kDisableWifiMessage[] = "disableWifi";
    149 const char kDisableWimaxMessage[] = "disableWimax";
    150 const char kEnableCellularMessage[] = "enableCellular";
    151 const char kEnableWifiMessage[] = "enableWifi";
    152 const char kEnableWimaxMessage[] = "enableWimax";
    153 const char kNetworkCommandMessage[] = "networkCommand";
    154 const char kRefreshNetworksMessage[] = "refreshNetworks";
    155 const char kSetApnMessage[] = "setApn";
    156 const char kSetAutoConnectMessage[] = "setAutoConnect";
    157 const char kSetCarrierMessage[] = "setCarrier";
    158 const char kSetIPConfigMessage[] = "setIPConfig";
    159 const char kSetPreferNetworkMessage[] = "setPreferNetwork";
    160 const char kSetServerHostname[] = "setServerHostname";
    161 const char kSetSimCardLockMessage[] = "setSimCardLock";
    162 const char kShowMorePlanInfoMessage[] = "showMorePlanInfo";
    163 
    164 // These are strings used to communicate with JavaScript.
    165 const char kTagActivate[] = "activate";
    166 const char kTagActivated[] = "activated";
    167 const char kTagActivationState[] = "activationState";
    168 const char kTagAddConnection[] = "add";
    169 const char kTagApn[] = "apn";
    170 const char kTagAutoConnect[] = "autoConnect";
    171 const char kTagBssid[] = "bssid";
    172 const char kTagCarrierSelectFlag[] = "showCarrierSelect";
    173 const char kTagCarrierUrl[] = "carrierUrl";
    174 const char kTagCellular[] = "cellular";
    175 const char kTagCellularAvailable[] = "cellularAvailable";
    176 const char kTagCellularEnabled[] = "cellularEnabled";
    177 const char kTagCellularSupportsScan[] = "cellularSupportsScan";
    178 const char kTagConfigure[] = "configure";
    179 const char kTagConnect[] = "connect";
    180 const char kTagConnected[] = "connected";
    181 const char kTagConnecting[] = "connecting";
    182 const char kTagConnectionState[] = "connectionState";
    183 const char kTagControlledBy[] = "controlledBy";
    184 const char kTagDataRemaining[] = "dataRemaining";
    185 const char kTagDeviceConnected[] = "deviceConnected";
    186 const char kTagDisableConnectButton[] = "disableConnectButton";
    187 const char kTagDisconnect[] = "disconnect";
    188 const char kTagEncryption[] = "encryption";
    189 const char kTagErrorState[] = "errorState";
    190 const char kTagEsn[] = "esn";
    191 const char kTagFirmwareRevision[] = "firmwareRevision";
    192 const char kTagForget[] = "forget";
    193 const char kTagFrequency[] = "frequency";
    194 const char kTagGsm[] = "gsm";
    195 const char kTagHardwareAddress[] = "hardwareAddress";
    196 const char kTagHardwareRevision[] = "hardwareRevision";
    197 const char kTagIdentity[] = "identity";
    198 const char kTagIccid[] = "iccid";
    199 const char kTagImei[] = "imei";
    200 const char kTagImsi[] = "imsi";
    201 const char kTagLanguage[] = "language";
    202 const char kTagLastGoodApn[] = "lastGoodApn";
    203 const char kTagLocalizedName[] = "localizedName";
    204 const char kTagManufacturer[] = "manufacturer";
    205 const char kTagMdn[] = "mdn";
    206 const char kTagMeid[] = "meid";
    207 const char kTagMin[] = "min";
    208 const char kTagModelId[] = "modelId";
    209 const char kTagName[] = "name";
    210 const char kTagNameServersGoogle[] = "nameServersGoogle";
    211 const char kTagNameServerType[] = "nameServerType";
    212 const char kTagNetworkId[] = "networkId";
    213 const char kTagNetworkName[] = "networkName";
    214 const char kTagNetworkTechnology[] = "networkTechnology";
    215 const char kTagOperatorCode[] = "operatorCode";
    216 const char kTagOperatorName[] = "operatorName";
    217 const char kTagOptions[] = "options";
    218 const char kTagPassword[] = "password";
    219 const char kTagPolicy[] = "policy";
    220 const char kTagPreferred[] = "preferred";
    221 const char kTagPrlVersion[] = "prlVersion";
    222 const char kTagProviderType[] = "providerType";
    223 const char kTagProviderApnList[] = "providerApnList";
    224 const char kTagRecommended[] = "recommended";
    225 const char kTagRecommendedValue[] = "recommendedValue";
    226 const char kTagRemembered[] = "remembered";
    227 const char kTagRememberedList[] = "rememberedList";
    228 const char kTagRestrictedPool[] = "restrictedPool";
    229 const char kTagRoamingState[] = "roamingState";
    230 const char kTagServerHostname[] = "serverHostname";
    231 const char kTagCarriers[] = "carriers";
    232 const char kTagCurrentCarrierIndex[] = "currentCarrierIndex";
    233 const char kTagServiceName[] = "serviceName";
    234 const char kTagServicePath[] = "servicePath";
    235 const char kTagShared[] = "shared";
    236 const char kTagShowActivateButton[] = "showActivateButton";
    237 const char kTagShowBuyButton[] = "showBuyButton";
    238 const char kTagShowPreferred[] = "showPreferred";
    239 const char kTagShowProxy[] = "showProxy";
    240 const char kTagShowStaticIPConfig[] = "showStaticIPConfig";
    241 const char kTagShowViewAccountButton[] = "showViewAccountButton";
    242 const char kTagSimCardLockEnabled[] = "simCardLockEnabled";
    243 const char kTagSsid[] = "ssid";
    244 const char kTagStrength[] = "strength";
    245 const char kTagSupportUrl[] = "supportUrl";
    246 const char kTagTrue[] = "true";
    247 const char kTagType[] = "type";
    248 const char kTagUsername[] = "username";
    249 const char kTagValue[] = "value";
    250 const char kTagVpn[] = "vpn";
    251 const char kTagVpnList[] = "vpnList";
    252 const char kTagWarning[] = "warning";
    253 const char kTagWifi[] = "wifi";
    254 const char kTagWifiAvailable[] = "wifiAvailable";
    255 const char kTagWifiEnabled[] = "wifiEnabled";
    256 const char kTagWimaxAvailable[] = "wimaxAvailable";
    257 const char kTagWimaxEnabled[] = "wimaxEnabled";
    258 const char kTagWiredList[] = "wiredList";
    259 const char kTagWirelessList[] = "wirelessList";
    260 
    261 const int kPreferredPriority = 1;
    262 
    263 void ShillError(const std::string& function,
    264                 const std::string& error_name,
    265                 scoped_ptr<base::DictionaryValue> error_data) {
    266   // UpdateConnectionData may send requests for stale services; ignore
    267   // these errors.
    268   if (function == "UpdateConnectionData" &&
    269       error_name == network_handler::kDBusFailedError)
    270     return;
    271   NET_LOG_ERROR("Shill Error from InternetOptionsHandler: " + error_name,
    272                 function);
    273 }
    274 
    275 const NetworkState* GetNetworkState(const std::string& service_path) {
    276   return NetworkHandler::Get()->network_state_handler()->
    277       GetNetworkState(service_path);
    278 }
    279 
    280 void SetNetworkProperty(const std::string& service_path,
    281                         const std::string& property,
    282                         base::Value* value) {
    283   NET_LOG_EVENT("SetNetworkProperty: " + property, service_path);
    284   base::DictionaryValue properties;
    285   properties.SetWithoutPathExpansion(property, value);
    286   NetworkHandler::Get()->network_configuration_handler()->SetProperties(
    287       service_path, properties,
    288       base::Bind(&base::DoNothing),
    289       base::Bind(&ShillError, "SetNetworkProperty"));
    290 }
    291 
    292 std::string ActivationStateString(const std::string& activation_state) {
    293   int id;
    294   if (activation_state == flimflam::kActivationStateActivated)
    295     id = IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_ACTIVATED;
    296   else if (activation_state == flimflam::kActivationStateActivating)
    297     id = IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_ACTIVATING;
    298   else if (activation_state == flimflam::kActivationStateNotActivated)
    299     id = IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_NOT_ACTIVATED;
    300   else if (activation_state == flimflam::kActivationStatePartiallyActivated)
    301     id = IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_PARTIALLY_ACTIVATED;
    302   else
    303     id = IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_UNKNOWN;
    304   return l10n_util::GetStringUTF8(id);
    305 }
    306 
    307 std::string RoamingStateString(const std::string& roaming_state) {
    308   int id;
    309   if (roaming_state == flimflam::kRoamingStateHome)
    310     id = IDS_CHROMEOS_NETWORK_ROAMING_STATE_HOME;
    311   else if (roaming_state == flimflam::kRoamingStateRoaming)
    312     id = IDS_CHROMEOS_NETWORK_ROAMING_STATE_ROAMING;
    313   else
    314     id = IDS_CHROMEOS_NETWORK_ROAMING_STATE_UNKNOWN;
    315   return l10n_util::GetStringUTF8(id);
    316 }
    317 
    318 std::string ConnectionStateString(const std::string& state) {
    319   int id;
    320   if (state == flimflam::kUnknownString)
    321     id = IDS_CHROMEOS_NETWORK_STATE_UNKNOWN;
    322   else if (state == flimflam::kStateIdle)
    323     id = IDS_CHROMEOS_NETWORK_STATE_IDLE;
    324   else if (state == flimflam::kStateCarrier)
    325     id = IDS_CHROMEOS_NETWORK_STATE_CARRIER;
    326   else if (state == flimflam::kStateAssociation)
    327     id = IDS_CHROMEOS_NETWORK_STATE_ASSOCIATION;
    328   else if (state == flimflam::kStateConfiguration)
    329     id = IDS_CHROMEOS_NETWORK_STATE_CONFIGURATION;
    330   else if (state == flimflam::kStateReady)
    331     id = IDS_CHROMEOS_NETWORK_STATE_READY;
    332   else if (state == flimflam::kStateDisconnect)
    333     id = IDS_CHROMEOS_NETWORK_STATE_DISCONNECT;
    334   else if (state == flimflam::kStateFailure)
    335     id = IDS_CHROMEOS_NETWORK_STATE_FAILURE;
    336   else if (state == flimflam::kStateActivationFailure)
    337     id = IDS_CHROMEOS_NETWORK_STATE_ACTIVATION_FAILURE;
    338   else if (state == flimflam::kStatePortal)
    339     id = IDS_CHROMEOS_NETWORK_STATE_PORTAL;
    340   else if (state == flimflam::kStateOnline)
    341     id = IDS_CHROMEOS_NETWORK_STATE_ONLINE;
    342   else
    343     id = IDS_CHROMEOS_NETWORK_STATE_UNRECOGNIZED;
    344   return l10n_util::GetStringUTF8(id);
    345 }
    346 
    347 std::string LoggedInUserTypeToString(
    348     LoginState::LoggedInUserType type) {
    349   switch (type) {
    350     case LoginState::LOGGED_IN_USER_NONE:
    351       return "none";
    352     case LoginState::LOGGED_IN_USER_REGULAR:
    353       return "regular";
    354     case LoginState::LOGGED_IN_USER_OWNER:
    355       return "owner";
    356     case LoginState::LOGGED_IN_USER_GUEST:
    357       return "guest";
    358     case LoginState::LOGGED_IN_USER_RETAIL_MODE:
    359       return "retail-mode";
    360     case LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT:
    361       return "public-account";
    362     case LoginState::LOGGED_IN_USER_LOCALLY_MANAGED:
    363       return "locally-managed";
    364     case LoginState::LOGGED_IN_USER_KIOSK_APP:
    365       return "kiosk-app";
    366     default:
    367       return "";
    368   }
    369 }
    370 
    371 std::string EncryptionString(const std::string& security,
    372                              const std::string& eap_method) {
    373   if (security == flimflam::kSecurityNone)
    374     return "";
    375   if (security == flimflam::kSecurityWpa)
    376     return "WPA";
    377   if (security == flimflam::kSecurityWep)
    378     return "WEP";
    379   if (security == flimflam::kSecurityRsn)
    380     return "RSN";
    381   if (security == flimflam::kSecurityPsk)
    382     return "PSK";
    383   if (security == flimflam::kSecurity8021x) {
    384     std::string result = "8021X";
    385     if (eap_method == flimflam::kEapMethodPEAP)
    386       result += "PEAP";
    387     else if (eap_method == flimflam::kEapMethodTLS)
    388       result += "TLS";
    389     else if (eap_method == flimflam::kEapMethodTTLS)
    390       result += "TTLS";
    391     else if (eap_method == flimflam::kEapMethodLEAP)
    392       result += "LEAP";
    393     return result;
    394   }
    395   return "Unknown";
    396 }
    397 
    398 std::string ProviderTypeString(
    399     const std::string& provider_type,
    400     const base::DictionaryValue& provider_properties) {
    401   int id;
    402   if (provider_type == flimflam::kProviderL2tpIpsec) {
    403     std::string client_cert_id;
    404     provider_properties.GetStringWithoutPathExpansion(
    405         flimflam::kL2tpIpsecClientCertIdProperty, &client_cert_id);
    406     if (client_cert_id.empty())
    407       id = IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_L2TP_IPSEC_PSK;
    408     else
    409       id = IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_L2TP_IPSEC_USER_CERT;
    410   } else if (provider_type == flimflam::kProviderOpenVpn) {
    411     id = IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_OPEN_VPN;
    412   } else {
    413     id = IDS_CHROMEOS_NETWORK_ERROR_UNKNOWN;
    414   }
    415   return l10n_util::GetStringUTF8(id);
    416 }
    417 
    418 // A helper class for building network information dictionaries to be sent to
    419 // the webui code.
    420 class NetworkInfoDictionary {
    421  public:
    422   // Sets properties based on |network| and sets an appropriate icon based
    423   // on the network type and |icon_scale_factor|.
    424   NetworkInfoDictionary(const NetworkState* network,
    425                         ui::ScaleFactor icon_scale_factor);
    426   NetworkInfoDictionary(const FavoriteState* network,
    427                         ui::ScaleFactor icon_scale_factor);
    428 
    429   // Builds the DictionaryValue representation from the previously set
    430   // parameters. Ownership of the returned pointer is transferred to the caller.
    431   base::DictionaryValue* BuildDictionary();
    432 
    433  private:
    434   void SetIcon(const gfx::ImageSkia& icon,
    435                ui::ScaleFactor icon_scale_factor) {
    436     gfx::ImageSkiaRep image_rep = icon.GetRepresentation(icon_scale_factor);
    437     icon_url_ = icon.isNull() ? "" : webui::GetBitmapDataUrl(
    438         image_rep.sk_bitmap());
    439   }
    440 
    441   std::string service_path_;
    442   std::string icon_url_;
    443   std::string name_;
    444   bool connecting_;
    445   bool connected_;
    446   bool connectable_;
    447   std::string connection_type_;
    448   bool remembered_;
    449   bool shared_;
    450   std::string activation_state_;
    451   bool policy_managed_;
    452 
    453   DISALLOW_COPY_AND_ASSIGN(NetworkInfoDictionary);
    454 };
    455 
    456 NetworkInfoDictionary::NetworkInfoDictionary(const NetworkState* network,
    457                                              ui::ScaleFactor icon_scale_factor)
    458     : service_path_(network->path()),
    459       name_(network->name()),
    460       connecting_(network->IsConnectingState()),
    461       connected_(network->IsConnectedState()),
    462       connectable_(network->connectable()),
    463       connection_type_(network->type()),
    464       remembered_(false),
    465       shared_(false),
    466       activation_state_(network->activation_state()),
    467       policy_managed_(network->IsManaged()) {
    468   if (network->type() == flimflam::kTypeEthernet)
    469     name_ = l10n_util::GetStringUTF8(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET);
    470   gfx::ImageSkia icon = ash::network_icon::GetImageForNetwork(
    471       network, ash::network_icon::ICON_TYPE_LIST);
    472   SetIcon(icon, icon_scale_factor);
    473 }
    474 
    475 NetworkInfoDictionary::NetworkInfoDictionary(const FavoriteState* favorite,
    476                                              ui::ScaleFactor icon_scale_factor)
    477     : service_path_(favorite->path()),
    478       name_(favorite->name()),
    479       connecting_(false),
    480       connected_(false),
    481       connectable_(false),
    482       connection_type_(favorite->type()),
    483       remembered_(true),
    484       shared_(!favorite->IsPrivate()),
    485       policy_managed_(favorite->IsManaged()) {
    486   if (favorite->type() == flimflam::kTypeEthernet)
    487     name_ = l10n_util::GetStringUTF8(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET);
    488   gfx::ImageSkia icon = ash::network_icon::GetImageForDisconnectedNetwork(
    489       ash::network_icon::ICON_TYPE_LIST, favorite->type());
    490   SetIcon(icon, icon_scale_factor);
    491 }
    492 
    493 base::DictionaryValue* NetworkInfoDictionary::BuildDictionary() {
    494   std::string status;
    495   if (remembered_) {
    496     if (shared_)
    497       status = l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SHARED_NETWORK);
    498   } else {
    499     int id;
    500     if (connected_)
    501       id = IDS_STATUSBAR_NETWORK_DEVICE_CONNECTED;
    502     else if (connecting_)
    503       id = IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING;
    504     else if (!connectable_)
    505       id = IDS_STATUSBAR_NETWORK_DEVICE_NOT_CONFIGURED;
    506     else
    507       id = IDS_STATUSBAR_NETWORK_DEVICE_DISCONNECTED;
    508     std::string status = l10n_util::GetStringUTF8(id);
    509     if (connection_type_ == flimflam::kTypeCellular &&
    510         activation_state_ != flimflam::kActivationStateActivated) {
    511       status.append(" / ");
    512       status.append(ActivationStateString(activation_state_));
    513     }
    514   }
    515 
    516   scoped_ptr<base::DictionaryValue> network_info(new base::DictionaryValue());
    517   network_info->SetString(kNetworkInfoKeyActivationState, activation_state_);
    518   network_info->SetBoolean(kNetworkInfoKeyConnectable, connectable_);
    519   network_info->SetBoolean(kNetworkInfoKeyConnected, connected_);
    520   network_info->SetBoolean(kNetworkInfoKeyConnecting, connecting_);
    521   network_info->SetString(kNetworkInfoKeyIconURL, icon_url_);
    522   network_info->SetString(kNetworkInfoKeyNetworkName, name_);
    523   network_info->SetString(kNetworkInfoKeyNetworkStatus, status);
    524   network_info->SetString(kNetworkInfoKeyNetworkType, connection_type_);
    525   network_info->SetBoolean(kNetworkInfoKeyRemembered, remembered_);
    526   network_info->SetString(kNetworkInfoKeyServicePath, service_path_);
    527   network_info->SetBoolean(kNetworkInfoKeyPolicyManaged, policy_managed_);
    528   return network_info.release();
    529 }
    530 
    531 // Pulls IP information out of a shill service properties dictionary. If
    532 // |static_ip| is true, then it fetches "StaticIP.*" properties. If not, then it
    533 // fetches "SavedIP.*" properties. Caller must take ownership of returned
    534 // dictionary.  If non-NULL, |ip_parameters_set| returns a count of the number
    535 // of IP routing parameters that get set.
    536 base::DictionaryValue* BuildIPInfoDictionary(
    537     const base::DictionaryValue& shill_properties,
    538     bool static_ip,
    539     int* routing_parameters_set) {
    540   std::string address_key;
    541   std::string prefix_len_key;
    542   std::string gateway_key;
    543   std::string name_servers_key;
    544   if (static_ip) {
    545     address_key = shill::kStaticIPAddressProperty;
    546     prefix_len_key = shill::kStaticIPPrefixlenProperty;
    547     gateway_key = shill::kStaticIPGatewayProperty;
    548     name_servers_key = shill::kStaticIPNameServersProperty;
    549   } else {
    550     address_key = shill::kSavedIPAddressProperty;
    551     prefix_len_key = shill::kSavedIPPrefixlenProperty;
    552     gateway_key = shill::kSavedIPGatewayProperty;
    553     name_servers_key = shill::kSavedIPNameServersProperty;
    554   }
    555 
    556   scoped_ptr<base::DictionaryValue> ip_info_dict(new base::DictionaryValue);
    557   std::string address;
    558   int routing_parameters = 0;
    559   if (shill_properties.GetStringWithoutPathExpansion(address_key, &address)) {
    560     ip_info_dict->SetString(kIpConfigAddress, address);
    561     VLOG(2) << "Found " << address_key << ": " << address;
    562     routing_parameters++;
    563   }
    564   int prefix_len = -1;
    565   if (shill_properties.GetIntegerWithoutPathExpansion(
    566       prefix_len_key, &prefix_len)) {
    567     ip_info_dict->SetInteger(kIpConfigPrefixLength, prefix_len);
    568     std::string netmask = network_util::PrefixLengthToNetmask(prefix_len);
    569     ip_info_dict->SetString(kIpConfigNetmask, netmask);
    570     VLOG(2) << "Found " << prefix_len_key << ": "
    571             <<  prefix_len << " (" << netmask << ")";
    572     routing_parameters++;
    573   }
    574   std::string gateway;
    575   if (shill_properties.GetStringWithoutPathExpansion(gateway_key, &gateway)) {
    576     ip_info_dict->SetString(kIpConfigGateway, gateway);
    577     VLOG(2) << "Found " << gateway_key << ": " << gateway;
    578     routing_parameters++;
    579   }
    580   if (routing_parameters_set)
    581     *routing_parameters_set = routing_parameters;
    582 
    583   std::string name_servers;
    584   if (shill_properties.GetStringWithoutPathExpansion(
    585       name_servers_key, &name_servers)) {
    586     ip_info_dict->SetString(kIpConfigNameServers, name_servers);
    587     VLOG(2) << "Found " << name_servers_key << ": " << name_servers;
    588   }
    589 
    590   return ip_info_dict.release();
    591 }
    592 
    593 static bool CanForgetNetworkType(const std::string& type) {
    594   return type == flimflam::kTypeWifi ||
    595          type == flimflam::kTypeWimax ||
    596          type == flimflam::kTypeVPN;
    597 }
    598 
    599 static bool CanAddNetworkType(const std::string& type) {
    600   return type == flimflam::kTypeWifi ||
    601          type == flimflam::kTypeVPN ||
    602          type == flimflam::kTypeCellular;
    603 }
    604 
    605 // Decorate pref value as CoreOptionsHandler::CreateValueForPref() does and
    606 // store it under |key| in |settings|. Takes ownership of |value|.
    607 void SetValueDictionary(base::DictionaryValue* settings,
    608                         const char* key,
    609                         base::Value* value,
    610                         const NetworkPropertyUIData& ui_data) {
    611   base::DictionaryValue* dict = new base::DictionaryValue();
    612   // DictionaryValue::Set() takes ownership of |value|.
    613   dict->Set(kTagValue, value);
    614   const base::Value* recommended_value = ui_data.default_value();
    615   if (ui_data.IsManaged())
    616     dict->SetString(kTagControlledBy, kTagPolicy);
    617   else if (recommended_value && recommended_value->Equals(value))
    618     dict->SetString(kTagControlledBy, kTagRecommended);
    619 
    620   if (recommended_value)
    621     dict->Set(kTagRecommendedValue, recommended_value->DeepCopy());
    622   settings->Set(key, dict);
    623 }
    624 
    625 std::string CopyStringFromDictionary(const base::DictionaryValue& source,
    626                                      const std::string& src_key,
    627                                      const std::string& dest_key,
    628                                      base::DictionaryValue* dest) {
    629   std::string string_value;
    630   if (source.GetStringWithoutPathExpansion(src_key, &string_value))
    631     dest->SetStringWithoutPathExpansion(dest_key, string_value);
    632   return string_value;
    633 }
    634 
    635 void CopyIntegerFromDictionary(const base::DictionaryValue& source,
    636                                const std::string& src_key,
    637                                const std::string& dest_key,
    638                                bool as_string,
    639                                base::DictionaryValue* dest) {
    640   int int_value;
    641   if (!source.GetIntegerWithoutPathExpansion(src_key, &int_value))
    642     return;
    643   if (as_string) {
    644     std::string str = base::StringPrintf("%d", int_value);
    645     dest->SetStringWithoutPathExpansion(dest_key, str);
    646   } else {
    647     dest->SetIntegerWithoutPathExpansion(dest_key, int_value);
    648   }
    649 }
    650 
    651 // Fills |dictionary| with the configuration details of |vpn|. |onc| is required
    652 // for augmenting the policy-managed information.
    653 void PopulateVPNDetails(const NetworkState* vpn,
    654                         const base::DictionaryValue& shill_properties,
    655                         base::DictionaryValue* dictionary) {
    656   // Name and Remembered are set in PopulateConnectionDetails().
    657   // Provider properties are stored in the "Provider" dictionary.
    658   const base::DictionaryValue* provider_properties = NULL;
    659   if (!shill_properties.GetDictionaryWithoutPathExpansion(
    660           flimflam::kProviderProperty, &provider_properties)) {
    661     LOG(ERROR) << "No provider properties for VPN: " << vpn->path();
    662     return;
    663   }
    664   std::string provider_type;
    665   provider_properties->GetStringWithoutPathExpansion(
    666       flimflam::kTypeProperty, &provider_type);
    667   dictionary->SetString(kTagProviderType,
    668                         ProviderTypeString(provider_type,
    669                                            *provider_properties));
    670 
    671   std::string username;
    672   if (provider_type == flimflam::kProviderOpenVpn) {
    673     provider_properties->GetStringWithoutPathExpansion(
    674         flimflam::kOpenVPNUserProperty, &username);
    675   } else {
    676     provider_properties->GetStringWithoutPathExpansion(
    677         flimflam::kL2tpIpsecUserProperty, &username);
    678   }
    679   dictionary->SetString(kTagUsername, username);
    680 
    681   onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
    682   const base::DictionaryValue* onc =
    683       network_connect::FindPolicyForActiveUser(vpn, &onc_source);
    684 
    685   NetworkPropertyUIData hostname_ui_data;
    686   hostname_ui_data.ParseOncProperty(
    687       onc_source,
    688       onc,
    689       base::StringPrintf("%s.%s", onc::network_config::kVPN, onc::vpn::kHost));
    690   std::string provider_host;
    691   provider_properties->GetStringWithoutPathExpansion(
    692       flimflam::kHostProperty, &provider_host);
    693   SetValueDictionary(dictionary, kTagServerHostname,
    694                      new base::StringValue(provider_host),
    695                      hostname_ui_data);
    696 }
    697 
    698 // Given a list of supported carrier's by the device, return the index of
    699 // the carrier the device is currently using.
    700 int FindCurrentCarrierIndex(const base::ListValue* carriers,
    701                             const DeviceState* device) {
    702   DCHECK(carriers);
    703   DCHECK(device);
    704   bool gsm = (device->technology_family() == flimflam::kTechnologyFamilyGsm);
    705   int index = 0;
    706   for (base::ListValue::const_iterator it = carriers->begin();
    707        it != carriers->end(); ++it, ++index) {
    708     std::string value;
    709     if (!(*it)->GetAsString(&value))
    710       continue;
    711     // For GSM devices the device name will be empty, so simply select
    712     // the Generic UMTS carrier option if present.
    713     if (gsm && (value == shill::kCarrierGenericUMTS))
    714       return index;
    715     // For other carriers, the service name will match the carrier name.
    716     if (value == device->carrier())
    717       return index;
    718   }
    719   return -1;
    720 }
    721 
    722 void PopulateWifiDetails(const NetworkState* wifi,
    723                          const base::DictionaryValue& shill_properties,
    724                          base::DictionaryValue* dictionary);
    725 // TODO(stevenjb): Move implementation here.
    726 
    727 void PopulateWimaxDetails(const NetworkState* wimax,
    728                           const base::DictionaryValue& shill_properties,
    729                           base::DictionaryValue* dictionary);
    730 // TODO(stevenjb): Move implementation here.
    731 
    732 void CreateDictionaryFromCellularApn(const base::DictionaryValue* apn,
    733                                      base::DictionaryValue* dictionary);
    734 // TODO(stevenjb): Move implementation here.
    735 
    736 void PopulateCellularDetails(const NetworkState* cellular,
    737                              const base::DictionaryValue& shill_properties,
    738                              base::DictionaryValue* dictionary);
    739 // TODO(stevenjb): Move implementation here.
    740 
    741 void PopulateConnectionDetails(const NetworkState* network,
    742                                const base::DictionaryValue& shill_properties,
    743                                base::DictionaryValue* dictionary);
    744 // TODO(stevenjb): Move implementation here.
    745 
    746 // Helper methods for SetIPConfigProperties
    747 bool AppendPropertyKeyIfPresent(const std::string& key,
    748                                 const base::DictionaryValue& old_properties,
    749                                 std::vector<std::string>* property_keys) {
    750   if (old_properties.HasKey(key)) {
    751     property_keys->push_back(key);
    752     return true;
    753   }
    754   return false;
    755 }
    756 
    757 bool AddStringPropertyIfChanged(const std::string& key,
    758                                 const std::string& new_value,
    759                                 const base::DictionaryValue& old_properties,
    760                                 base::DictionaryValue* new_properties) {
    761   std::string old_value;
    762   if (!old_properties.GetStringWithoutPathExpansion(key, &old_value) ||
    763       new_value != old_value) {
    764     new_properties->SetStringWithoutPathExpansion(key, new_value);
    765     return true;
    766   }
    767   return false;
    768 }
    769 
    770 bool AddIntegerPropertyIfChanged(const std::string& key,
    771                                  int new_value,
    772                                  const base::DictionaryValue& old_properties,
    773                                  base::DictionaryValue* new_properties) {
    774   int old_value;
    775   if (!old_properties.GetIntegerWithoutPathExpansion(key, &old_value) ||
    776       new_value != old_value) {
    777     new_properties->SetIntegerWithoutPathExpansion(key, new_value);
    778     return true;
    779   }
    780   return false;
    781 }
    782 
    783 void RequestReconnect(const std::string& service_path,
    784                       gfx::NativeWindow owning_window) {
    785   NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork(
    786       service_path,
    787       base::Bind(&ash::network_connect::ConnectToNetwork,
    788                  service_path, owning_window),
    789       base::Bind(&ShillError, "RequestReconnect"));
    790 }
    791 
    792 }  // namespace
    793 
    794 InternetOptionsHandler::InternetOptionsHandler()
    795     : weak_factory_(this) {
    796   registrar_.Add(this, chrome::NOTIFICATION_REQUIRE_PIN_SETTING_CHANGE_ENDED,
    797                  content::NotificationService::AllSources());
    798   registrar_.Add(this, chrome::NOTIFICATION_ENTER_PIN_ENDED,
    799                  content::NotificationService::AllSources());
    800   NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE);
    801   LoginState::Get()->AddObserver(this);
    802 }
    803 
    804 InternetOptionsHandler::~InternetOptionsHandler() {
    805   if (NetworkHandler::IsInitialized()) {
    806     NetworkHandler::Get()->network_state_handler()->RemoveObserver(
    807         this, FROM_HERE);
    808   }
    809   if (LoginState::Get()->IsInitialized())
    810     LoginState::Get()->RemoveObserver(this);
    811 }
    812 
    813 void InternetOptionsHandler::GetLocalizedValues(
    814     base::DictionaryValue* localized_strings) {
    815   DCHECK(localized_strings);
    816 
    817   static OptionsStringResource resources[] = {
    818 
    819     // Main settings page.
    820 
    821     { "ethernetTitle", IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET },
    822     { "wifiTitle", IDS_OPTIONS_SETTINGS_SECTION_TITLE_WIFI_NETWORK },
    823     { "wimaxTitle", IDS_OPTIONS_SETTINGS_SECTION_TITLE_WIMAX_NETWORK },
    824     { "cellularTitle", IDS_OPTIONS_SETTINGS_SECTION_TITLE_CELLULAR_NETWORK },
    825     { "vpnTitle", IDS_OPTIONS_SETTINGS_SECTION_TITLE_PRIVATE_NETWORK },
    826     { "networkNotConnected", IDS_OPTIONS_SETTINGS_NETWORK_NOT_CONNECTED },
    827     { "networkConnected", IDS_CHROMEOS_NETWORK_STATE_READY },
    828     { "joinOtherNetwork", IDS_OPTIONS_SETTINGS_NETWORK_OTHER },
    829     { "networkOffline", IDS_OPTIONS_SETTINGS_NETWORK_OFFLINE },
    830     { "networkDisabled", IDS_OPTIONS_SETTINGS_NETWORK_DISABLED },
    831     { "networkOnline", IDS_OPTIONS_SETTINGS_NETWORK_ONLINE },
    832     { "networkOptions", IDS_OPTIONS_SETTINGS_NETWORK_OPTIONS },
    833     { "turnOffWifi", IDS_OPTIONS_SETTINGS_NETWORK_DISABLE_WIFI },
    834     { "turnOffWimax", IDS_OPTIONS_SETTINGS_NETWORK_DISABLE_WIMAX },
    835     { "turnOffCellular", IDS_OPTIONS_SETTINGS_NETWORK_DISABLE_CELLULAR },
    836     { "disconnectNetwork", IDS_OPTIONS_SETTINGS_DISCONNECT },
    837     { "preferredNetworks", IDS_OPTIONS_SETTINGS_PREFERRED_NETWORKS_LABEL },
    838     { "preferredNetworksPage", IDS_OPTIONS_SETTINGS_PREFERRED_NETWORKS_TITLE },
    839     { "useSharedProxies", IDS_OPTIONS_SETTINGS_USE_SHARED_PROXIES },
    840     { "addConnectionTitle",
    841       IDS_OPTIONS_SETTINGS_SECTION_TITLE_ADD_CONNECTION },
    842     { "addConnectionWifi", IDS_OPTIONS_SETTINGS_ADD_CONNECTION_WIFI },
    843     { "addConnectionVPN", IDS_STATUSBAR_NETWORK_ADD_VPN },
    844     { "otherCellularNetworks", IDS_OPTIONS_SETTINGS_OTHER_CELLULAR_NETWORKS },
    845     { "enableDataRoaming", IDS_OPTIONS_SETTINGS_ENABLE_DATA_ROAMING },
    846     { "disableDataRoaming", IDS_OPTIONS_SETTINGS_DISABLE_DATA_ROAMING },
    847     { "dataRoamingDisableToggleTooltip",
    848       IDS_OPTIONS_SETTINGS_TOGGLE_DATA_ROAMING_RESTRICTION },
    849     { "activateNetwork", IDS_STATUSBAR_NETWORK_DEVICE_ACTIVATE },
    850 
    851     // Internet details dialog.
    852 
    853     { "changeProxyButton",
    854       IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CHANGE_PROXY_BUTTON },
    855     { "managedNetwork", IDS_OPTIONS_SETTINGS_MANAGED_NETWORK },
    856     { "wifiNetworkTabLabel", IDS_OPTIONS_SETTINGS_INTERNET_TAB_CONNECTION },
    857     { "vpnTabLabel", IDS_OPTIONS_SETTINGS_INTERNET_TAB_VPN },
    858     { "cellularConnTabLabel", IDS_OPTIONS_SETTINGS_INTERNET_TAB_CONNECTION },
    859     { "cellularDeviceTabLabel", IDS_OPTIONS_SETTINGS_INTERNET_TAB_DEVICE },
    860     { "networkTabLabel", IDS_OPTIONS_SETTINGS_INTERNET_TAB_NETWORK },
    861     { "securityTabLabel", IDS_OPTIONS_SETTINGS_INTERNET_TAB_SECURITY },
    862     { "proxyTabLabel", IDS_OPTIONS_SETTINGS_INTERNET_TAB_PROXY },
    863     { "connectionState", IDS_OPTIONS_SETTINGS_INTERNET_CONNECTION_STATE },
    864     { "inetAddress", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_ADDRESS },
    865     { "inetNetmask", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SUBNETMASK },
    866     { "inetGateway", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_GATEWAY },
    867     { "inetNameServers", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_DNSSERVER },
    868     { "ipAutomaticConfiguration",
    869         IDS_OPTIONS_SETTINGS_INTERNET_IP_AUTOMATIC_CONFIGURATION },
    870     { "automaticNameServers",
    871         IDS_OPTIONS_SETTINGS_INTERNET_AUTOMATIC_NAME_SERVERS },
    872     { "userNameServer1", IDS_OPTIONS_SETTINGS_INTERNET_USER_NAME_SERVER_1 },
    873     { "userNameServer2", IDS_OPTIONS_SETTINGS_INTERNET_USER_NAME_SERVER_2 },
    874     { "userNameServer3", IDS_OPTIONS_SETTINGS_INTERNET_USER_NAME_SERVER_3 },
    875     { "userNameServer4", IDS_OPTIONS_SETTINGS_INTERNET_USER_NAME_SERVER_4 },
    876     { "googleNameServers", IDS_OPTIONS_SETTINGS_INTERNET_GOOGLE_NAME_SERVERS },
    877     { "userNameServers", IDS_OPTIONS_SETTINGS_INTERNET_USER_NAME_SERVERS },
    878     { "hardwareAddress",
    879       IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_HARDWARE_ADDRESS },
    880     { "detailsInternetDismiss", IDS_CLOSE },
    881     { "activateButton", IDS_OPTIONS_SETTINGS_ACTIVATE },
    882     { "buyplanButton", IDS_OPTIONS_SETTINGS_BUY_PLAN },
    883     { "connectButton", IDS_OPTIONS_SETTINGS_CONNECT },
    884     { "configureButton", IDS_OPTIONS_SETTINGS_CONFIGURE },
    885     { "disconnectButton", IDS_OPTIONS_SETTINGS_DISCONNECT },
    886     { "viewAccountButton", IDS_STATUSBAR_NETWORK_VIEW_ACCOUNT },
    887     { "wimaxConnTabLabel", IDS_OPTIONS_SETTINGS_INTERNET_TAB_WIMAX },
    888 
    889     // Wifi Tab.
    890 
    891     { "inetSsid", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_ID },
    892     { "inetBssid", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_BSSID },
    893     { "inetEncryption",
    894       IDS_OPTIONS_SETTIGNS_INTERNET_OPTIONS_NETWORK_ENCRYPTION },
    895     { "inetFrequency",
    896       IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_FREQUENCY },
    897     { "inetFrequencyFormat",
    898       IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_FREQUENCY_MHZ },
    899     { "inetSignalStrength",
    900       IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_STRENGTH },
    901     { "inetSignalStrengthFormat",
    902       IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_STRENGTH_PERCENTAGE },
    903     { "inetPassProtected",
    904       IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NET_PROTECTED },
    905     { "inetNetworkShared",
    906       IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_SHARED },
    907     { "inetPreferredNetwork",
    908       IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PREFER_NETWORK },
    909     { "inetAutoConnectNetwork",
    910       IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_AUTO_CONNECT },
    911     { "inetLogin", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_LOGIN },
    912     { "inetShowPass", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SHOWPASSWORD },
    913     { "inetPassPrompt", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PASSWORD },
    914     { "inetSsidPrompt", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SSID },
    915     { "inetStatus", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_STATUS_TITLE },
    916     { "inetConnect", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CONNECT_TITLE },
    917 
    918     // VPN Tab.
    919 
    920     { "inetServiceName",
    921       IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_SERVICE_NAME },
    922     { "inetServerHostname",
    923       IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_SERVER_HOSTNAME },
    924     { "inetProviderType",
    925       IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_PROVIDER_TYPE },
    926     { "inetUsername", IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_USERNAME },
    927 
    928     // Cellular Tab.
    929 
    930     { "serviceName", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_SERVICE_NAME },
    931     { "networkTechnology",
    932       IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_NETWORK_TECHNOLOGY },
    933     { "operatorName", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_OPERATOR },
    934     { "operatorCode", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_OPERATOR_CODE },
    935     { "activationState",
    936       IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_ACTIVATION_STATE },
    937     { "roamingState", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_ROAMING_STATE },
    938     { "restrictedPool",
    939       IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_RESTRICTED_POOL },
    940     { "errorState", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_ERROR_STATE },
    941     { "manufacturer", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_MANUFACTURER },
    942     { "modelId", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_MODEL_ID },
    943     { "firmwareRevision",
    944       IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_FIRMWARE_REVISION },
    945     { "hardwareRevision",
    946       IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_HARDWARE_REVISION },
    947     { "prlVersion", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_PRL_VERSION },
    948     { "cellularApnLabel", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_APN },
    949     { "cellularApnOther", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_APN_OTHER },
    950     { "cellularApnUsername",
    951       IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_APN_USERNAME },
    952     { "cellularApnPassword",
    953       IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_APN_PASSWORD },
    954     { "cellularApnUseDefault",
    955       IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_APN_CLEAR },
    956     { "cellularApnSet", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_APN_SET },
    957     { "cellularApnCancel", IDS_CANCEL },
    958 
    959     // Security Tab.
    960 
    961     { "accessSecurityTabLink",
    962       IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_ACCESS_SECURITY_TAB },
    963     { "lockSimCard", IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_LOCK_SIM_CARD },
    964     { "changePinButton",
    965       IDS_OPTIONS_SETTINGS_INTERNET_CELLULAR_CHANGE_PIN_BUTTON },
    966 
    967     // Proxy Tab.
    968     { "webProxyAutoDiscoveryUrl", IDS_PROXY_WEB_PROXY_AUTO_DISCOVERY },
    969   };
    970 
    971   RegisterStrings(localized_strings, resources, arraysize(resources));
    972 
    973   std::string owner;
    974   chromeos::CrosSettings::Get()->GetString(chromeos::kDeviceOwner, &owner);
    975   localized_strings->SetString("ownerUserId", UTF8ToUTF16(owner));
    976 
    977   base::DictionaryValue* network_dictionary = new base::DictionaryValue;
    978   FillNetworkInfo(network_dictionary);
    979   localized_strings->Set("networkData", network_dictionary);
    980 }
    981 
    982 void InternetOptionsHandler::InitializePage() {
    983   base::DictionaryValue dictionary;
    984   dictionary.SetString(kTagCellular,
    985       GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_BARS_DARK));
    986   dictionary.SetString(kTagWifi,
    987       GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_ARCS_DARK));
    988   dictionary.SetString(kTagVpn,
    989       GetIconDataUrl(IDR_AURA_UBER_TRAY_NETWORK_VPN));
    990   web_ui()->CallJavascriptFunction(kSetDefaultNetworkIconsFunction,
    991                                    dictionary);
    992   NetworkHandler::Get()->network_state_handler()->RequestScan();
    993   RefreshNetworkData();
    994   UpdateLoggedInUserType();
    995 }
    996 
    997 void InternetOptionsHandler::RegisterMessages() {
    998   // Setup handlers specific to this panel.
    999   web_ui()->RegisterMessageCallback(kNetworkCommandMessage,
   1000       base::Bind(&InternetOptionsHandler::NetworkCommandCallback,
   1001                  base::Unretained(this)));
   1002   web_ui()->RegisterMessageCallback(kRefreshNetworksMessage,
   1003       base::Bind(&InternetOptionsHandler::RefreshNetworksCallback,
   1004                  base::Unretained(this)));
   1005   web_ui()->RegisterMessageCallback(kSetPreferNetworkMessage,
   1006       base::Bind(&InternetOptionsHandler::SetPreferNetworkCallback,
   1007                  base::Unretained(this)));
   1008   web_ui()->RegisterMessageCallback(kSetAutoConnectMessage,
   1009       base::Bind(&InternetOptionsHandler::SetAutoConnectCallback,
   1010                  base::Unretained(this)));
   1011   web_ui()->RegisterMessageCallback(kSetIPConfigMessage,
   1012       base::Bind(&InternetOptionsHandler::SetIPConfigCallback,
   1013                  base::Unretained(this)));
   1014   web_ui()->RegisterMessageCallback(kEnableWifiMessage,
   1015       base::Bind(&InternetOptionsHandler::EnableWifiCallback,
   1016                  base::Unretained(this)));
   1017   web_ui()->RegisterMessageCallback(kDisableWifiMessage,
   1018       base::Bind(&InternetOptionsHandler::DisableWifiCallback,
   1019                  base::Unretained(this)));
   1020   web_ui()->RegisterMessageCallback(kEnableCellularMessage,
   1021       base::Bind(&InternetOptionsHandler::EnableCellularCallback,
   1022                  base::Unretained(this)));
   1023   web_ui()->RegisterMessageCallback(kDisableCellularMessage,
   1024       base::Bind(&InternetOptionsHandler::DisableCellularCallback,
   1025                  base::Unretained(this)));
   1026   web_ui()->RegisterMessageCallback(kEnableWimaxMessage,
   1027       base::Bind(&InternetOptionsHandler::EnableWimaxCallback,
   1028                  base::Unretained(this)));
   1029   web_ui()->RegisterMessageCallback(kDisableWimaxMessage,
   1030       base::Bind(&InternetOptionsHandler::DisableWimaxCallback,
   1031                  base::Unretained(this)));
   1032   web_ui()->RegisterMessageCallback(kBuyDataPlanMessage,
   1033       base::Bind(&InternetOptionsHandler::BuyDataPlanCallback,
   1034                  base::Unretained(this)));
   1035   web_ui()->RegisterMessageCallback(kShowMorePlanInfoMessage,
   1036       base::Bind(&InternetOptionsHandler::ShowMorePlanInfoCallback,
   1037                  base::Unretained(this)));
   1038   web_ui()->RegisterMessageCallback(kSetApnMessage,
   1039       base::Bind(&InternetOptionsHandler::SetApnCallback,
   1040                  base::Unretained(this)));
   1041   web_ui()->RegisterMessageCallback(kSetCarrierMessage,
   1042       base::Bind(&InternetOptionsHandler::SetCarrierCallback,
   1043                  base::Unretained(this)));
   1044   web_ui()->RegisterMessageCallback(kSetSimCardLockMessage,
   1045       base::Bind(&InternetOptionsHandler::SetSimCardLockCallback,
   1046                  base::Unretained(this)));
   1047   web_ui()->RegisterMessageCallback(kChangePinMessage,
   1048       base::Bind(&InternetOptionsHandler::ChangePinCallback,
   1049                  base::Unretained(this)));
   1050   web_ui()->RegisterMessageCallback(kSetServerHostname,
   1051       base::Bind(&InternetOptionsHandler::SetServerHostnameCallback,
   1052                  base::Unretained(this)));
   1053 }
   1054 
   1055 void InternetOptionsHandler::EnableWifiCallback(const base::ListValue* args) {
   1056   NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
   1057       flimflam::kTypeWifi, true,
   1058       base::Bind(&ShillError, "EnableWifiCallback"));
   1059 }
   1060 
   1061 void InternetOptionsHandler::DisableWifiCallback(const base::ListValue* args) {
   1062   NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
   1063       flimflam::kTypeWifi, false,
   1064       base::Bind(&ShillError, "DisableWifiCallback"));
   1065 }
   1066 
   1067 void InternetOptionsHandler::EnableCellularCallback(
   1068     const base::ListValue* args) {
   1069   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
   1070   const DeviceState* device =
   1071       handler->GetDeviceStateByType(flimflam::kTypeCellular);
   1072   if (!device) {
   1073     LOG(ERROR) << "Mobile device not found.";
   1074     return;
   1075   }
   1076   if (!device->sim_lock_type().empty()) {
   1077     SimDialogDelegate::ShowDialog(GetNativeWindow(),
   1078                                   SimDialogDelegate::SIM_DIALOG_UNLOCK);
   1079     return;
   1080   }
   1081   if (!handler->IsTechnologyEnabled(flimflam::kTypeCellular)) {
   1082     handler->SetTechnologyEnabled(
   1083         flimflam::kTypeCellular, true,
   1084         base::Bind(&ShillError, "EnableCellularCallback"));
   1085     return;
   1086   }
   1087   if (device->IsSimAbsent()) {
   1088     MobileConfig* config = MobileConfig::GetInstance();
   1089     if (config->IsReady()) {
   1090       const MobileConfig::LocaleConfig* locale_config =
   1091           config->GetLocaleConfig();
   1092       if (locale_config) {
   1093         std::string setup_url = locale_config->setup_url();
   1094         if (!setup_url.empty()) {
   1095           chrome::ShowSingletonTab(GetAppropriateBrowser(), GURL(setup_url));
   1096           return;
   1097         }
   1098       }
   1099     }
   1100     // TODO(nkostylev): Show generic error message. http://crosbug.com/15444
   1101   }
   1102   LOG(ERROR) << "EnableCellularCallback called for enabled mobile device";
   1103 }
   1104 
   1105 void InternetOptionsHandler::DisableCellularCallback(
   1106     const base::ListValue* args) {
   1107   NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
   1108       NetworkStateHandler::kMatchTypeMobile, false,
   1109       base::Bind(&ShillError, "DisableCellularCallback"));
   1110 }
   1111 
   1112 void InternetOptionsHandler::EnableWimaxCallback(const base::ListValue* args) {
   1113   NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
   1114       flimflam::kTypeWimax, true,
   1115       base::Bind(&ShillError, "EnableWimaxCallback"));
   1116 }
   1117 
   1118 void InternetOptionsHandler::DisableWimaxCallback(const base::ListValue* args) {
   1119   NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
   1120       flimflam::kTypeWimax, false,
   1121       base::Bind(&ShillError, "DisableWimaxCallback"));
   1122 }
   1123 
   1124 void InternetOptionsHandler::ShowMorePlanInfoCallback(
   1125     const base::ListValue* args) {
   1126   if (!web_ui())
   1127     return;
   1128   std::string service_path;
   1129   if (args->GetSize() != 1 || !args->GetString(0, &service_path)) {
   1130     NOTREACHED();
   1131     return;
   1132   }
   1133   network_connect::ShowMobileSetup(service_path);
   1134 }
   1135 
   1136 void InternetOptionsHandler::BuyDataPlanCallback(const base::ListValue* args) {
   1137   if (!web_ui())
   1138     return;
   1139   std::string service_path;
   1140   if (args->GetSize() != 1 || !args->GetString(0, &service_path)) {
   1141     NOTREACHED();
   1142     return;
   1143   }
   1144   network_connect::ShowMobileSetup(service_path);
   1145 }
   1146 
   1147 void InternetOptionsHandler::SetApnCallback(const base::ListValue* args) {
   1148   std::string service_path;
   1149   if (!args->GetString(0, &service_path)) {
   1150     NOTREACHED();
   1151     return;
   1152   }
   1153   NetworkHandler::Get()->network_configuration_handler()->GetProperties(
   1154       service_path,
   1155       base::Bind(&InternetOptionsHandler::SetApnProperties,
   1156                  weak_factory_.GetWeakPtr(), base::Owned(args->DeepCopy())),
   1157       base::Bind(&ShillError, "SetApnCallback"));
   1158 }
   1159 
   1160 void InternetOptionsHandler::SetApnProperties(
   1161     const base::ListValue* args,
   1162     const std::string& service_path,
   1163     const base::DictionaryValue& shill_properties) {
   1164   std::string apn, username, password;
   1165   if (!args->GetString(1, &apn) ||
   1166       !args->GetString(2, &username) ||
   1167       !args->GetString(3, &password)) {
   1168     NOTREACHED();
   1169     return;
   1170   }
   1171   NET_LOG_EVENT("SetApnCallback", service_path);
   1172 
   1173   if (apn.empty()) {
   1174     std::vector<std::string> properties_to_clear;
   1175     properties_to_clear.push_back(flimflam::kCellularApnProperty);
   1176     NetworkHandler::Get()->network_configuration_handler()->ClearProperties(
   1177       service_path, properties_to_clear,
   1178       base::Bind(&base::DoNothing),
   1179       base::Bind(&ShillError, "ClearCellularApnProperties"));
   1180     return;
   1181   }
   1182 
   1183   const base::DictionaryValue* shill_apn_dict = NULL;
   1184   std::string network_id;
   1185   if (shill_properties.GetDictionaryWithoutPathExpansion(
   1186           flimflam::kCellularApnProperty, &shill_apn_dict)) {
   1187     shill_apn_dict->GetStringWithoutPathExpansion(
   1188         flimflam::kApnNetworkIdProperty, &network_id);
   1189   }
   1190   base::DictionaryValue properties;
   1191   base::DictionaryValue* apn_dict = new base::DictionaryValue;
   1192   apn_dict->SetStringWithoutPathExpansion(flimflam::kApnProperty, apn);
   1193   apn_dict->SetStringWithoutPathExpansion(flimflam::kApnNetworkIdProperty,
   1194                                           network_id);
   1195   apn_dict->SetStringWithoutPathExpansion(flimflam::kApnUsernameProperty,
   1196                                           username);
   1197   apn_dict->SetStringWithoutPathExpansion(flimflam::kApnPasswordProperty,
   1198                                           password);
   1199   properties.SetWithoutPathExpansion(flimflam::kCellularApnProperty, apn_dict);
   1200   NetworkHandler::Get()->network_configuration_handler()->SetProperties(
   1201       service_path, properties,
   1202       base::Bind(&base::DoNothing),
   1203       base::Bind(&ShillError, "SetApnProperties"));
   1204 }
   1205 
   1206 void InternetOptionsHandler::CarrierStatusCallback() {
   1207   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
   1208   const DeviceState* device =
   1209       handler->GetDeviceStateByType(flimflam::kTypeCellular);
   1210   if (device && (device->carrier() == shill::kCarrierSprint)) {
   1211     const NetworkState* network =
   1212         handler->FirstNetworkByType(flimflam::kTypeCellular);
   1213     if (network) {
   1214       ash::network_connect::ActivateCellular(network->path());
   1215       UpdateConnectionData(network->path());
   1216     }
   1217   }
   1218   UpdateCarrier();
   1219 }
   1220 
   1221 void InternetOptionsHandler::SetCarrierCallback(const base::ListValue* args) {
   1222   std::string service_path;
   1223   std::string carrier;
   1224   if (args->GetSize() != 2 ||
   1225       !args->GetString(0, &service_path) ||
   1226       !args->GetString(1, &carrier)) {
   1227     NOTREACHED();
   1228     return;
   1229   }
   1230   const DeviceState* device = NetworkHandler::Get()->network_state_handler()->
   1231       GetDeviceStateByType(flimflam::kTypeCellular);
   1232   if (!device) {
   1233     LOG(WARNING) << "SetCarrierCallback with no cellular device.";
   1234     return;
   1235   }
   1236   NetworkHandler::Get()->network_device_handler()->SetCarrier(
   1237       device->path(),
   1238       carrier,
   1239       base::Bind(&InternetOptionsHandler::CarrierStatusCallback,
   1240                  weak_factory_.GetWeakPtr()),
   1241       base::Bind(&ShillError, "SetCarrierCallback"));
   1242 }
   1243 
   1244 void InternetOptionsHandler::SetSimCardLockCallback(
   1245     const base::ListValue* args) {
   1246   bool require_pin_new_value;
   1247   if (!args->GetBoolean(0, &require_pin_new_value)) {
   1248     NOTREACHED();
   1249     return;
   1250   }
   1251   // 1. Bring up SIM unlock dialog, pass new RequirePin setting in URL.
   1252   // 2. Dialog will ask for current PIN in any case.
   1253   // 3. If card is locked it will first call PIN unlock operation
   1254   // 4. Then it will call Set RequirePin, passing the same PIN.
   1255   // 5. We'll get notified by REQUIRE_PIN_SETTING_CHANGE_ENDED notification.
   1256   SimDialogDelegate::SimDialogMode mode;
   1257   if (require_pin_new_value)
   1258     mode = SimDialogDelegate::SIM_DIALOG_SET_LOCK_ON;
   1259   else
   1260     mode = SimDialogDelegate::SIM_DIALOG_SET_LOCK_OFF;
   1261   SimDialogDelegate::ShowDialog(GetNativeWindow(), mode);
   1262 }
   1263 
   1264 void InternetOptionsHandler::ChangePinCallback(const base::ListValue* args) {
   1265   SimDialogDelegate::ShowDialog(GetNativeWindow(),
   1266       SimDialogDelegate::SIM_DIALOG_CHANGE_PIN);
   1267 }
   1268 
   1269 void InternetOptionsHandler::RefreshNetworksCallback(
   1270     const base::ListValue* args) {
   1271   NetworkHandler::Get()->network_state_handler()->RequestScan();
   1272 }
   1273 
   1274 std::string InternetOptionsHandler::GetIconDataUrl(int resource_id) const {
   1275   gfx::ImageSkia* icon =
   1276       ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
   1277   gfx::ImageSkiaRep image_rep = icon->GetRepresentation(
   1278       web_ui()->GetDeviceScaleFactor());
   1279   return webui::GetBitmapDataUrl(image_rep.sk_bitmap());
   1280 }
   1281 
   1282 void InternetOptionsHandler::RefreshNetworkData() {
   1283   base::DictionaryValue dictionary;
   1284   FillNetworkInfo(&dictionary);
   1285   web_ui()->CallJavascriptFunction(
   1286       kRefreshNetworkDataFunction, dictionary);
   1287 }
   1288 
   1289 void InternetOptionsHandler::UpdateConnectionData(
   1290     const std::string& service_path) {
   1291   NetworkHandler::Get()->network_configuration_handler()->GetProperties(
   1292       service_path,
   1293       base::Bind(&InternetOptionsHandler::UpdateConnectionDataCallback,
   1294                  weak_factory_.GetWeakPtr()),
   1295       base::Bind(&ShillError, "UpdateConnectionData"));
   1296 }
   1297 
   1298 void InternetOptionsHandler::UpdateConnectionDataCallback(
   1299     const std::string& service_path,
   1300     const base::DictionaryValue& shill_properties) {
   1301   const NetworkState* network = GetNetworkState(service_path);
   1302   if (!network)
   1303     return;
   1304   base::DictionaryValue dictionary;
   1305   PopulateConnectionDetails(network, shill_properties, &dictionary);
   1306   web_ui()->CallJavascriptFunction(kUpdateConnectionDataFunction, dictionary);
   1307 }
   1308 
   1309 void InternetOptionsHandler::UpdateCarrier() {
   1310   web_ui()->CallJavascriptFunction(kUpdateCarrierFunction);
   1311 }
   1312 
   1313 void InternetOptionsHandler::NetworkManagerChanged() {
   1314   if (!web_ui())
   1315     return;
   1316   RefreshNetworkData();
   1317 }
   1318 
   1319 void InternetOptionsHandler::NetworkListChanged() {
   1320   if (!web_ui())
   1321     return;
   1322   RefreshNetworkData();
   1323 }
   1324 
   1325 void InternetOptionsHandler::NetworkPropertiesUpdated(
   1326     const NetworkState* network) {
   1327   if (!web_ui())
   1328     return;
   1329   RefreshNetworkData();
   1330   UpdateConnectionData(network->path());
   1331 }
   1332 
   1333 void InternetOptionsHandler::LoggedInStateChanged(
   1334     LoginState::LoggedInState state) {
   1335   UpdateLoggedInUserType();
   1336 }
   1337 
   1338 void InternetOptionsHandler::UpdateLoggedInUserType() {
   1339   if (!web_ui())
   1340     return;
   1341   base::StringValue login_type(
   1342       LoggedInUserTypeToString(LoginState::Get()->GetLoggedInUserType()));
   1343   web_ui()->CallJavascriptFunction(
   1344       kUpdateLoggedInUserTypeFunction, login_type);
   1345 }
   1346 
   1347 void InternetOptionsHandler::Observe(
   1348     int type,
   1349     const content::NotificationSource& source,
   1350     const content::NotificationDetails& details) {
   1351   OptionsPageUIHandler::Observe(type, source, details);
   1352   if (type == chrome::NOTIFICATION_REQUIRE_PIN_SETTING_CHANGE_ENDED) {
   1353     base::FundamentalValue require_pin(*content::Details<bool>(details).ptr());
   1354     web_ui()->CallJavascriptFunction(
   1355         kUpdateSecurityTabFunction, require_pin);
   1356   } else if (type == chrome::NOTIFICATION_ENTER_PIN_ENDED) {
   1357     // We make an assumption (which is valid for now) that the SIM
   1358     // unlock dialog is put up only when the user is trying to enable
   1359     // mobile data.
   1360     bool cancelled = *content::Details<bool>(details).ptr();
   1361     if (cancelled)
   1362       RefreshNetworkData();
   1363     // The case in which the correct PIN was entered and the SIM is
   1364     // now unlocked is handled in NetworkMenuButton.
   1365   }
   1366 }
   1367 
   1368 void InternetOptionsHandler::SetServerHostnameCallback(
   1369     const base::ListValue* args) {
   1370   std::string service_path, server_hostname;
   1371   if (args->GetSize() < 2 ||
   1372       !args->GetString(0, &service_path) ||
   1373       !args->GetString(1, &server_hostname)) {
   1374     NOTREACHED();
   1375     return;
   1376   }
   1377   SetNetworkProperty(service_path, flimflam::kProviderHostProperty,
   1378                      base::Value::CreateStringValue(server_hostname));
   1379 }
   1380 
   1381 void InternetOptionsHandler::SetPreferNetworkCallback(
   1382     const base::ListValue* args) {
   1383   std::string service_path, prefer_network_str;
   1384   if (args->GetSize() < 2 ||
   1385       !args->GetString(0, &service_path) ||
   1386       !args->GetString(1, &prefer_network_str)) {
   1387     NOTREACHED();
   1388     return;
   1389   }
   1390   int priority = (prefer_network_str == kTagTrue) ? kPreferredPriority : 0;
   1391   SetNetworkProperty(service_path, flimflam::kPriorityProperty,
   1392                      base::Value::CreateIntegerValue(priority));
   1393 }
   1394 
   1395 void InternetOptionsHandler::SetAutoConnectCallback(
   1396     const base::ListValue* args) {
   1397   std::string service_path, auto_connect_str;
   1398   if (args->GetSize() < 2 ||
   1399       !args->GetString(0, &service_path) ||
   1400       !args->GetString(1, &auto_connect_str)) {
   1401     NOTREACHED();
   1402     return;
   1403   }
   1404   bool auto_connect = auto_connect_str == kTagTrue;
   1405   SetNetworkProperty(service_path, flimflam::kAutoConnectProperty,
   1406                      base::Value::CreateBooleanValue(auto_connect));
   1407 }
   1408 
   1409 void InternetOptionsHandler::SetIPConfigCallback(const base::ListValue* args) {
   1410   std::string service_path;
   1411   if (!args->GetString(0, &service_path)) {
   1412     NOTREACHED();
   1413     return;
   1414   }
   1415   NetworkHandler::Get()->network_configuration_handler()->GetProperties(
   1416       service_path,
   1417       base::Bind(&InternetOptionsHandler::SetIPConfigProperties,
   1418                  weak_factory_.GetWeakPtr(), base::Owned(args->DeepCopy())),
   1419       base::Bind(&ShillError, "SetIPConfigCallback"));
   1420 }
   1421 
   1422 void InternetOptionsHandler::SetIPConfigProperties(
   1423     const base::ListValue* args,
   1424     const std::string& service_path,
   1425     const base::DictionaryValue& shill_properties) {
   1426   std::string address, netmask, gateway, name_server_type, name_servers;
   1427   bool dhcp_for_ip;
   1428   if (!args->GetBoolean(1, &dhcp_for_ip) ||
   1429       !args->GetString(2, &address) ||
   1430       !args->GetString(3, &netmask) ||
   1431       !args->GetString(4, &gateway) ||
   1432       !args->GetString(5, &name_server_type) ||
   1433       !args->GetString(6, &name_servers)) {
   1434     NOTREACHED();
   1435     return;
   1436   }
   1437   NET_LOG_USER("SetIPConfigProperties", service_path);
   1438 
   1439   bool request_reconnect = false;
   1440   std::vector<std::string> properties_to_clear;
   1441   base::DictionaryValue properties_to_set;
   1442 
   1443   if (dhcp_for_ip) {
   1444     request_reconnect |= AppendPropertyKeyIfPresent(
   1445         shill::kStaticIPAddressProperty,
   1446         shill_properties, &properties_to_clear);
   1447     request_reconnect |= AppendPropertyKeyIfPresent(
   1448         shill::kStaticIPPrefixlenProperty,
   1449         shill_properties, &properties_to_clear);
   1450     request_reconnect |= AppendPropertyKeyIfPresent(
   1451         shill::kStaticIPGatewayProperty,
   1452         shill_properties, &properties_to_clear);
   1453   } else {
   1454     request_reconnect |= AddStringPropertyIfChanged(
   1455         shill::kStaticIPAddressProperty,
   1456         address, shill_properties, &properties_to_set);
   1457     int prefixlen = network_util::NetmaskToPrefixLength(netmask);
   1458     if (prefixlen > 0) {
   1459       LOG(ERROR) << "Invalid prefix length for: " << service_path;
   1460       prefixlen = 0;
   1461     }
   1462     request_reconnect |= AddIntegerPropertyIfChanged(
   1463         shill::kStaticIPPrefixlenProperty,
   1464         prefixlen, shill_properties, &properties_to_set);
   1465     request_reconnect |= AddStringPropertyIfChanged(
   1466         shill::kStaticIPGatewayProperty,
   1467         gateway, shill_properties, &properties_to_set);
   1468   }
   1469 
   1470   if (name_server_type == kNameServerTypeAutomatic) {
   1471     AppendPropertyKeyIfPresent(shill::kStaticIPNameServersProperty,
   1472                                shill_properties, &properties_to_clear);
   1473   } else {
   1474     if (name_server_type == kNameServerTypeGoogle)
   1475       name_servers = kGoogleNameServers;
   1476     AddStringPropertyIfChanged(
   1477         shill::kStaticIPNameServersProperty,
   1478         name_servers, shill_properties, &properties_to_set);
   1479   }
   1480 
   1481   if (!properties_to_clear.empty()) {
   1482     NetworkHandler::Get()->network_configuration_handler()->ClearProperties(
   1483       service_path, properties_to_clear,
   1484       base::Bind(&base::DoNothing),
   1485       base::Bind(&ShillError, "ClearIPConfigProperties"));
   1486   }
   1487   if (!properties_to_set.empty()) {
   1488     NetworkHandler::Get()->network_configuration_handler()->SetProperties(
   1489         service_path, properties_to_set,
   1490         base::Bind(&base::DoNothing),
   1491         base::Bind(&ShillError, "SetIPConfigProperties"));
   1492   }
   1493   std::string device_path;
   1494   shill_properties.GetStringWithoutPathExpansion(
   1495       flimflam::kDeviceProperty, &device_path);
   1496   if (!device_path.empty()) {
   1497     base::Closure callback = base::Bind(&base::DoNothing);
   1498     // If auto config or a static IP property changed, we need to reconnect
   1499     // to the network.
   1500     if (request_reconnect)
   1501       callback = base::Bind(&RequestReconnect, service_path, GetNativeWindow());
   1502     NetworkHandler::Get()->network_device_handler()->RequestRefreshIPConfigs(
   1503         device_path,
   1504         callback,
   1505         base::Bind(&ShillError, "RequestRefreshIPConfigs"));
   1506   }
   1507 }
   1508 
   1509 void InternetOptionsHandler::PopulateDictionaryDetailsCallback(
   1510     const std::string& service_path,
   1511     const base::DictionaryValue& shill_properties) {
   1512   const NetworkState* network = GetNetworkState(service_path);
   1513   if (!network) {
   1514     LOG(ERROR) << "Network properties not found: " << service_path;
   1515     return;
   1516   }
   1517 
   1518   onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
   1519   const base::DictionaryValue* onc =
   1520       network_connect::FindPolicyForActiveUser(network, &onc_source);
   1521   const NetworkPropertyUIData property_ui_data(onc_source);
   1522 
   1523   base::DictionaryValue dictionary;
   1524 
   1525   // Device hardware address
   1526   const DeviceState* device = NetworkHandler::Get()->network_state_handler()->
   1527       GetDeviceState(network->device_path());
   1528   if (device)
   1529     dictionary.SetString(kTagHardwareAddress, device->mac_address());
   1530 
   1531   // IP config
   1532   scoped_ptr<base::DictionaryValue> ipconfig_dhcp(new base::DictionaryValue);
   1533   ipconfig_dhcp->SetString(kIpConfigAddress, network->ip_address());
   1534   ipconfig_dhcp->SetString(kIpConfigNetmask, network->GetNetmask());
   1535   ipconfig_dhcp->SetString(kIpConfigGateway, network->gateway());
   1536   std::string ipconfig_name_servers = network->GetDnsServersAsString();
   1537   ipconfig_dhcp->SetString(kIpConfigNameServers, ipconfig_name_servers);
   1538   ipconfig_dhcp->SetString(kIpConfigWebProxyAutoDiscoveryUrl,
   1539                            network->web_proxy_auto_discovery_url().spec());
   1540   SetValueDictionary(&dictionary,
   1541                      kDictionaryIpConfig,
   1542                      ipconfig_dhcp.release(),
   1543                      property_ui_data);
   1544 
   1545   std::string name_server_type = kNameServerTypeAutomatic;
   1546   int automatic_ip_config = 0;
   1547   scoped_ptr<base::DictionaryValue> static_ip_dict(
   1548       BuildIPInfoDictionary(shill_properties, true, &automatic_ip_config));
   1549   dictionary.SetBoolean(kIpConfigAutoConfig, automatic_ip_config == 0);
   1550   DCHECK(automatic_ip_config == 3 || automatic_ip_config == 0)
   1551       << "UI doesn't support automatic specification of individual "
   1552       << "static IP parameters.";
   1553   scoped_ptr<base::DictionaryValue> saved_ip_dict(
   1554       BuildIPInfoDictionary(shill_properties, false, NULL));
   1555   dictionary.Set(kDictionarySavedIp, saved_ip_dict.release());
   1556 
   1557   // Determine what kind of name server setting we have by comparing the
   1558   // StaticIP and Google values with the ipconfig values.
   1559   std::string static_ip_nameservers;
   1560   static_ip_dict->GetString(kIpConfigNameServers, &static_ip_nameservers);
   1561   if (!static_ip_nameservers.empty() &&
   1562       static_ip_nameservers == ipconfig_name_servers) {
   1563     name_server_type = kNameServerTypeUser;
   1564   }
   1565   if (ipconfig_name_servers == kGoogleNameServers) {
   1566     name_server_type = kNameServerTypeGoogle;
   1567   }
   1568   SetValueDictionary(&dictionary,
   1569                      kDictionaryStaticIp,
   1570                      static_ip_dict.release(),
   1571                      property_ui_data);
   1572 
   1573   std::string type = network->type();
   1574   dictionary.SetString(kTagType, type);
   1575   dictionary.SetString(kTagServicePath, network->path());
   1576   dictionary.SetString(kTagNameServerType, name_server_type);
   1577   dictionary.SetString(kTagNameServersGoogle, kGoogleNameServers);
   1578 
   1579   // Only show proxy for remembered networks.
   1580   dictionary.SetBoolean(kTagShowProxy, !network->profile_path().empty());
   1581 
   1582   // Enable static ip config for ethernet. For wifi, enable if flag is set.
   1583   bool staticIPConfig = type == flimflam::kTypeEthernet ||
   1584       (type == flimflam::kTypeWifi &&
   1585        CommandLine::ForCurrentProcess()->HasSwitch(
   1586            chromeos::switches::kEnableStaticIPConfig));
   1587   dictionary.SetBoolean(kTagShowStaticIPConfig, staticIPConfig);
   1588 
   1589   dictionary.SetBoolean(kTagShowPreferred, !network->profile_path().empty());
   1590   bool preferred = network->priority() > 0;
   1591   SetValueDictionary(&dictionary, kTagPreferred,
   1592                      new base::FundamentalValue(preferred),
   1593                      property_ui_data);
   1594 
   1595   NetworkPropertyUIData auto_connect_ui_data(onc_source);
   1596   std::string onc_path_to_auto_connect;
   1597   if (type == flimflam::kTypeWifi) {
   1598     onc_path_to_auto_connect = base::StringPrintf(
   1599         "%s.%s",
   1600         onc::network_config::kWiFi,
   1601         onc::wifi::kAutoConnect);
   1602   } else if (type == flimflam::kTypeVPN) {
   1603     onc_path_to_auto_connect = base::StringPrintf(
   1604         "%s.%s",
   1605         onc::network_config::kVPN,
   1606         onc::vpn::kAutoConnect);
   1607   }
   1608   if (!onc_path_to_auto_connect.empty()) {
   1609     auto_connect_ui_data.ParseOncProperty(
   1610         onc_source, onc, onc_path_to_auto_connect);
   1611   }
   1612   SetValueDictionary(&dictionary, kTagAutoConnect,
   1613                      new base::FundamentalValue(network->auto_connect()),
   1614                      auto_connect_ui_data);
   1615 
   1616   PopulateConnectionDetails(network, shill_properties, &dictionary);
   1617 
   1618   // Show details dialog
   1619   web_ui()->CallJavascriptFunction(kShowDetailedInfoFunction, dictionary);
   1620 }
   1621 
   1622 namespace {
   1623 
   1624 void PopulateConnectionDetails(const NetworkState* network,
   1625                                const base::DictionaryValue& shill_properties,
   1626                                base::DictionaryValue* dictionary) {
   1627   dictionary->SetString(kNetworkInfoKeyServicePath, network->path());
   1628   dictionary->SetString(kTagServiceName, network->name());
   1629   dictionary->SetBoolean(kTagConnecting, network->IsConnectingState());
   1630   dictionary->SetBoolean(kTagConnected, network->IsConnectedState());
   1631   dictionary->SetString(kTagConnectionState,
   1632                         ConnectionStateString(network->connection_state()));
   1633   dictionary->SetString(kTagNetworkName, network->name());
   1634   dictionary->SetString(kTagErrorState,
   1635                         ash::network_connect::ErrorString(network->error()));
   1636 
   1637   dictionary->SetBoolean(kTagRemembered, !network->profile_path().empty());
   1638   bool shared = !network->IsPrivate();
   1639   dictionary->SetBoolean(kTagShared, shared);
   1640 
   1641   const std::string& type = network->type();
   1642   const NetworkState* connected_network =
   1643       NetworkHandler::Get()->network_state_handler()->ConnectedNetworkByType(
   1644           type);
   1645 
   1646   dictionary->SetBoolean(kTagDeviceConnected, connected_network != NULL);
   1647 
   1648   if (type == flimflam::kTypeWifi)
   1649     PopulateWifiDetails(network, shill_properties, dictionary);
   1650   else if (type == flimflam::kTypeWimax)
   1651     PopulateWimaxDetails(network, shill_properties, dictionary);
   1652   else if (type == flimflam::kTypeCellular)
   1653     PopulateCellularDetails(network, shill_properties, dictionary);
   1654   else if (type == flimflam::kTypeVPN)
   1655     PopulateVPNDetails(network, shill_properties, dictionary);
   1656 }
   1657 
   1658 void PopulateWifiDetails(const NetworkState* wifi,
   1659                          const base::DictionaryValue& shill_properties,
   1660                          base::DictionaryValue* dictionary) {
   1661   dictionary->SetString(kTagSsid, wifi->name());
   1662   dictionary->SetInteger(kTagStrength, wifi->signal_strength());
   1663 
   1664   std::string security, eap_method;
   1665   shill_properties.GetStringWithoutPathExpansion(
   1666       flimflam::kSecurityProperty, &security);
   1667   shill_properties.GetStringWithoutPathExpansion(
   1668       flimflam::kEapMethodProperty, &eap_method);
   1669   dictionary->SetString(kTagEncryption, EncryptionString(security, eap_method));
   1670   CopyStringFromDictionary(shill_properties, flimflam::kWifiBSsid,
   1671                            kTagBssid, dictionary);
   1672   CopyIntegerFromDictionary(shill_properties, flimflam::kWifiFrequency,
   1673                             kTagFrequency, false, dictionary);
   1674 }
   1675 
   1676 void PopulateWimaxDetails(const NetworkState* wimax,
   1677                           const base::DictionaryValue& shill_properties,
   1678                           base::DictionaryValue* dictionary) {
   1679   dictionary->SetInteger(kTagStrength, wimax->signal_strength());
   1680   CopyStringFromDictionary(shill_properties, flimflam::kEapIdentityProperty,
   1681                            kTagIdentity, dictionary);
   1682 }
   1683 
   1684 void CreateDictionaryFromCellularApn(const base::DictionaryValue* apn,
   1685                                      base::DictionaryValue* dictionary) {
   1686   CopyStringFromDictionary(*apn, flimflam::kApnProperty,
   1687                            kTagApn, dictionary);
   1688   CopyStringFromDictionary(*apn, flimflam::kApnNetworkIdProperty,
   1689                            kTagNetworkId, dictionary);
   1690   CopyStringFromDictionary(*apn, flimflam::kApnUsernameProperty,
   1691                            kTagUsername, dictionary);
   1692   CopyStringFromDictionary(*apn, flimflam::kApnPasswordProperty,
   1693                            kTagPassword, dictionary);
   1694   CopyStringFromDictionary(*apn, flimflam::kApnNameProperty,
   1695                            kTagName, dictionary);
   1696   CopyStringFromDictionary(*apn, flimflam::kApnLocalizedNameProperty,
   1697                            kTagLocalizedName, dictionary);
   1698   CopyStringFromDictionary(*apn, flimflam::kApnLanguageProperty,
   1699                            kTagLanguage, dictionary);
   1700 }
   1701 
   1702 void PopulateCellularDetails(const NetworkState* cellular,
   1703                              const base::DictionaryValue& shill_properties,
   1704                              base::DictionaryValue* dictionary) {
   1705   dictionary->SetBoolean(kTagCarrierSelectFlag,
   1706                          CommandLine::ForCurrentProcess()->HasSwitch(
   1707                              chromeos::switches::kEnableCarrierSwitching));
   1708   // Cellular network / connection settings.
   1709   dictionary->SetString(kTagNetworkTechnology, cellular->network_technology());
   1710   dictionary->SetString(kTagActivationState,
   1711                         ActivationStateString(cellular->activation_state()));
   1712   dictionary->SetString(kTagRoamingState,
   1713                         RoamingStateString(cellular->roaming()));
   1714   bool restricted = cellular->connection_state() == flimflam::kStatePortal;
   1715   dictionary->SetString(kTagRestrictedPool,
   1716                         restricted ?
   1717                         l10n_util::GetStringUTF8(
   1718                             IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL) :
   1719                         l10n_util::GetStringUTF8(
   1720                             IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL));
   1721 
   1722   const base::DictionaryValue* serving_operator = NULL;
   1723   if (shill_properties.GetDictionaryWithoutPathExpansion(
   1724           flimflam::kServingOperatorProperty, &serving_operator)) {
   1725     CopyStringFromDictionary(*serving_operator, flimflam::kOperatorNameKey,
   1726                              kTagOperatorName, dictionary);
   1727     CopyStringFromDictionary(*serving_operator, flimflam::kOperatorCodeKey,
   1728                              kTagOperatorCode, dictionary);
   1729   }
   1730 
   1731   const base::DictionaryValue* olp = NULL;
   1732   if (shill_properties.GetDictionaryWithoutPathExpansion(
   1733           flimflam::kPaymentPortalProperty, &olp)) {
   1734     std::string url;
   1735     olp->GetStringWithoutPathExpansion(flimflam::kPaymentPortalURL, &url);
   1736     dictionary->SetString(kTagSupportUrl, url);
   1737   }
   1738 
   1739   base::DictionaryValue* apn = new base::DictionaryValue;
   1740   const base::DictionaryValue* source_apn = NULL;
   1741   if (shill_properties.GetDictionaryWithoutPathExpansion(
   1742           flimflam::kCellularApnProperty, &source_apn)) {
   1743     CreateDictionaryFromCellularApn(source_apn, apn);
   1744   }
   1745   dictionary->Set(kTagApn, apn);
   1746 
   1747   base::DictionaryValue* last_good_apn = new base::DictionaryValue;
   1748   if (shill_properties.GetDictionaryWithoutPathExpansion(
   1749           flimflam::kCellularLastGoodApnProperty, &source_apn)) {
   1750     CreateDictionaryFromCellularApn(source_apn, last_good_apn);
   1751   }
   1752   dictionary->Set(kTagLastGoodApn, last_good_apn);
   1753 
   1754   // These default to empty and are only set if device != NULL.
   1755   std::string carrier_id;
   1756   std::string mdn;
   1757 
   1758   // Device settings.
   1759   const DeviceState* device = NetworkHandler::Get()->network_state_handler()->
   1760       GetDeviceState(cellular->device_path());
   1761   if (device) {
   1762     // TODO(stevenjb): Add NetworkDeviceHandler::GetProperties() and use that
   1763     // to retrieve the complete dictionary of device properties, instead of
   1764     // caching them (will be done for the new UI).
   1765     const base::DictionaryValue& device_properties = device->properties();
   1766     const NetworkPropertyUIData cellular_property_ui_data(
   1767         cellular->ui_data().onc_source());
   1768     CopyStringFromDictionary(device_properties, flimflam::kManufacturerProperty,
   1769                             kTagManufacturer, dictionary);
   1770     CopyStringFromDictionary(device_properties, flimflam::kModelIDProperty,
   1771                             kTagModelId, dictionary);
   1772     CopyStringFromDictionary(device_properties,
   1773                             flimflam::kFirmwareRevisionProperty,
   1774                             kTagFirmwareRevision, dictionary);
   1775     CopyStringFromDictionary(device_properties,
   1776                             flimflam::kHardwareRevisionProperty,
   1777                             kTagHardwareRevision, dictionary);
   1778     CopyIntegerFromDictionary(device_properties, flimflam::kPRLVersionProperty,
   1779                              kTagPrlVersion, true, dictionary);
   1780     CopyStringFromDictionary(device_properties, flimflam::kMeidProperty,
   1781                             kTagMeid, dictionary);
   1782     CopyStringFromDictionary(device_properties, flimflam::kIccidProperty,
   1783                             kTagIccid, dictionary);
   1784     CopyStringFromDictionary(device_properties, flimflam::kImeiProperty,
   1785                             kTagImei, dictionary);
   1786     mdn = CopyStringFromDictionary(device_properties, flimflam::kMdnProperty,
   1787                                    kTagMdn, dictionary);
   1788     CopyStringFromDictionary(device_properties, flimflam::kImsiProperty,
   1789                             kTagImsi, dictionary);
   1790     CopyStringFromDictionary(device_properties, flimflam::kEsnProperty,
   1791                             kTagEsn, dictionary);
   1792     CopyStringFromDictionary(device_properties, flimflam::kMinProperty,
   1793                             kTagMin, dictionary);
   1794     std::string family;
   1795     device_properties.GetStringWithoutPathExpansion(
   1796         flimflam::kTechnologyFamilyProperty, &family);
   1797     dictionary->SetBoolean(kTagGsm, family == flimflam::kNetworkTechnologyGsm);
   1798 
   1799     SetValueDictionary(
   1800         dictionary, kTagSimCardLockEnabled,
   1801         new base::FundamentalValue(device->sim_lock_enabled()),
   1802         cellular_property_ui_data);
   1803 
   1804     carrier_id = device->home_provider_id();
   1805 
   1806     MobileConfig* config = MobileConfig::GetInstance();
   1807     if (config->IsReady()) {
   1808       const MobileConfig::Carrier* carrier = config->GetCarrier(carrier_id);
   1809       if (carrier && !carrier->top_up_url().empty())
   1810         dictionary->SetString(kTagCarrierUrl, carrier->top_up_url());
   1811     }
   1812 
   1813     base::ListValue* apn_list_value = new base::ListValue();
   1814     const base::ListValue* apn_list;
   1815     if (device_properties.GetListWithoutPathExpansion(
   1816             flimflam::kCellularApnListProperty, &apn_list)) {
   1817       for (base::ListValue::const_iterator iter = apn_list->begin();
   1818            iter != apn_list->end(); ++iter) {
   1819         const base::DictionaryValue* dict;
   1820         if ((*iter)->GetAsDictionary(&dict)) {
   1821           base::DictionaryValue* apn = new base::DictionaryValue;
   1822           CreateDictionaryFromCellularApn(dict, apn);
   1823           apn_list_value->Append(apn);
   1824         }
   1825       }
   1826     }
   1827     SetValueDictionary(dictionary, kTagProviderApnList, apn_list_value,
   1828                        cellular_property_ui_data);
   1829     if (CommandLine::ForCurrentProcess()->HasSwitch(
   1830             chromeos::switches::kEnableCarrierSwitching)) {
   1831       const base::ListValue* supported_carriers;
   1832       if (device_properties.GetListWithoutPathExpansion(
   1833               shill::kSupportedCarriersProperty, &supported_carriers)) {
   1834         dictionary->Set(kTagCarriers, supported_carriers->DeepCopy());
   1835         dictionary->SetInteger(kTagCurrentCarrierIndex,
   1836                                FindCurrentCarrierIndex(supported_carriers,
   1837                                                        device));
   1838       } else {
   1839         // In case of any error, set the current carrier tag to -1 indicating
   1840         // to the JS code to fallback to a single carrier.
   1841         dictionary->SetInteger(kTagCurrentCarrierIndex, -1);
   1842       }
   1843     }
   1844   }
   1845 
   1846   // Set Cellular Buttons Visibility
   1847   dictionary->SetBoolean(
   1848       kTagDisableConnectButton,
   1849       cellular->activation_state() == flimflam::kActivationStateActivating ||
   1850       cellular->IsConnectingState());
   1851 
   1852   // Don't show any account management related buttons if the activation
   1853   // state is unknown or no payment portal URL is available.
   1854   std::string support_url;
   1855   if (cellular->activation_state() == flimflam::kActivationStateUnknown ||
   1856       !dictionary->GetString(kTagSupportUrl, &support_url) ||
   1857       support_url.empty()) {
   1858     VLOG(2) << "No support URL is available. Don't display buttons.";
   1859     return;
   1860   }
   1861 
   1862   if (cellular->activation_state() != flimflam::kActivationStateActivating &&
   1863       cellular->activation_state() != flimflam::kActivationStateActivated) {
   1864     dictionary->SetBoolean(kTagShowActivateButton, true);
   1865   } else {
   1866     const MobileConfig::Carrier* carrier =
   1867         MobileConfig::GetInstance()->GetCarrier(carrier_id);
   1868     if (carrier && carrier->show_portal_button()) {
   1869       // The button should be shown for a LTE network even when the LTE network
   1870       // is not connected, but CrOS is online. This is done to enable users to
   1871       // update their plan even if they are out of credits.
   1872       // The button should not be shown when the device's mdn is not set,
   1873       // because the network's proper portal url cannot be generated without it
   1874       const NetworkState* default_network =
   1875           NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
   1876       const std::string& technology = cellular->network_technology();
   1877       bool force_show_view_account_button =
   1878           (technology == flimflam::kNetworkTechnologyLte ||
   1879            technology == flimflam::kNetworkTechnologyLteAdvanced) &&
   1880           default_network &&
   1881           !mdn.empty();
   1882 
   1883       // The button will trigger ShowMorePlanInfoCallback() which will open
   1884       // carrier specific portal.
   1885       if (cellular->IsConnectedState() || force_show_view_account_button)
   1886         dictionary->SetBoolean(kTagShowViewAccountButton, true);
   1887     }
   1888   }
   1889 }
   1890 
   1891 }  // namespace
   1892 
   1893 gfx::NativeWindow InternetOptionsHandler::GetNativeWindow() const {
   1894   return web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow();
   1895 }
   1896 
   1897 Browser* InternetOptionsHandler::GetAppropriateBrowser() {
   1898   return chrome::FindOrCreateTabbedBrowser(
   1899       ProfileManager::GetDefaultProfileOrOffTheRecord(),
   1900       chrome::HOST_DESKTOP_TYPE_ASH);
   1901 }
   1902 
   1903 void InternetOptionsHandler::NetworkCommandCallback(
   1904     const base::ListValue* args) {
   1905   std::string type;
   1906   std::string service_path;
   1907   std::string command;
   1908   if (args->GetSize() != 3 ||
   1909       !args->GetString(0, &type) ||
   1910       !args->GetString(1, &service_path) ||
   1911       !args->GetString(2, &command)) {
   1912     NOTREACHED();
   1913     return;
   1914   }
   1915 
   1916   // Process commands that do not require an existing network.
   1917   if (command == kTagAddConnection) {
   1918     if (CanAddNetworkType(type))
   1919       AddConnection(type);
   1920   } else if (command == kTagForget) {
   1921     if (CanForgetNetworkType(type)) {
   1922       NetworkHandler::Get()->network_configuration_handler()->
   1923           RemoveConfiguration(
   1924               service_path,
   1925               base::Bind(&base::DoNothing),
   1926               base::Bind(&ShillError, "NetworkCommand: " + command));
   1927     }
   1928   } else if (command == kTagOptions) {
   1929     NetworkHandler::Get()->network_configuration_handler()->GetProperties(
   1930         service_path,
   1931         base::Bind(&InternetOptionsHandler::PopulateDictionaryDetailsCallback,
   1932                    weak_factory_.GetWeakPtr()),
   1933         base::Bind(&ShillError, "NetworkCommand: " + command));
   1934   } else if (command == kTagConnect) {
   1935     ash::network_connect::ConnectToNetwork(service_path, GetNativeWindow());
   1936   } else if (command == kTagDisconnect) {
   1937     NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork(
   1938         service_path,
   1939         base::Bind(&base::DoNothing),
   1940         base::Bind(&ShillError, "NetworkCommand: " + command));
   1941   } else if (command == kTagConfigure) {
   1942     NetworkConfigView::Show(service_path, GetNativeWindow());
   1943   } else if (command == kTagActivate && type == flimflam::kTypeCellular) {
   1944     ash::network_connect::ActivateCellular(service_path);
   1945     // Activation may update network properties (e.g. ActivationState), so
   1946     // request them here in case they change.
   1947     UpdateConnectionData(service_path);
   1948   } else {
   1949     VLOG(1) << "Unknown command: " << command;
   1950     NOTREACHED();
   1951   }
   1952 }
   1953 
   1954 void InternetOptionsHandler::AddConnection(const std::string& type) {
   1955   if (type == flimflam::kTypeWifi)
   1956     NetworkConfigView::ShowForType(flimflam::kTypeWifi, GetNativeWindow());
   1957   else if (type == flimflam::kTypeVPN)
   1958     NetworkConfigView::ShowForType(flimflam::kTypeVPN, GetNativeWindow());
   1959   else if (type == flimflam::kTypeCellular)
   1960     ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow());
   1961   else
   1962     NOTREACHED();
   1963 }
   1964 
   1965 base::ListValue* InternetOptionsHandler::GetWiredList() {
   1966   base::ListValue* list = new base::ListValue();
   1967   const NetworkState* network = NetworkHandler::Get()->network_state_handler()->
   1968       FirstNetworkByType(flimflam::kTypeEthernet);
   1969   if (!network)
   1970     return list;
   1971   NetworkInfoDictionary network_dict(network, web_ui()->GetDeviceScaleFactor());
   1972   list->Append(network_dict.BuildDictionary());
   1973   return list;
   1974 }
   1975 
   1976 base::ListValue* InternetOptionsHandler::GetWirelessList() {
   1977   base::ListValue* list = new base::ListValue();
   1978 
   1979   NetworkStateHandler::NetworkStateList networks;
   1980   NetworkHandler::Get()->network_state_handler()->GetNetworkList(&networks);
   1981   for (NetworkStateHandler::NetworkStateList::const_iterator iter =
   1982            networks.begin(); iter != networks.end(); ++iter) {
   1983     const NetworkState* network = *iter;
   1984     if (network->type() != flimflam::kTypeWifi &&
   1985         network->type() != flimflam::kTypeWimax &&
   1986         network->type() != flimflam::kTypeCellular)
   1987       continue;
   1988     NetworkInfoDictionary network_dict(
   1989         network, web_ui()->GetDeviceScaleFactor());
   1990     list->Append(network_dict.BuildDictionary());
   1991   }
   1992 
   1993   return list;
   1994 }
   1995 
   1996 base::ListValue* InternetOptionsHandler::GetVPNList() {
   1997   base::ListValue* list = new base::ListValue();
   1998 
   1999   NetworkStateHandler::NetworkStateList networks;
   2000   NetworkHandler::Get()->network_state_handler()->GetNetworkList(&networks);
   2001   for (NetworkStateHandler::NetworkStateList::const_iterator iter =
   2002            networks.begin(); iter != networks.end(); ++iter) {
   2003     const NetworkState* network = *iter;
   2004     if (network->type() != flimflam::kTypeVPN)
   2005       continue;
   2006     NetworkInfoDictionary network_dict(
   2007         network, web_ui()->GetDeviceScaleFactor());
   2008     list->Append(network_dict.BuildDictionary());
   2009   }
   2010 
   2011   return list;
   2012 }
   2013 
   2014 base::ListValue* InternetOptionsHandler::GetRememberedList() {
   2015   base::ListValue* list = new base::ListValue();
   2016 
   2017   NetworkStateHandler::FavoriteStateList favorites;
   2018   NetworkHandler::Get()->network_state_handler()->GetFavoriteList(&favorites);
   2019   for (NetworkStateHandler::FavoriteStateList::const_iterator iter =
   2020            favorites.begin(); iter != favorites.end(); ++iter) {
   2021     const FavoriteState* favorite = *iter;
   2022     if (favorite->type() != flimflam::kTypeWifi &&
   2023         favorite->type() != flimflam::kTypeVPN)
   2024       continue;
   2025     NetworkInfoDictionary network_dict(
   2026         favorite, web_ui()->GetDeviceScaleFactor());
   2027     list->Append(network_dict.BuildDictionary());
   2028   }
   2029 
   2030   return list;
   2031 }
   2032 
   2033 void InternetOptionsHandler::FillNetworkInfo(
   2034     base::DictionaryValue* dictionary) {
   2035   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
   2036   dictionary->Set(kTagWiredList, GetWiredList());
   2037   dictionary->Set(kTagWirelessList, GetWirelessList());
   2038   dictionary->Set(kTagVpnList, GetVPNList());
   2039   dictionary->Set(kTagRememberedList, GetRememberedList());
   2040 
   2041   dictionary->SetBoolean(kTagWifiAvailable,
   2042                          handler->IsTechnologyAvailable(flimflam::kTypeWifi));
   2043   dictionary->SetBoolean(kTagWifiEnabled,
   2044                          handler->IsTechnologyEnabled(flimflam::kTypeWifi));
   2045 
   2046   dictionary->SetBoolean(kTagCellularAvailable,
   2047                          handler->IsTechnologyAvailable(
   2048                              NetworkStateHandler::kMatchTypeMobile));
   2049   dictionary->SetBoolean(kTagCellularEnabled,
   2050                          handler->IsTechnologyEnabled(
   2051                              NetworkStateHandler::kMatchTypeMobile));
   2052   const DeviceState* cellular =
   2053       handler->GetDeviceStateByType(NetworkStateHandler::kMatchTypeMobile);
   2054   dictionary->SetBoolean(
   2055       kTagCellularSupportsScan,
   2056       cellular && cellular->support_network_scan());
   2057 
   2058   dictionary->SetBoolean(kTagWimaxAvailable,
   2059                          handler->IsTechnologyAvailable(flimflam::kTypeWimax));
   2060   dictionary->SetBoolean(kTagWimaxEnabled,
   2061                          handler->IsTechnologyEnabled(flimflam::kTypeWimax));
   2062 }
   2063 
   2064 }  // namespace options
   2065 }  // namespace chromeos
   2066