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